@dirwell/core 0.0.0-stage → 0.0.1-alpha.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Dirwell contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,9 @@
1
- # Temporary Holding Version
1
+ # @dirwell/core
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Framework-neutral filesystem, listing and static-publication SDK. Install with `npm install @dirwell/core@alpha` and a theme of your choice.
4
+
5
+ Core owns filesystem selection, safe navigation, public listing projection and static publication. It requires an explicit theme and does not load a default theme, image renderer, frontend framework, config loader or watcher. The only runtime npm dependency is picomatch.
6
+
7
+ `generateExplorer` publishes a dedicated output tree. `listing` independently plans HTML pages and data blocks; a synchronous callback can select plans per directory. Metadata rendering is an injected Node-side provider. `createDirectoryService` performs live, one-directory reads without writing a generated tree. With filters, selection still walks physical names to preserve descendant inclusion; it is not a constant-cost indexed database query.
8
+
9
+ The service rejects dot segments, absolute paths, backslashes, reserved root paths and paths outside the physical root. Symlink metadata retains existing declared-target behavior. Node-side entries are private inputs; use `projectListingEntry` before public serialization. Reads are not a transactional filesystem snapshot and are not qualified against adversarial concurrent directory replacement.
@@ -0,0 +1,22 @@
1
+ import { i as ListingManifest, r as ListingEntry, t as ListingBlock } from "./listing-CnkSglVT.mjs";
2
+ //#region src/client.d.ts
3
+ export declare class ListingDataError extends Error {
4
+ readonly name = "ListingDataError";
5
+ }
6
+ export interface LoadedListing {
7
+ readonly manifest: ListingManifest;
8
+ /** Hrefs have been normalized to absolute HTTP(S) URLs. */
9
+ readonly entries: readonly ListingEntry[];
10
+ }
11
+ /** Load a coherent static listing; retry a stale/missing block once using a fresh manifest. */
12
+ export declare function loadListing(manifestUrl: string, options?: {
13
+ readonly fetch?: typeof fetch;
14
+ readonly signal?: AbortSignal;
15
+ readonly maxEntries?: number;
16
+ readonly cache?: RequestCache;
17
+ }): Promise<LoadedListing>;
18
+ /** Validate a public page slice and normalize its navigation URLs. */
19
+ export declare function parseListingEntries(value: unknown, baseHref: string, maxEntries?: number): readonly ListingEntry[];
20
+ //#endregion
21
+ export type { ListingBlock };
22
+ //# sourceMappingURL=client.d.mts.map
@@ -0,0 +1,158 @@
1
+ import { t as copyJsonObject } from "./json-Bvj6xQLq.mjs";
2
+ //#region src/client.ts
3
+ var ListingDataError = class extends Error {
4
+ name = "ListingDataError";
5
+ };
6
+ var StaleListingError = class extends ListingDataError {};
7
+ const object = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
8
+ const count = (value) => typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
9
+ const kind = (value) => typeof value === "string" && [
10
+ "directory",
11
+ "file",
12
+ "symlink",
13
+ "other"
14
+ ].includes(value);
15
+ function string(value, name) {
16
+ if (typeof value !== "string") throw new ListingDataError(`Invalid ${name}`);
17
+ return value;
18
+ }
19
+ function boolean(value, name) {
20
+ if (typeof value !== "boolean") throw new ListingDataError(`Invalid ${name}`);
21
+ return value;
22
+ }
23
+ function href(value, base) {
24
+ if (value === null) return null;
25
+ const result = new URL(string(value, "href"), base);
26
+ if (!["http:", "https:"].includes(result.protocol)) throw new ListingDataError("Unsupported listing link protocol");
27
+ return result.href;
28
+ }
29
+ function entry(value, base) {
30
+ if (!object(value) || !kind(value.kind) || typeof value.size !== "number" || !Number.isFinite(value.size) || value.size < 0) throw new ListingDataError("Invalid listing entry");
31
+ let link = null;
32
+ if (value.link !== null) {
33
+ if (!object(value.link)) throw new ListingDataError("Invalid link metadata");
34
+ const targetKind = value.link.targetKind;
35
+ if (targetKind !== null && (!kind(targetKind) || targetKind === "symlink")) throw new ListingDataError("Invalid target kind");
36
+ const targetSize = value.link.targetSize;
37
+ if (targetSize !== null && (typeof targetSize !== "number" || !Number.isFinite(targetSize) || targetSize < 0)) throw new ListingDataError("Invalid target size");
38
+ link = {
39
+ target: string(value.link.target, "target"),
40
+ targetKind,
41
+ targetSize,
42
+ unavailable: boolean(value.link.unavailable, "unavailable"),
43
+ cycle: boolean(value.link.cycle, "cycle")
44
+ };
45
+ }
46
+ return {
47
+ ...value.presentation === void 0 ? {} : { presentation: copyJsonObject(value.presentation) },
48
+ id: string(value.id, "id"),
49
+ name: string(value.name, "name"),
50
+ kind: value.kind,
51
+ href: href(value.href, base),
52
+ exitsExplorer: boolean(value.exitsExplorer, "exitsExplorer"),
53
+ size: value.size,
54
+ modifiedAt: string(value.modifiedAt, "modifiedAt"),
55
+ link
56
+ };
57
+ }
58
+ function manifest(value) {
59
+ if (!object(value) || value.version !== 1 || !count(value.total) || !Array.isArray(value.blocks) || !object(value.sort)) throw new ListingDataError("Invalid listing manifest");
60
+ const sort = value.sort;
61
+ if (typeof sort.field !== "string" || ![
62
+ "name",
63
+ "size",
64
+ "modified"
65
+ ].includes(sort.field) || typeof sort.direction !== "string" || !["asc", "desc"].includes(sort.direction) || typeof sort.nameMode !== "string" || ![
66
+ "locale",
67
+ "natural",
68
+ "unicode"
69
+ ].includes(sort.nameMode) || typeof sort.directoriesFirst !== "boolean") throw new ListingDataError("Invalid listing order");
70
+ const field = sort.field === "size" ? "size" : sort.field === "modified" ? "modified" : "name";
71
+ const direction = sort.direction === "desc" ? "desc" : "asc";
72
+ const nameMode = sort.nameMode === "unicode" ? "unicode" : sort.nameMode === "locale" ? "locale" : "natural";
73
+ const blocks = value.blocks.map((item) => {
74
+ if (!object(item) || !count(item.offset) || !count(item.count)) throw new ListingDataError("Invalid block descriptor");
75
+ return {
76
+ href: string(item.href, "block href"),
77
+ offset: item.offset,
78
+ count: item.count
79
+ };
80
+ });
81
+ if (blocks.length === 0) throw new ListingDataError("Missing blocks");
82
+ return {
83
+ version: 1,
84
+ revision: string(value.revision, "revision"),
85
+ directory: string(value.directory, "directory"),
86
+ hrefBase: string(value.hrefBase, "href base"),
87
+ total: value.total,
88
+ sort: {
89
+ field,
90
+ direction,
91
+ nameMode,
92
+ directoriesFirst: sort.directoriesFirst
93
+ },
94
+ blocks
95
+ };
96
+ }
97
+ /** Load a coherent static listing; retry a stale/missing block once using a fresh manifest. */
98
+ async function loadListing(manifestUrl, options = {}) {
99
+ const request = options.fetch ?? fetch;
100
+ const maxEntries = options.maxEntries ?? 1e5;
101
+ if (!count(maxEntries)) throw new ListingDataError("Invalid entry limit");
102
+ const source = new URL(manifestUrl);
103
+ if (!["http:", "https:"].includes(source.protocol)) throw new ListingDataError("Listing loading requires HTTP(S); use native file navigation");
104
+ for (let attempt = 0; attempt < 2; attempt++) try {
105
+ const init = {
106
+ ...options.signal === void 0 ? {} : { signal: options.signal },
107
+ cache: attempt === 0 ? options.cache ?? "default" : "reload"
108
+ };
109
+ const response = await request(source, init);
110
+ if (!response.ok) throw new ListingDataError(`Manifest request failed: ${response.status}`);
111
+ const current = manifest(await response.json());
112
+ if (current.total > maxEntries) throw new ListingDataError("Listing exceeds the configured entry limit");
113
+ const base = new URL(current.hrefBase, source);
114
+ if (!["http:", "https:"].includes(base.protocol)) throw new ListingDataError("Unsupported href base protocol");
115
+ const entries = [];
116
+ const ids = /* @__PURE__ */ new Set();
117
+ for (const descriptor of current.blocks) {
118
+ if (descriptor.offset !== entries.length || descriptor.count + entries.length > current.total) throw new ListingDataError("Invalid block coverage");
119
+ const blockUrl = new URL(descriptor.href, source);
120
+ if (blockUrl.origin !== source.origin || !["http:", "https:"].includes(blockUrl.protocol)) throw new ListingDataError("Block leaves the manifest origin");
121
+ const blockResponse = await request(blockUrl, init);
122
+ if (blockResponse.status === 404 || blockResponse.status === 410) throw new StaleListingError("Block no longer available");
123
+ if (!blockResponse.ok) throw new ListingDataError(`Block request failed: ${blockResponse.status}`);
124
+ const data = await blockResponse.json();
125
+ if (!object(data) || data.version !== 1 || data.revision !== current.revision) throw new StaleListingError("Listing revision changed");
126
+ if (data.offset !== descriptor.offset || data.total !== current.total || !Array.isArray(data.entries) || data.entries.length !== descriptor.count) throw new ListingDataError("Invalid block envelope");
127
+ for (const raw of data.entries) {
128
+ const record = entry(raw, base);
129
+ if (ids.has(record.id)) throw new ListingDataError("Duplicate entry ID");
130
+ ids.add(record.id);
131
+ entries.push(record);
132
+ }
133
+ }
134
+ if (entries.length !== current.total) throw new ListingDataError("Incomplete listing");
135
+ return {
136
+ manifest: current,
137
+ entries
138
+ };
139
+ } catch (error) {
140
+ if (options.signal?.aborted || !(error instanceof StaleListingError) || attempt === 1) throw error;
141
+ }
142
+ throw new ListingDataError("Listing unavailable");
143
+ }
144
+ /** Validate a public page slice and normalize its navigation URLs. */
145
+ function parseListingEntries(value, baseHref, maxEntries = 1e5) {
146
+ if (!Array.isArray(value) || value.length > maxEntries) throw new ListingDataError("Invalid page slice");
147
+ const base = new URL(baseHref), ids = /* @__PURE__ */ new Set();
148
+ const result = value.map((raw) => entry(raw, base));
149
+ for (const record of result) {
150
+ if (ids.has(record.id)) throw new ListingDataError("Duplicate entry ID");
151
+ ids.add(record.id);
152
+ }
153
+ return result;
154
+ }
155
+ //#endregion
156
+ export { ListingDataError, loadListing, parseListingEntries };
157
+
158
+ //# sourceMappingURL=client.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.mjs","names":[],"sources":["../src/client.ts"],"sourcesContent":["import { copyJsonObject } from \"./json.ts\";\nimport type { ListingEntry, ListingManifest, ListingBlock } from \"./listing.ts\";\n\nexport class ListingDataError extends Error {\n override readonly name = \"ListingDataError\";\n}\nclass StaleListingError extends ListingDataError {}\nconst object = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\nconst count = (value: unknown): value is number =>\n typeof value === \"number\" && Number.isSafeInteger(value) && value >= 0;\nconst kind = (value: unknown): value is ListingEntry[\"kind\"] =>\n typeof value === \"string\" && [\"directory\", \"file\", \"symlink\", \"other\"].includes(value);\nfunction string(value: unknown, name: string): string {\n if (typeof value !== \"string\") throw new ListingDataError(`Invalid ${name}`);\n return value;\n}\nfunction boolean(value: unknown, name: string): boolean {\n if (typeof value !== \"boolean\") throw new ListingDataError(`Invalid ${name}`);\n return value;\n}\nfunction href(value: unknown, base: URL): string | null {\n if (value === null) return null;\n const result = new URL(string(value, \"href\"), base);\n if (![\"http:\", \"https:\"].includes(result.protocol))\n throw new ListingDataError(\"Unsupported listing link protocol\");\n return result.href;\n}\nfunction entry(value: unknown, base: URL): ListingEntry {\n if (\n !object(value) ||\n !kind(value.kind) ||\n typeof value.size !== \"number\" ||\n !Number.isFinite(value.size) ||\n value.size < 0\n )\n throw new ListingDataError(\"Invalid listing entry\");\n let link: ListingEntry[\"link\"] = null;\n if (value.link !== null) {\n if (!object(value.link)) throw new ListingDataError(\"Invalid link metadata\");\n const targetKind = value.link.targetKind;\n if (targetKind !== null && (!kind(targetKind) || targetKind === \"symlink\"))\n throw new ListingDataError(\"Invalid target kind\");\n const targetSize = value.link.targetSize;\n if (\n targetSize !== null &&\n (typeof targetSize !== \"number\" || !Number.isFinite(targetSize) || targetSize < 0)\n )\n throw new ListingDataError(\"Invalid target size\");\n link = {\n target: string(value.link.target, \"target\"),\n targetKind,\n targetSize,\n unavailable: boolean(value.link.unavailable, \"unavailable\"),\n cycle: boolean(value.link.cycle, \"cycle\"),\n };\n }\n return {\n ...(value.presentation === undefined\n ? {}\n : { presentation: copyJsonObject(value.presentation) }),\n id: string(value.id, \"id\"),\n name: string(value.name, \"name\"),\n kind: value.kind,\n href: href(value.href, base),\n exitsExplorer: boolean(value.exitsExplorer, \"exitsExplorer\"),\n size: value.size,\n modifiedAt: string(value.modifiedAt, \"modifiedAt\"),\n link,\n };\n}\nfunction manifest(value: unknown): ListingManifest {\n if (\n !object(value) ||\n value.version !== 1 ||\n !count(value.total) ||\n !Array.isArray(value.blocks) ||\n !object(value.sort)\n )\n throw new ListingDataError(\"Invalid listing manifest\");\n const sort = value.sort;\n if (\n typeof sort.field !== \"string\" ||\n ![\"name\", \"size\", \"modified\"].includes(sort.field) ||\n typeof sort.direction !== \"string\" ||\n ![\"asc\", \"desc\"].includes(sort.direction) ||\n typeof sort.nameMode !== \"string\" ||\n ![\"locale\", \"natural\", \"unicode\"].includes(sort.nameMode) ||\n typeof sort.directoriesFirst !== \"boolean\"\n )\n throw new ListingDataError(\"Invalid listing order\");\n // Guarded enum members are copied through explicit branches, without trusting an assertion.\n const field = sort.field === \"size\" ? \"size\" : sort.field === \"modified\" ? \"modified\" : \"name\";\n const direction = sort.direction === \"desc\" ? \"desc\" : \"asc\";\n const nameMode =\n sort.nameMode === \"unicode\" ? \"unicode\" : sort.nameMode === \"locale\" ? \"locale\" : \"natural\";\n const blocks = value.blocks.map((item: unknown) => {\n if (!object(item) || !count(item.offset) || !count(item.count))\n throw new ListingDataError(\"Invalid block descriptor\");\n return { href: string(item.href, \"block href\"), offset: item.offset, count: item.count };\n });\n if (blocks.length === 0) throw new ListingDataError(\"Missing blocks\");\n return {\n version: 1,\n revision: string(value.revision, \"revision\"),\n directory: string(value.directory, \"directory\"),\n hrefBase: string(value.hrefBase, \"href base\"),\n total: value.total,\n sort: { field, direction, nameMode, directoriesFirst: sort.directoriesFirst },\n blocks,\n };\n}\nexport interface LoadedListing {\n readonly manifest: ListingManifest;\n /** Hrefs have been normalized to absolute HTTP(S) URLs. */\n readonly entries: readonly ListingEntry[];\n}\n/** Load a coherent static listing; retry a stale/missing block once using a fresh manifest. */\nexport async function loadListing(\n manifestUrl: string,\n options: {\n readonly fetch?: typeof fetch;\n readonly signal?: AbortSignal;\n readonly maxEntries?: number;\n readonly cache?: RequestCache;\n } = {},\n): Promise<LoadedListing> {\n const request = options.fetch ?? fetch;\n const maxEntries = options.maxEntries ?? 100000;\n if (!count(maxEntries)) throw new ListingDataError(\"Invalid entry limit\");\n const source = new URL(manifestUrl);\n if (![\"http:\", \"https:\"].includes(source.protocol))\n throw new ListingDataError(\"Listing loading requires HTTP(S); use native file navigation\");\n for (let attempt = 0; attempt < 2; attempt++) {\n try {\n const init: RequestInit = {\n ...(options.signal === undefined ? {} : { signal: options.signal }),\n cache: attempt === 0 ? (options.cache ?? \"default\") : \"reload\",\n };\n const response = await request(source, init);\n if (!response.ok) throw new ListingDataError(`Manifest request failed: ${response.status}`);\n const current = manifest(await response.json());\n if (current.total > maxEntries)\n throw new ListingDataError(\"Listing exceeds the configured entry limit\");\n const base = new URL(current.hrefBase, source);\n if (![\"http:\", \"https:\"].includes(base.protocol))\n throw new ListingDataError(\"Unsupported href base protocol\");\n const entries: ListingEntry[] = [];\n const ids = new Set<string>();\n for (const descriptor of current.blocks) {\n if (\n descriptor.offset !== entries.length ||\n descriptor.count + entries.length > current.total\n )\n throw new ListingDataError(\"Invalid block coverage\");\n const blockUrl = new URL(descriptor.href, source);\n if (blockUrl.origin !== source.origin || ![\"http:\", \"https:\"].includes(blockUrl.protocol))\n throw new ListingDataError(\"Block leaves the manifest origin\");\n const blockResponse = await request(blockUrl, init);\n if (blockResponse.status === 404 || blockResponse.status === 410)\n throw new StaleListingError(\"Block no longer available\");\n if (!blockResponse.ok)\n throw new ListingDataError(`Block request failed: ${blockResponse.status}`);\n const data: unknown = await blockResponse.json();\n if (!object(data) || data.version !== 1 || data.revision !== current.revision)\n throw new StaleListingError(\"Listing revision changed\");\n if (\n data.offset !== descriptor.offset ||\n data.total !== current.total ||\n !Array.isArray(data.entries) ||\n data.entries.length !== descriptor.count\n )\n throw new ListingDataError(\"Invalid block envelope\");\n for (const raw of data.entries) {\n const record = entry(raw, base);\n if (ids.has(record.id)) throw new ListingDataError(\"Duplicate entry ID\");\n ids.add(record.id);\n entries.push(record);\n }\n }\n if (entries.length !== current.total) throw new ListingDataError(\"Incomplete listing\");\n return { manifest: current, entries };\n } catch (error) {\n if (options.signal?.aborted || !(error instanceof StaleListingError) || attempt === 1)\n throw error;\n }\n }\n throw new ListingDataError(\"Listing unavailable\");\n}\n// Keep the transport type usable without importing Node-side implementation code.\nexport type { ListingBlock };\n\n/** Validate a public page slice and normalize its navigation URLs. */\nexport function parseListingEntries(\n value: unknown,\n baseHref: string,\n maxEntries = 100_000,\n): readonly ListingEntry[] {\n if (!Array.isArray(value) || value.length > maxEntries)\n throw new ListingDataError(\"Invalid page slice\");\n const base = new URL(baseHref),\n ids = new Set<string>();\n const result = value.map((raw) => entry(raw, base));\n for (const record of result) {\n if (ids.has(record.id)) throw new ListingDataError(\"Duplicate entry ID\");\n ids.add(record.id);\n }\n return result;\n}\n"],"mappings":";;AAGA,IAAa,mBAAb,cAAsC,MAAM;CAC1C,OAAyB;AAC3B;AACA,IAAM,oBAAN,cAAgC,iBAAiB,CAAC;AAClD,MAAM,UAAU,UACd,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AACrE,MAAM,SAAS,UACb,OAAO,UAAU,YAAY,OAAO,cAAc,KAAK,KAAK,SAAS;AACvE,MAAM,QAAQ,UACZ,OAAO,UAAU,YAAY;CAAC;CAAa;CAAQ;CAAW;AAAO,CAAC,CAAC,SAAS,KAAK;AACvF,SAAS,OAAO,OAAgB,MAAsB;CACpD,IAAI,OAAO,UAAU,UAAU,MAAM,IAAI,iBAAiB,WAAW,MAAM;CAC3E,OAAO;AACT;AACA,SAAS,QAAQ,OAAgB,MAAuB;CACtD,IAAI,OAAO,UAAU,WAAW,MAAM,IAAI,iBAAiB,WAAW,MAAM;CAC5E,OAAO;AACT;AACA,SAAS,KAAK,OAAgB,MAA0B;CACtD,IAAI,UAAU,MAAM,OAAO;CAC3B,MAAM,SAAS,IAAI,IAAI,OAAO,OAAO,MAAM,GAAG,IAAI;CAClD,IAAI,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,SAAS,OAAO,QAAQ,GAC/C,MAAM,IAAI,iBAAiB,mCAAmC;CAChE,OAAO,OAAO;AAChB;AACA,SAAS,MAAM,OAAgB,MAAyB;CACtD,IACE,CAAC,OAAO,KAAK,KACb,CAAC,KAAK,MAAM,IAAI,KAChB,OAAO,MAAM,SAAS,YACtB,CAAC,OAAO,SAAS,MAAM,IAAI,KAC3B,MAAM,OAAO,GAEb,MAAM,IAAI,iBAAiB,uBAAuB;CACpD,IAAI,OAA6B;CACjC,IAAI,MAAM,SAAS,MAAM;EACvB,IAAI,CAAC,OAAO,MAAM,IAAI,GAAG,MAAM,IAAI,iBAAiB,uBAAuB;EAC3E,MAAM,aAAa,MAAM,KAAK;EAC9B,IAAI,eAAe,SAAS,CAAC,KAAK,UAAU,KAAK,eAAe,YAC9D,MAAM,IAAI,iBAAiB,qBAAqB;EAClD,MAAM,aAAa,MAAM,KAAK;EAC9B,IACE,eAAe,SACd,OAAO,eAAe,YAAY,CAAC,OAAO,SAAS,UAAU,KAAK,aAAa,IAEhF,MAAM,IAAI,iBAAiB,qBAAqB;EAClD,OAAO;GACL,QAAQ,OAAO,MAAM,KAAK,QAAQ,QAAQ;GAC1C;GACA;GACA,aAAa,QAAQ,MAAM,KAAK,aAAa,aAAa;GAC1D,OAAO,QAAQ,MAAM,KAAK,OAAO,OAAO;EAC1C;CACF;CACA,OAAO;EACL,GAAI,MAAM,iBAAiB,KAAA,IACvB,CAAC,IACD,EAAE,cAAc,eAAe,MAAM,YAAY,EAAE;EACvD,IAAI,OAAO,MAAM,IAAI,IAAI;EACzB,MAAM,OAAO,MAAM,MAAM,MAAM;EAC/B,MAAM,MAAM;EACZ,MAAM,KAAK,MAAM,MAAM,IAAI;EAC3B,eAAe,QAAQ,MAAM,eAAe,eAAe;EAC3D,MAAM,MAAM;EACZ,YAAY,OAAO,MAAM,YAAY,YAAY;EACjD;CACF;AACF;AACA,SAAS,SAAS,OAAiC;CACjD,IACE,CAAC,OAAO,KAAK,KACb,MAAM,YAAY,KAClB,CAAC,MAAM,MAAM,KAAK,KAClB,CAAC,MAAM,QAAQ,MAAM,MAAM,KAC3B,CAAC,OAAO,MAAM,IAAI,GAElB,MAAM,IAAI,iBAAiB,0BAA0B;CACvD,MAAM,OAAO,MAAM;CACnB,IACE,OAAO,KAAK,UAAU,YACtB,CAAC;EAAC;EAAQ;EAAQ;CAAU,CAAC,CAAC,SAAS,KAAK,KAAK,KACjD,OAAO,KAAK,cAAc,YAC1B,CAAC,CAAC,OAAO,MAAM,CAAC,CAAC,SAAS,KAAK,SAAS,KACxC,OAAO,KAAK,aAAa,YACzB,CAAC;EAAC;EAAU;EAAW;CAAS,CAAC,CAAC,SAAS,KAAK,QAAQ,KACxD,OAAO,KAAK,qBAAqB,WAEjC,MAAM,IAAI,iBAAiB,uBAAuB;CAEpD,MAAM,QAAQ,KAAK,UAAU,SAAS,SAAS,KAAK,UAAU,aAAa,aAAa;CACxF,MAAM,YAAY,KAAK,cAAc,SAAS,SAAS;CACvD,MAAM,WACJ,KAAK,aAAa,YAAY,YAAY,KAAK,aAAa,WAAW,WAAW;CACpF,MAAM,SAAS,MAAM,OAAO,KAAK,SAAkB;EACjD,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,KAAK,CAAC,MAAM,KAAK,KAAK,GAC3D,MAAM,IAAI,iBAAiB,0BAA0B;EACvD,OAAO;GAAE,MAAM,OAAO,KAAK,MAAM,YAAY;GAAG,QAAQ,KAAK;GAAQ,OAAO,KAAK;EAAM;CACzF,CAAC;CACD,IAAI,OAAO,WAAW,GAAG,MAAM,IAAI,iBAAiB,gBAAgB;CACpE,OAAO;EACL,SAAS;EACT,UAAU,OAAO,MAAM,UAAU,UAAU;EAC3C,WAAW,OAAO,MAAM,WAAW,WAAW;EAC9C,UAAU,OAAO,MAAM,UAAU,WAAW;EAC5C,OAAO,MAAM;EACb,MAAM;GAAE;GAAO;GAAW;GAAU,kBAAkB,KAAK;EAAiB;EAC5E;CACF;AACF;;AAOA,eAAsB,YACpB,aACA,UAKI,CAAC,GACmB;CACxB,MAAM,UAAU,QAAQ,SAAS;CACjC,MAAM,aAAa,QAAQ,cAAc;CACzC,IAAI,CAAC,MAAM,UAAU,GAAG,MAAM,IAAI,iBAAiB,qBAAqB;CACxE,MAAM,SAAS,IAAI,IAAI,WAAW;CAClC,IAAI,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,SAAS,OAAO,QAAQ,GAC/C,MAAM,IAAI,iBAAiB,8DAA8D;CAC3F,KAAK,IAAI,UAAU,GAAG,UAAU,GAAG,WACjC,IAAI;EACF,MAAM,OAAoB;GACxB,GAAI,QAAQ,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,QAAQ,OAAO;GACjE,OAAO,YAAY,IAAK,QAAQ,SAAS,YAAa;EACxD;EACA,MAAM,WAAW,MAAM,QAAQ,QAAQ,IAAI;EAC3C,IAAI,CAAC,SAAS,IAAI,MAAM,IAAI,iBAAiB,4BAA4B,SAAS,QAAQ;EAC1F,MAAM,UAAU,SAAS,MAAM,SAAS,KAAK,CAAC;EAC9C,IAAI,QAAQ,QAAQ,YAClB,MAAM,IAAI,iBAAiB,4CAA4C;EACzE,MAAM,OAAO,IAAI,IAAI,QAAQ,UAAU,MAAM;EAC7C,IAAI,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,SAAS,KAAK,QAAQ,GAC7C,MAAM,IAAI,iBAAiB,gCAAgC;EAC7D,MAAM,UAA0B,CAAC;EACjC,MAAM,sBAAM,IAAI,IAAY;EAC5B,KAAK,MAAM,cAAc,QAAQ,QAAQ;GACvC,IACE,WAAW,WAAW,QAAQ,UAC9B,WAAW,QAAQ,QAAQ,SAAS,QAAQ,OAE5C,MAAM,IAAI,iBAAiB,wBAAwB;GACrD,MAAM,WAAW,IAAI,IAAI,WAAW,MAAM,MAAM;GAChD,IAAI,SAAS,WAAW,OAAO,UAAU,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,SAAS,SAAS,QAAQ,GACtF,MAAM,IAAI,iBAAiB,kCAAkC;GAC/D,MAAM,gBAAgB,MAAM,QAAQ,UAAU,IAAI;GAClD,IAAI,cAAc,WAAW,OAAO,cAAc,WAAW,KAC3D,MAAM,IAAI,kBAAkB,2BAA2B;GACzD,IAAI,CAAC,cAAc,IACjB,MAAM,IAAI,iBAAiB,yBAAyB,cAAc,QAAQ;GAC5E,MAAM,OAAgB,MAAM,cAAc,KAAK;GAC/C,IAAI,CAAC,OAAO,IAAI,KAAK,KAAK,YAAY,KAAK,KAAK,aAAa,QAAQ,UACnE,MAAM,IAAI,kBAAkB,0BAA0B;GACxD,IACE,KAAK,WAAW,WAAW,UAC3B,KAAK,UAAU,QAAQ,SACvB,CAAC,MAAM,QAAQ,KAAK,OAAO,KAC3B,KAAK,QAAQ,WAAW,WAAW,OAEnC,MAAM,IAAI,iBAAiB,wBAAwB;GACrD,KAAK,MAAM,OAAO,KAAK,SAAS;IAC9B,MAAM,SAAS,MAAM,KAAK,IAAI;IAC9B,IAAI,IAAI,IAAI,OAAO,EAAE,GAAG,MAAM,IAAI,iBAAiB,oBAAoB;IACvE,IAAI,IAAI,OAAO,EAAE;IACjB,QAAQ,KAAK,MAAM;GACrB;EACF;EACA,IAAI,QAAQ,WAAW,QAAQ,OAAO,MAAM,IAAI,iBAAiB,oBAAoB;EACrF,OAAO;GAAE,UAAU;GAAS;EAAQ;CACtC,SAAS,OAAO;EACd,IAAI,QAAQ,QAAQ,WAAW,EAAE,iBAAiB,sBAAsB,YAAY,GAClF,MAAM;CACV;CAEF,MAAM,IAAI,iBAAiB,qBAAqB;AAClD;;AAKA,SAAgB,oBACd,OACA,UACA,aAAa,KACY;CACzB,IAAI,CAAC,MAAM,QAAQ,KAAK,KAAK,MAAM,SAAS,YAC1C,MAAM,IAAI,iBAAiB,oBAAoB;CACjD,MAAM,OAAO,IAAI,IAAI,QAAQ,GAC3B,sBAAM,IAAI,IAAY;CACxB,MAAM,SAAS,MAAM,KAAK,QAAQ,MAAM,KAAK,IAAI,CAAC;CAClD,KAAK,MAAM,UAAU,QAAQ;EAC3B,IAAI,IAAI,IAAI,OAAO,EAAE,GAAG,MAAM,IAAI,iBAAiB,oBAAoB;EACvE,IAAI,IAAI,OAAO,EAAE;CACnB;CACA,OAAO;AACT"}
@@ -0,0 +1,39 @@
1
+ import { A as ImageSource, B as JsonValue, C as RenderedPage, D as SymlinkMetadata, E as SortOptions, F as MetadataValue, I as PageMetadata, L as ResolvedMetadataContext, M as MetadataImage, N as MetadataImageValue, O as ThemeContext, P as MetadataOptions, R as ThemeMetadataDefaults, S as OutputNameResolver, T as SortField, V as copyJsonObject, _ as FileTimes, a as ListingPage, b as MetadataProviderFactory, c as ListingPolicyContext, d as validateListingPlan, f as DirectoryData, g as FileSystemEntry, h as FileMetadata, i as ListingManifest, j as MetadataContext, k as ContentCounts, l as listingRevision, m as ExplorerTheme, n as ListingContext, o as ListingPlan, p as EntryKind, r as ListingEntry, s as ListingPolicy, t as ListingBlock, u as projectListingEntry, v as GenerateOptions, w as SortDirection, x as NameSortMode, y as MetadataProvider, z as JsonObject } from "./listing-CnkSglVT.mjs";
2
+ import { FileHandle } from "node:fs/promises";
3
+ //#region src/generator.d.ts
4
+ export declare const defaultOutputName: OutputNameResolver;
5
+ export declare function compareEntries(left: FileSystemEntry, right: FileSystemEntry, options?: SortOptions): number;
6
+ export declare function generateExplorer(options: GenerateOptions): Promise<void>;
7
+ /** Internal entry point for hosts that stage previews outside their published output. */
8
+ export declare function generateExplorerSkippingPaths(options: GenerateOptions, ignoredPaths: readonly string[]): Promise<void>;
9
+ export declare function readGeneratedPage(filePath: string): Promise<string>;
10
+ //#endregion
11
+ //#region src/html.d.ts
12
+ /** Escape untrusted text for HTML/XML text nodes and double-quoted attributes. */
13
+ export declare function escapeHtml(value: string): string;
14
+ //#endregion
15
+ //#region src/service.d.ts
16
+ interface DirectoryServiceOptions {
17
+ readonly root: string;
18
+ readonly include?: string | readonly string[];
19
+ readonly exclude?: string | readonly string[];
20
+ readonly sort?: SortOptions;
21
+ }
22
+ interface DirectoryService {
23
+ readonly resolvePath: (logicalPath: string) => Promise<string>;
24
+ readonly openFile: (logicalPath: string) => Promise<{
25
+ readonly entry: FileSystemEntry;
26
+ readonly handle: FileHandle;
27
+ readonly canonicalPath: string;
28
+ }>;
29
+ readonly getEntry: (logicalPath: string) => Promise<FileSystemEntry>;
30
+ readonly listDirectory: (logicalPath: string) => Promise<DirectoryData>;
31
+ }
32
+ export declare class DirectoryAccessError extends Error {
33
+ readonly name = "DirectoryAccessError";
34
+ }
35
+ /** Live reads; no watcher, recursive stat snapshot, output tree or implicit cache. */
36
+ export declare function createDirectoryService(options: DirectoryServiceOptions): Promise<DirectoryService>;
37
+ //#endregion
38
+ export { type ContentCounts, type DirectoryData, type DirectoryService, type DirectoryServiceOptions, type EntryKind, type ExplorerTheme, type FileMetadata, type FileSystemEntry, type FileTimes, type GenerateOptions, type ImageSource, type JsonObject, type JsonValue, type ListingBlock, type ListingContext, type ListingEntry, type ListingManifest, type ListingPage, type ListingPlan, type ListingPolicy, type ListingPolicyContext, type MetadataContext, type MetadataImage, type MetadataImageValue, type MetadataOptions, type MetadataProvider, type MetadataProviderFactory, type MetadataValue, type NameSortMode, type OutputNameResolver, type PageMetadata, type RenderedPage, type ResolvedMetadataContext, type SortDirection, type SortField, type SortOptions, type SymlinkMetadata, type ThemeContext, type ThemeMetadataDefaults, copyJsonObject, listingRevision, projectListingEntry, validateListingPlan };
39
+ //# sourceMappingURL=index.d.mts.map