@superbee/core 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/dist/backend.d.ts +77 -0
- package/dist/backend.d.ts.map +1 -0
- package/dist/backend.js +380 -0
- package/dist/backend.js.map +1 -0
- package/dist/bundle.d.ts +38 -0
- package/dist/bundle.d.ts.map +1 -0
- package/dist/bundle.js +107 -0
- package/dist/bundle.js.map +1 -0
- package/dist/content-type.d.ts +72 -0
- package/dist/content-type.d.ts.map +1 -0
- package/dist/content-type.js +149 -0
- package/dist/content-type.js.map +1 -0
- package/dist/document-mutation.d.ts +83 -0
- package/dist/document-mutation.d.ts.map +1 -0
- package/dist/document-mutation.js +319 -0
- package/dist/document-mutation.js.map +1 -0
- package/dist/document-precondition.d.ts +62 -0
- package/dist/document-precondition.d.ts.map +1 -0
- package/dist/document-precondition.js +134 -0
- package/dist/document-precondition.js.map +1 -0
- package/dist/document-write-policy.d.ts +42 -0
- package/dist/document-write-policy.d.ts.map +1 -0
- package/dist/document-write-policy.js +134 -0
- package/dist/document-write-policy.js.map +1 -0
- package/dist/engine.d.ts +48 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +209 -0
- package/dist/engine.js.map +1 -0
- package/dist/errors.d.ts +36 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +50 -0
- package/dist/errors.js.map +1 -0
- package/dist/filesystem-identity.d.ts +208 -0
- package/dist/filesystem-identity.d.ts.map +1 -0
- package/dist/filesystem-identity.js +675 -0
- package/dist/filesystem-identity.js.map +1 -0
- package/dist/filesystem-lock.d.ts +65 -0
- package/dist/filesystem-lock.d.ts.map +1 -0
- package/dist/filesystem-lock.js +460 -0
- package/dist/filesystem-lock.js.map +1 -0
- package/dist/freshness.d.ts +31 -0
- package/dist/freshness.d.ts.map +1 -0
- package/dist/freshness.js +98 -0
- package/dist/freshness.js.map +1 -0
- package/dist/frontmatter-contract.d.ts +17 -0
- package/dist/frontmatter-contract.d.ts.map +1 -0
- package/dist/frontmatter-contract.js +29 -0
- package/dist/frontmatter-contract.js.map +1 -0
- package/dist/frontmatter.d.ts +30 -0
- package/dist/frontmatter.d.ts.map +1 -0
- package/dist/frontmatter.js +115 -0
- package/dist/frontmatter.js.map +1 -0
- package/dist/index-marker.d.ts +3 -0
- package/dist/index-marker.d.ts.map +1 -0
- package/dist/index-marker.js +3 -0
- package/dist/index-marker.js.map +1 -0
- package/dist/index-projection.d.ts +79 -0
- package/dist/index-projection.d.ts.map +1 -0
- package/dist/index-projection.js +245 -0
- package/dist/index-projection.js.map +1 -0
- package/dist/index.d.ts +68 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +110 -0
- package/dist/index.js.map +1 -0
- package/dist/kinds-load.d.ts +13 -0
- package/dist/kinds-load.d.ts.map +1 -0
- package/dist/kinds-load.js +34 -0
- package/dist/kinds-load.js.map +1 -0
- package/dist/kinds.d.ts +241 -0
- package/dist/kinds.d.ts.map +1 -0
- package/dist/kinds.js +1001 -0
- package/dist/kinds.js.map +1 -0
- package/dist/links.d.ts +62 -0
- package/dist/links.d.ts.map +1 -0
- package/dist/links.js +203 -0
- package/dist/links.js.map +1 -0
- package/dist/meaningful-change-time.d.ts +11 -0
- package/dist/meaningful-change-time.d.ts.map +1 -0
- package/dist/meaningful-change-time.js +16 -0
- package/dist/meaningful-change-time.js.map +1 -0
- package/dist/memory-backend.d.ts +55 -0
- package/dist/memory-backend.d.ts.map +1 -0
- package/dist/memory-backend.js +214 -0
- package/dist/memory-backend.js.map +1 -0
- package/dist/mutation-attribution.d.ts +19 -0
- package/dist/mutation-attribution.d.ts.map +1 -0
- package/dist/mutation-attribution.js +34 -0
- package/dist/mutation-attribution.js.map +1 -0
- package/dist/mutation.d.ts +89 -0
- package/dist/mutation.d.ts.map +1 -0
- package/dist/mutation.js +94 -0
- package/dist/mutation.js.map +1 -0
- package/dist/page.d.ts +87 -0
- package/dist/page.d.ts.map +1 -0
- package/dist/page.js +151 -0
- package/dist/page.js.map +1 -0
- package/dist/paths.d.ts +78 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +148 -0
- package/dist/paths.js.map +1 -0
- package/dist/portable-frontmatter.d.ts +8 -0
- package/dist/portable-frontmatter.d.ts.map +1 -0
- package/dist/portable-frontmatter.js +35 -0
- package/dist/portable-frontmatter.js.map +1 -0
- package/dist/publication-filesystem.d.ts +6 -0
- package/dist/publication-filesystem.d.ts.map +1 -0
- package/dist/publication-filesystem.js +6 -0
- package/dist/publication-filesystem.js.map +1 -0
- package/dist/query-filter.d.ts +12 -0
- package/dist/query-filter.d.ts.map +1 -0
- package/dist/query-filter.js +29 -0
- package/dist/query-filter.js.map +1 -0
- package/dist/query-selection.d.ts +25 -0
- package/dist/query-selection.d.ts.map +1 -0
- package/dist/query-selection.js +48 -0
- package/dist/query-selection.js.map +1 -0
- package/dist/remote-backend.d.ts +152 -0
- package/dist/remote-backend.d.ts.map +1 -0
- package/dist/remote-backend.js +505 -0
- package/dist/remote-backend.js.map +1 -0
- package/dist/remote.d.ts +4 -0
- package/dist/remote.d.ts.map +1 -0
- package/dist/remote.js +3 -0
- package/dist/remote.js.map +1 -0
- package/dist/storage.d.ts +7 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +6 -0
- package/dist/storage.js.map +1 -0
- package/dist/types.d.ts +438 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +12 -0
- package/dist/types.js.map +1 -0
- package/dist/validation.d.ts +22 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +12 -0
- package/dist/validation.js.map +1 -0
- package/dist/version-transport.d.ts +13 -0
- package/dist/version-transport.d.ts.map +1 -0
- package/dist/version-transport.js +26 -0
- package/dist/version-transport.js.map +1 -0
- package/dist/versioning.d.ts +48 -0
- package/dist/versioning.d.ts.map +1 -0
- package/dist/versioning.js +62 -0
- package/dist/versioning.js.map +1 -0
- package/package.json +84 -0
package/dist/page.js
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure View registry/entry path grammar shared by every producer and consumer.
|
|
3
|
+
*
|
|
4
|
+
* `View` is the ONLY accepted kind name: the legacy `Page` spelling is no longer read
|
|
5
|
+
* (the repo's `migrate-legacy-view-names` script renames legacy content in place). Registry ids
|
|
6
|
+
* are concept ids under `views-registry/` (legacy `pages-registry/` LOCATIONS stay recognized;
|
|
7
|
+
* relocation is a separate open decision); entries are opaque blob keys under
|
|
8
|
+
* `views/` (legacy `pages/`). Both retain exact, case-preserving nested paths while
|
|
9
|
+
* rejecting spellings that discovery or storage cannot safely round-trip. ONE segment
|
|
10
|
+
* grammar, parameterized by prefix — never a parallel module per name.
|
|
11
|
+
*/
|
|
12
|
+
import { assertSafeBlobKey, assertSafeConceptId } from "./paths.js";
|
|
13
|
+
/** Legacy registry-id prefix — the LOCATION stays recognized (only the legacy kind NAME is retired). */
|
|
14
|
+
export const PAGE_REGISTRY_PREFIX = "pages-registry/";
|
|
15
|
+
/** Legacy blob-key prefix for View entries — the LOCATION stays recognized. */
|
|
16
|
+
export const PAGE_ENTRY_PREFIX = "pages/";
|
|
17
|
+
/** Current registry-id prefix for `type: View` docs. */
|
|
18
|
+
export const VIEW_REGISTRY_PREFIX = "views-registry/";
|
|
19
|
+
/** Current blob-key prefix for View entries. */
|
|
20
|
+
export const VIEW_ENTRY_PREFIX = "views/";
|
|
21
|
+
/**
|
|
22
|
+
* The kind names the launcher/registry surfaces accept: exactly `View`. Exact, case-sensitive
|
|
23
|
+
* match. The legacy `Page` name is deliberately NOT here — a Page-typed doc no longer registers
|
|
24
|
+
* anywhere (the CLI's `status` legacy_naming finding is the loud diagnostic for leftover stock,
|
|
25
|
+
* and `migrate-legacy-view-names` is the remedy).
|
|
26
|
+
*/
|
|
27
|
+
export const PAGE_TYPE_NAMES = ["View"];
|
|
28
|
+
/** One capability resolver shared by registry parsing and the loopback server's security gates. */
|
|
29
|
+
export function resolveBridgeCapability(value) {
|
|
30
|
+
return value === "bundle-read" || value === "bundle-propose" ? value : "none";
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* THE one reader of the registry-doc capability FIELD: `access`, and ONLY `access`. The legacy
|
|
34
|
+
* `bridge` spelling is no longer read — a doc declaring only `bridge` resolves to `undefined`
|
|
35
|
+
* here and fails closed to `none` downstream (the `migrate-legacy-view-names` script renames
|
|
36
|
+
* existing stock in place; the CLI's `status` legacy_naming finding flags leftover `bridge`
|
|
37
|
+
* fields loudly).
|
|
38
|
+
*/
|
|
39
|
+
export function declaredAccessValue(frontmatter) {
|
|
40
|
+
// Own-property-gated: an INHERITED field (a crafted prototype, or a polluted
|
|
41
|
+
// Object.prototype) must never grant capability — only a field the doc itself declares counts.
|
|
42
|
+
return Object.hasOwn(frontmatter, "access") ? frontmatter.access : undefined;
|
|
43
|
+
}
|
|
44
|
+
/** Resolve a registry doc's declared capability: {@link declaredAccessValue} through the fail-closed {@link resolveBridgeCapability} — an absent or unrecognized `access` yields `none`. */
|
|
45
|
+
export function resolveDeclaredAccess(frontmatter) {
|
|
46
|
+
return resolveBridgeCapability(declaredAccessValue(frontmatter));
|
|
47
|
+
}
|
|
48
|
+
/** True iff `value` is exactly the accepted kind name (`View`). The legacy `Page` name is rejected. */
|
|
49
|
+
export function isPageTypeName(value) {
|
|
50
|
+
return value === "View";
|
|
51
|
+
}
|
|
52
|
+
const PAGE_SEGMENT = /^[A-Za-z0-9._-]+$/;
|
|
53
|
+
/**
|
|
54
|
+
* `.md` (checked case-insensitively) is rejected on EVERY segment, not just the last: a mid-path
|
|
55
|
+
* segment like `x.md` in `pages-registry/x.md/y` would create an on-disk DIRECTORY literally named
|
|
56
|
+
* `x.md`, blocking a future concept-doc write to id `pages-registry/x` (the exact
|
|
57
|
+
* doc/dir collision {@link assertSafeBlobKey} already documents on the entry-key side). ONE
|
|
58
|
+
* shared check for both the registry-id and
|
|
59
|
+
* entry-key grammars, so the two paths can't drift again the way they did before this fix (the
|
|
60
|
+
* entry-key side already inherited this via `assertSafeBlobKey`; the registry-id side did not).
|
|
61
|
+
*/
|
|
62
|
+
function hasSafePageSegments(value, prefix) {
|
|
63
|
+
if (!value.startsWith(prefix) || value.length === prefix.length)
|
|
64
|
+
return false;
|
|
65
|
+
if (value.startsWith("/") || /[\\%?#]/.test(value))
|
|
66
|
+
return false;
|
|
67
|
+
const segments = value.slice(prefix.length).split("/");
|
|
68
|
+
return segments.every((segment) => !segment.startsWith(".") && PAGE_SEGMENT.test(segment) && !segment.toLowerCase().endsWith(".md"));
|
|
69
|
+
}
|
|
70
|
+
function isRegistryIdUnder(id, prefix) {
|
|
71
|
+
if (typeof id !== "string" || !hasSafePageSegments(id, prefix)) {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
try {
|
|
75
|
+
assertSafeConceptId(id);
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function isEntryKeyUnder(entry, prefix) {
|
|
83
|
+
if (typeof entry !== "string" || !hasSafePageSegments(entry, prefix))
|
|
84
|
+
return false;
|
|
85
|
+
try {
|
|
86
|
+
assertSafeBlobKey(entry);
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/** Strict concept-id grammar for registry documents at the legacy LOCATION (`pages-registry/…`). Nested ids and ordinary dots are valid. */
|
|
94
|
+
export function isPageRegistryId(id) {
|
|
95
|
+
return isRegistryIdUnder(id, PAGE_REGISTRY_PREFIX);
|
|
96
|
+
}
|
|
97
|
+
/** Strict concept-id grammar for View registry documents (`views-registry/…`) — the SAME segment rules as {@link isPageRegistryId}. */
|
|
98
|
+
export function isViewRegistryId(id) {
|
|
99
|
+
return isRegistryIdUnder(id, VIEW_REGISTRY_PREFIX);
|
|
100
|
+
}
|
|
101
|
+
/** True iff `id` is a valid registry id under EITHER accepted prefix (`views-registry/` or legacy `pages-registry/`). */
|
|
102
|
+
export function isAnyRegistryId(id) {
|
|
103
|
+
return isPageRegistryId(id) || isViewRegistryId(id);
|
|
104
|
+
}
|
|
105
|
+
/** Strict blob-key grammar for executable View entries at the legacy LOCATION (`pages/…`). */
|
|
106
|
+
export function isPageEntryKey(entry) {
|
|
107
|
+
return isEntryKeyUnder(entry, PAGE_ENTRY_PREFIX);
|
|
108
|
+
}
|
|
109
|
+
/** Strict blob-key grammar for executable View entries (`views/…`) — the SAME segment rules as {@link isPageEntryKey}. */
|
|
110
|
+
export function isViewEntryKey(entry) {
|
|
111
|
+
return isEntryKeyUnder(entry, VIEW_ENTRY_PREFIX);
|
|
112
|
+
}
|
|
113
|
+
/** True iff `entry` is a valid entry key under EITHER accepted prefix (`views/` or legacy `pages/`). */
|
|
114
|
+
export function isAnyEntryKey(entry) {
|
|
115
|
+
return isPageEntryKey(entry) || isViewEntryKey(entry);
|
|
116
|
+
}
|
|
117
|
+
/** True only for the content-addressed version tokens allowed to pin executable View bytes. */
|
|
118
|
+
export function isViewEntryVersion(value) {
|
|
119
|
+
return typeof value === "string" && /^sha256:[0-9a-f]{64}$/.test(value);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* THE one registration predicate: a doc is a usable View registration iff its id satisfies
|
|
123
|
+
* an accepted registry-id grammar ({@link isAnyRegistryId}), its `type` is exactly an accepted
|
|
124
|
+
* kind name ({@link isPageTypeName}), AND its `entry` satisfies an accepted entry-key grammar
|
|
125
|
+
* ({@link isAnyEntryKey}). An explicitly declared `entry_version` must be a canonical
|
|
126
|
+
* content-addressed token. Returns the validated registration, or `null`.
|
|
127
|
+
*
|
|
128
|
+
* This is a SECURITY boundary shared by every surface that decides what counts as a registered
|
|
129
|
+
* page — the launcher/`open-page` parse (ui `parseRegisteredPage`), the `ui` command's
|
|
130
|
+
* nonce-mint allowlist, and its serve-time re-verification. All of them MUST consume this one
|
|
131
|
+
* function: a doc any surface rejects must be un-mintable and un-servable everywhere, never
|
|
132
|
+
* "rejected by the launcher but still served by the nonce route".
|
|
133
|
+
*/
|
|
134
|
+
export function parseRegistration(id, frontmatter) {
|
|
135
|
+
if (!isAnyRegistryId(id) || !isPageTypeName(frontmatter.type) || !isAnyEntryKey(frontmatter.entry))
|
|
136
|
+
return null;
|
|
137
|
+
const rawEntryVersion = Object.hasOwn(frontmatter, "entry_version")
|
|
138
|
+
? frontmatter.entry_version
|
|
139
|
+
: undefined;
|
|
140
|
+
if (rawEntryVersion !== undefined &&
|
|
141
|
+
!isViewEntryVersion(rawEntryVersion)) {
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
return {
|
|
145
|
+
id,
|
|
146
|
+
type: frontmatter.type,
|
|
147
|
+
entry: frontmatter.entry,
|
|
148
|
+
...(rawEntryVersion ? { entryVersion: rawEntryVersion } : {}),
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=page.js.map
|
package/dist/page.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page.js","sourceRoot":"","sources":["../src/page.ts"],"names":[],"mappings":"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"}
|
package/dist/paths.d.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure path helpers for OKF concept identity and reserved-file handling.
|
|
3
|
+
*
|
|
4
|
+
* A *Concept ID* is a bundle-relative path with the trailing `.md` removed
|
|
5
|
+
* (`tables/users.md` -> `tables/users`); IDs use forward slashes. Two filenames
|
|
6
|
+
* are RESERVED at any directory level — `index.md` (§6) and `log.md` (§7) — and
|
|
7
|
+
* are NOT concept documents (they carry no `type` and are excluded from queries).
|
|
8
|
+
*
|
|
9
|
+
* Everything here is pure and dependency-free, hence directly unit-testable.
|
|
10
|
+
*/
|
|
11
|
+
import type { ConceptId } from "./types.js";
|
|
12
|
+
/** The two OKF reserved filenames, valid at any directory level (§3.1). */
|
|
13
|
+
export declare const RESERVED_FILENAMES: readonly ["index.md", "log.md"];
|
|
14
|
+
/** Normalize any separators to forward slashes and collapse duplicate slashes. */
|
|
15
|
+
export declare function toPosix(p: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* True when the bundle-relative path's final segment is a reserved OKF filename
|
|
18
|
+
* (`index.md` / `log.md`) at ANY directory level.
|
|
19
|
+
*/
|
|
20
|
+
export declare function isReservedFile(relPath: string): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Concept ID from a bundle-relative markdown file path: normalize separators,
|
|
23
|
+
* drop a leading `./` or `/`, and strip the trailing `.md`.
|
|
24
|
+
*/
|
|
25
|
+
export declare function conceptIdFromPath(relPath: string): ConceptId;
|
|
26
|
+
/**
|
|
27
|
+
* Bundle-relative markdown file path for an ALREADY-CANONICAL concept ID.
|
|
28
|
+
*
|
|
29
|
+
* A concept ID is the file path with exactly its FINAL `.md` suffix removed. Therefore an
|
|
30
|
+
* ordinary `x.md` file has id `x`, while a valid `x.md.md` file has id `x.md`. Do not strip a
|
|
31
|
+
* suffix here: doing so aliases those two distinct concepts onto the same physical file. User
|
|
32
|
+
* interfaces that accept file-like spellings normalize them through {@link conceptIdFromPath}
|
|
33
|
+
* before entering the engine/storage seam.
|
|
34
|
+
*/
|
|
35
|
+
export declare function pathFromConceptId(id: ConceptId): string;
|
|
36
|
+
/**
|
|
37
|
+
* Guard the canonical concept-ID grammar before an id reaches storage. In addition to path
|
|
38
|
+
* traversal / absolute escape, aliases that a filesystem would silently normalize (`./`, `//`,
|
|
39
|
+
* `\\`, or an interior `.` segment) are rejected so every backend keys the SAME identity.
|
|
40
|
+
* File-like user input is normalized before this boundary with {@link conceptIdFromPath}.
|
|
41
|
+
*/
|
|
42
|
+
export declare function assertSafeConceptId(id: ConceptId): void;
|
|
43
|
+
/**
|
|
44
|
+
* Guard a blob key before it is joined onto the bundle root for a filesystem read or
|
|
45
|
+
* write. Same traversal/absolute-escape shape as {@link assertSafeConceptId}, PLUS
|
|
46
|
+
* three blob-specific rejections so the blob and concept-document namespaces stay
|
|
47
|
+
* disjoint in both directions:
|
|
48
|
+
* - ANY segment ending in `.md`, checked CASE-INSENSITIVELY (`report.MD` would collide
|
|
49
|
+
* with `report.md` on a case-insensitive filesystem such as APFS, silently bypassing
|
|
50
|
+
* concept-doc CAS and getting ingested as a doc by the next bundle walk) — not just
|
|
51
|
+
* the FINAL segment: a key like `report.md/attachment.png` would otherwise pass (its
|
|
52
|
+
* final segment is `attachment.png`) while creating an on-disk DIRECTORY literally
|
|
53
|
+
* named `report.md`, which collides with — and blocks — any future concept doc write
|
|
54
|
+
* to id `report` (`pathFromConceptId("report")` targets that exact path as a FILE).
|
|
55
|
+
* This also covers the two reserved filenames (`index.md`/`log.md`), which always
|
|
56
|
+
* carry that extension, at any depth.
|
|
57
|
+
* - any dot-prefixed path segment (invisible to the concept walk by convention, and
|
|
58
|
+
* the exact shape `FilesystemBackend.atomicWrite`'s own temp files use — a blob key
|
|
59
|
+
* must never collide with that).
|
|
60
|
+
* - a trailing-slash / empty final segment (a blob key must name a file, not a dir).
|
|
61
|
+
* Applies to EVERY blob operation — read and exists included, not just write — so a
|
|
62
|
+
* probing `readBlob`/`existsBlob` can't be used to bypass the guard writes enforce.
|
|
63
|
+
*
|
|
64
|
+
* Note (raw-vs-normalized storage): like a {@link ConceptId}, the key's non-extension
|
|
65
|
+
* segments are stored VERBATIM (case preserved, no other normalization) — this mirrors
|
|
66
|
+
* the engine's pre-existing concept-id behavior (an id's casing/spelling is exactly what
|
|
67
|
+
* the caller wrote) rather than introducing a NEW normalization rule just for blobs.
|
|
68
|
+
*/
|
|
69
|
+
export declare function assertSafeBlobKey(key: string): void;
|
|
70
|
+
/**
|
|
71
|
+
* Guard a reserved-file directory (the `dir` argument to `readReserved`/`writeReserved`,
|
|
72
|
+
* where `""` denotes the bundle root) against path traversal / absolute escape before it
|
|
73
|
+
* is joined onto the bundle root. Unlike {@link assertSafeConceptId}, an empty string IS
|
|
74
|
+
* valid here (it means "the bundle root itself"). Throws on a non-string, an absolute
|
|
75
|
+
* dir, or any `..` segment.
|
|
76
|
+
*/
|
|
77
|
+
export declare function assertSafeReservedDir(dir: string): void;
|
|
78
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAG5C,2EAA2E;AAC3E,eAAO,MAAM,kBAAkB,iCAAkC,CAAC;AAElE,kFAAkF;AAClF,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEzC;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAGvD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAO5D;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,SAAS,GAAG,MAAM,CAGvD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,SAAS,GAAG,IAAI,CAwBvD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CA0BnD;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAWvD"}
|
package/dist/paths.js
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure path helpers for OKF concept identity and reserved-file handling.
|
|
3
|
+
*
|
|
4
|
+
* A *Concept ID* is a bundle-relative path with the trailing `.md` removed
|
|
5
|
+
* (`tables/users.md` -> `tables/users`); IDs use forward slashes. Two filenames
|
|
6
|
+
* are RESERVED at any directory level — `index.md` (§6) and `log.md` (§7) — and
|
|
7
|
+
* are NOT concept documents (they carry no `type` and are excluded from queries).
|
|
8
|
+
*
|
|
9
|
+
* Everything here is pure and dependency-free, hence directly unit-testable.
|
|
10
|
+
*/
|
|
11
|
+
import { InvalidInputError } from "./errors.js";
|
|
12
|
+
/** The two OKF reserved filenames, valid at any directory level (§3.1). */
|
|
13
|
+
export const RESERVED_FILENAMES = ["index.md", "log.md"];
|
|
14
|
+
/** Normalize any separators to forward slashes and collapse duplicate slashes. */
|
|
15
|
+
export function toPosix(p) {
|
|
16
|
+
return p.replace(/\\/g, "/").replace(/\/{2,}/g, "/");
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* True when the bundle-relative path's final segment is a reserved OKF filename
|
|
20
|
+
* (`index.md` / `log.md`) at ANY directory level.
|
|
21
|
+
*/
|
|
22
|
+
export function isReservedFile(relPath) {
|
|
23
|
+
const base = toPosix(relPath).split("/").pop() ?? "";
|
|
24
|
+
return RESERVED_FILENAMES.includes(base);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Concept ID from a bundle-relative markdown file path: normalize separators,
|
|
28
|
+
* drop a leading `./` or `/`, and strip the trailing `.md`.
|
|
29
|
+
*/
|
|
30
|
+
export function conceptIdFromPath(relPath) {
|
|
31
|
+
const norm = toPosix(relPath)
|
|
32
|
+
.replace(/^\.?\//, "")
|
|
33
|
+
.split("/")
|
|
34
|
+
.filter((segment) => segment !== ".")
|
|
35
|
+
.join("/");
|
|
36
|
+
return norm.endsWith(".md") ? norm.slice(0, -3) : norm;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Bundle-relative markdown file path for an ALREADY-CANONICAL concept ID.
|
|
40
|
+
*
|
|
41
|
+
* A concept ID is the file path with exactly its FINAL `.md` suffix removed. Therefore an
|
|
42
|
+
* ordinary `x.md` file has id `x`, while a valid `x.md.md` file has id `x.md`. Do not strip a
|
|
43
|
+
* suffix here: doing so aliases those two distinct concepts onto the same physical file. User
|
|
44
|
+
* interfaces that accept file-like spellings normalize them through {@link conceptIdFromPath}
|
|
45
|
+
* before entering the engine/storage seam.
|
|
46
|
+
*/
|
|
47
|
+
export function pathFromConceptId(id) {
|
|
48
|
+
assertSafeConceptId(id);
|
|
49
|
+
return `${id}.md`;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Guard the canonical concept-ID grammar before an id reaches storage. In addition to path
|
|
53
|
+
* traversal / absolute escape, aliases that a filesystem would silently normalize (`./`, `//`,
|
|
54
|
+
* `\\`, or an interior `.` segment) are rejected so every backend keys the SAME identity.
|
|
55
|
+
* File-like user input is normalized before this boundary with {@link conceptIdFromPath}.
|
|
56
|
+
*/
|
|
57
|
+
export function assertSafeConceptId(id) {
|
|
58
|
+
if (typeof id !== "string" || id.trim() === "") {
|
|
59
|
+
throw new InvalidInputError("Concept id must be a non-empty string.");
|
|
60
|
+
}
|
|
61
|
+
if (id.startsWith("/")) {
|
|
62
|
+
throw new InvalidInputError(`Concept id must be bundle-relative, got absolute '${id}'.`);
|
|
63
|
+
}
|
|
64
|
+
if (id.includes("\\")) {
|
|
65
|
+
throw new InvalidInputError(`Concept id must use forward slashes: '${id}'.`);
|
|
66
|
+
}
|
|
67
|
+
const segments = id.split("/");
|
|
68
|
+
if (segments.some((seg) => seg === "..")) {
|
|
69
|
+
throw new InvalidInputError(`Concept id must not contain '..' segments: '${id}'.`);
|
|
70
|
+
}
|
|
71
|
+
if (segments.some((seg) => seg === "." || seg === "")) {
|
|
72
|
+
throw new InvalidInputError(`Concept id must be canonical (no '.', duplicate-slash, leading './', or trailing-slash segments): '${id}'.`);
|
|
73
|
+
}
|
|
74
|
+
if (segments.slice(0, -1).some((seg) => seg.toLowerCase().endsWith(".md"))) {
|
|
75
|
+
throw new InvalidInputError(`Concept id must not contain a non-final segment ending in '.md': '${id}' (it collides with a concept file at that path).`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Guard a blob key before it is joined onto the bundle root for a filesystem read or
|
|
80
|
+
* write. Same traversal/absolute-escape shape as {@link assertSafeConceptId}, PLUS
|
|
81
|
+
* three blob-specific rejections so the blob and concept-document namespaces stay
|
|
82
|
+
* disjoint in both directions:
|
|
83
|
+
* - ANY segment ending in `.md`, checked CASE-INSENSITIVELY (`report.MD` would collide
|
|
84
|
+
* with `report.md` on a case-insensitive filesystem such as APFS, silently bypassing
|
|
85
|
+
* concept-doc CAS and getting ingested as a doc by the next bundle walk) — not just
|
|
86
|
+
* the FINAL segment: a key like `report.md/attachment.png` would otherwise pass (its
|
|
87
|
+
* final segment is `attachment.png`) while creating an on-disk DIRECTORY literally
|
|
88
|
+
* named `report.md`, which collides with — and blocks — any future concept doc write
|
|
89
|
+
* to id `report` (`pathFromConceptId("report")` targets that exact path as a FILE).
|
|
90
|
+
* This also covers the two reserved filenames (`index.md`/`log.md`), which always
|
|
91
|
+
* carry that extension, at any depth.
|
|
92
|
+
* - any dot-prefixed path segment (invisible to the concept walk by convention, and
|
|
93
|
+
* the exact shape `FilesystemBackend.atomicWrite`'s own temp files use — a blob key
|
|
94
|
+
* must never collide with that).
|
|
95
|
+
* - a trailing-slash / empty final segment (a blob key must name a file, not a dir).
|
|
96
|
+
* Applies to EVERY blob operation — read and exists included, not just write — so a
|
|
97
|
+
* probing `readBlob`/`existsBlob` can't be used to bypass the guard writes enforce.
|
|
98
|
+
*
|
|
99
|
+
* Note (raw-vs-normalized storage): like a {@link ConceptId}, the key's non-extension
|
|
100
|
+
* segments are stored VERBATIM (case preserved, no other normalization) — this mirrors
|
|
101
|
+
* the engine's pre-existing concept-id behavior (an id's casing/spelling is exactly what
|
|
102
|
+
* the caller wrote) rather than introducing a NEW normalization rule just for blobs.
|
|
103
|
+
*/
|
|
104
|
+
export function assertSafeBlobKey(key) {
|
|
105
|
+
if (typeof key !== "string" || key.trim() === "") {
|
|
106
|
+
throw new InvalidInputError("Blob key must be a non-empty string.");
|
|
107
|
+
}
|
|
108
|
+
const norm = toPosix(key);
|
|
109
|
+
if (norm.startsWith("/")) {
|
|
110
|
+
throw new InvalidInputError(`Blob key must be bundle-relative, got absolute '${key}'.`);
|
|
111
|
+
}
|
|
112
|
+
const segments = norm.split("/");
|
|
113
|
+
if (segments.some((seg) => seg === "..")) {
|
|
114
|
+
throw new InvalidInputError(`Blob key must not contain '..' segments: '${key}'.`);
|
|
115
|
+
}
|
|
116
|
+
if (segments.some((seg) => seg.startsWith("."))) {
|
|
117
|
+
throw new InvalidInputError(`Blob key must not contain dot-prefixed segments: '${key}'.`);
|
|
118
|
+
}
|
|
119
|
+
const last = segments[segments.length - 1] ?? "";
|
|
120
|
+
if (last === "") {
|
|
121
|
+
throw new InvalidInputError(`Blob key must name a file, not end with '/': '${key}'.`);
|
|
122
|
+
}
|
|
123
|
+
if (segments.some((seg) => seg.toLowerCase().endsWith(".md"))) {
|
|
124
|
+
throw new InvalidInputError(`Blob key '${key}' has a path segment ending in '.md' (checked case-insensitively, at ` +
|
|
125
|
+
`any depth), which collides with the concept-document namespace — write it as a doc ` +
|
|
126
|
+
`instead.`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Guard a reserved-file directory (the `dir` argument to `readReserved`/`writeReserved`,
|
|
131
|
+
* where `""` denotes the bundle root) against path traversal / absolute escape before it
|
|
132
|
+
* is joined onto the bundle root. Unlike {@link assertSafeConceptId}, an empty string IS
|
|
133
|
+
* valid here (it means "the bundle root itself"). Throws on a non-string, an absolute
|
|
134
|
+
* dir, or any `..` segment.
|
|
135
|
+
*/
|
|
136
|
+
export function assertSafeReservedDir(dir) {
|
|
137
|
+
if (typeof dir !== "string") {
|
|
138
|
+
throw new InvalidInputError("Reserved-file directory must be a string.");
|
|
139
|
+
}
|
|
140
|
+
const norm = toPosix(dir);
|
|
141
|
+
if (norm.startsWith("/")) {
|
|
142
|
+
throw new InvalidInputError(`Reserved-file directory must be bundle-relative, got absolute '${dir}'.`);
|
|
143
|
+
}
|
|
144
|
+
if (norm.split("/").some((seg) => seg === "..")) {
|
|
145
|
+
throw new InvalidInputError(`Reserved-file directory must not contain '..' segments: '${dir}'.`);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Browser/Worker-safe parsing for the bundle-root OKF edition marker. */
|
|
2
|
+
import type { Frontmatter } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Parse only a leading YAML frontmatter block. This deliberately avoids gray-matter: that package
|
|
5
|
+
* constructs a Node Buffer while parsing even a string, so it cannot execute in a Worker runtime.
|
|
6
|
+
*/
|
|
7
|
+
export declare function parseLeadingFrontmatter(raw: string, context?: string): Frontmatter;
|
|
8
|
+
//# sourceMappingURL=portable-frontmatter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"portable-frontmatter.d.ts","sourceRoot":"","sources":["../src/portable-frontmatter.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAK1E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,WAAW,CAwBlF"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/** Browser/Worker-safe parsing for the bundle-root OKF edition marker. */
|
|
2
|
+
import yaml from "js-yaml";
|
|
3
|
+
import { MalformedDocumentError } from "./frontmatter-contract.js";
|
|
4
|
+
/**
|
|
5
|
+
* Parse only a leading YAML frontmatter block. This deliberately avoids gray-matter: that package
|
|
6
|
+
* constructs a Node Buffer while parsing even a string, so it cannot execute in a Worker runtime.
|
|
7
|
+
*/
|
|
8
|
+
export function parseLeadingFrontmatter(raw, context) {
|
|
9
|
+
// Match the legacy parser's UTF-8 text behavior without pulling its Buffer-dependent package
|
|
10
|
+
// into the portable graph. Only a single file-leading BOM is an encoding marker.
|
|
11
|
+
const input = raw.startsWith("\uFEFF") ? raw.slice(1) : raw;
|
|
12
|
+
if (!/^---(?:\r?\n|$)/.test(input))
|
|
13
|
+
return {};
|
|
14
|
+
const firstLineEnd = input.indexOf("\n");
|
|
15
|
+
const afterOpening = firstLineEnd === -1 ? "" : input.slice(firstLineEnd + 1);
|
|
16
|
+
const closing = /^---\r?$/m.exec(afterOpening);
|
|
17
|
+
if (!closing) {
|
|
18
|
+
throw new MalformedDocumentError(context, new Error("unterminated YAML frontmatter delimiter"));
|
|
19
|
+
}
|
|
20
|
+
try {
|
|
21
|
+
const parsed = yaml.safeLoad(afterOpening.slice(0, closing.index));
|
|
22
|
+
if (parsed === undefined || parsed === null)
|
|
23
|
+
return {};
|
|
24
|
+
if (typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
25
|
+
throw new TypeError("YAML frontmatter must be a mapping");
|
|
26
|
+
}
|
|
27
|
+
return parsed;
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
if (error instanceof MalformedDocumentError)
|
|
31
|
+
throw error;
|
|
32
|
+
throw new MalformedDocumentError(context, error);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=portable-frontmatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"portable-frontmatter.js","sourceRoot":"","sources":["../src/portable-frontmatter.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAE1E,OAAO,IAAI,MAAM,SAAS,CAAC;AAE3B,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAGnE;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,GAAW,EAAE,OAAgB;IACnE,6FAA6F;IAC7F,iFAAiF;IACjF,MAAM,KAAK,GAAG,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAC5D,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,EAAiB,CAAC;IAE7D,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,MAAM,YAAY,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC;IAC9E,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC/C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,sBAAsB,CAAC,OAAO,EAAE,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC,CAAC;IAClG,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;QACnE,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO,EAAiB,CAAC;QACtE,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACxD,MAAM,IAAI,SAAS,CAAC,oCAAoC,CAAC,CAAC;QAC5D,CAAC;QACD,OAAO,MAAqB,CAAC;IAC/B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,sBAAsB;YAAE,MAAM,KAAK,CAAC;QACzD,MAAM,IAAI,sBAAsB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACnD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Publication-only filesystem capture helpers. This subpath deliberately does not widen the
|
|
3
|
+
* stable StorageBackend seam or the main `@superbee/core` export surface.
|
|
4
|
+
*/
|
|
5
|
+
export { listFilesystemReservedObjects, readRawFilesystemDocument, readRawFilesystemReserved, } from "./backend.js";
|
|
6
|
+
//# sourceMappingURL=publication-filesystem.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publication-filesystem.d.ts","sourceRoot":"","sources":["../src/publication-filesystem.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EACL,6BAA6B,EAC7B,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Publication-only filesystem capture helpers. This subpath deliberately does not widen the
|
|
3
|
+
* stable StorageBackend seam or the main `@superbee/core` export surface.
|
|
4
|
+
*/
|
|
5
|
+
export { listFilesystemReservedObjects, readRawFilesystemDocument, readRawFilesystemReserved, } from "./backend.js";
|
|
6
|
+
//# sourceMappingURL=publication-filesystem.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publication-filesystem.js","sourceRoot":"","sources":["../src/publication-filesystem.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EACL,6BAA6B,EAC7B,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Browser-safe, storage-free query predicate shared by every head-projection consumer. */
|
|
2
|
+
import type { ConceptId, Frontmatter, QueryFilter } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* THE canonical {@link QueryFilter} predicate — every facet (`prefix`, `type`, `tags`, `fields`),
|
|
5
|
+
* ANDed. Kept in a storage-free module so both Node consumers and the browser View bridge can use
|
|
6
|
+
* the same scalar/array/string-coercion semantics without importing the filesystem-backed engine.
|
|
7
|
+
*/
|
|
8
|
+
export declare function matchesFilter(doc: {
|
|
9
|
+
id: ConceptId;
|
|
10
|
+
frontmatter: Frontmatter;
|
|
11
|
+
}, filter: QueryFilter): boolean;
|
|
12
|
+
//# sourceMappingURL=query-filter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-filter.d.ts","sourceRoot":"","sources":["../src/query-filter.ts"],"names":[],"mappings":"AAAA,2FAA2F;AAC3F,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEtE;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE;IAAE,EAAE,EAAE,SAAS,CAAC;IAAC,WAAW,EAAE,WAAW,CAAA;CAAE,EAChD,MAAM,EAAE,WAAW,GAClB,OAAO,CAmBT"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE canonical {@link QueryFilter} predicate — every facet (`prefix`, `type`, `tags`, `fields`),
|
|
3
|
+
* ANDed. Kept in a storage-free module so both Node consumers and the browser View bridge can use
|
|
4
|
+
* the same scalar/array/string-coercion semantics without importing the filesystem-backed engine.
|
|
5
|
+
*/
|
|
6
|
+
export function matchesFilter(doc, filter) {
|
|
7
|
+
if (filter.prefix && !doc.id.startsWith(filter.prefix))
|
|
8
|
+
return false;
|
|
9
|
+
if (filter.type && doc.frontmatter.type !== filter.type)
|
|
10
|
+
return false;
|
|
11
|
+
if (filter.tags && filter.tags.length > 0) {
|
|
12
|
+
const tags = Array.isArray(doc.frontmatter.tags) ? doc.frontmatter.tags : [];
|
|
13
|
+
if (!filter.tags.every((tag) => tags.includes(tag)))
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
if (filter.fields) {
|
|
17
|
+
const frontmatter = doc.frontmatter;
|
|
18
|
+
for (const [key, expected] of Object.entries(filter.fields)) {
|
|
19
|
+
const raw = frontmatter[key];
|
|
20
|
+
const actual = raw === undefined || raw === null
|
|
21
|
+
? []
|
|
22
|
+
: (Array.isArray(raw) ? raw : [raw]).map((value) => String(value));
|
|
23
|
+
if (!actual.includes(expected))
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=query-filter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-filter.js","sourceRoot":"","sources":["../src/query-filter.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAC3B,GAAgD,EAChD,MAAmB;IAEnB,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IACrE,IAAI,MAAM,CAAC,IAAI,IAAI,GAAG,CAAC,WAAW,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IACtE,IAAI,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7E,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;IACpE,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,MAAM,WAAW,GAAG,GAAG,CAAC,WAAsC,CAAC;QAC/D,KAAK,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5D,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;YAC7B,MAAM,MAAM,GACV,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,IAAI;gBAC/B,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YACvE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBAAE,OAAO,KAAK,CAAC;QAC/C,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-safe post-filtering shared by human-facing query surfaces.
|
|
3
|
+
*
|
|
4
|
+
* Storage-facing `type`/`prefix` filtering stays in `queryHeads`; this helper owns the
|
|
5
|
+
* field-set, declared-terminal, honest-count, and limit projection used after those rows arrive.
|
|
6
|
+
*/
|
|
7
|
+
import { type KindConvention } from "./kinds.js";
|
|
8
|
+
import type { Frontmatter } from "./types.js";
|
|
9
|
+
export interface QuerySelectionParams {
|
|
10
|
+
type?: string;
|
|
11
|
+
prefix?: string;
|
|
12
|
+
field?: string;
|
|
13
|
+
open?: boolean;
|
|
14
|
+
limit?: number;
|
|
15
|
+
/** Bundle-root OKF edition, used only for declaration-driven logical field aliases. */
|
|
16
|
+
okfVersion?: string;
|
|
17
|
+
}
|
|
18
|
+
export declare function applyQuerySelectionFilters<T extends {
|
|
19
|
+
id: string;
|
|
20
|
+
frontmatter: Frontmatter;
|
|
21
|
+
}>(rows: T[], params: QuerySelectionParams, kinds?: KindConvention[]): {
|
|
22
|
+
rows: T[];
|
|
23
|
+
count: number;
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=query-selection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-selection.d.ts","sourceRoot":"","sources":["../src/query-selection.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,WAAW,oBAAoB;IACnC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uFAAuF;IACvF,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,0BAA0B,CACxC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,WAAW,CAAA;CAAE,EAElD,IAAI,EAAE,CAAC,EAAE,EACT,MAAM,EAAE,oBAAoB,EAC5B,KAAK,GAAE,cAAc,EAAO,GAC3B;IAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAqC9B"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-safe post-filtering shared by human-facing query surfaces.
|
|
3
|
+
*
|
|
4
|
+
* Storage-facing `type`/`prefix` filtering stays in `queryHeads`; this helper owns the
|
|
5
|
+
* field-set, declared-terminal, honest-count, and limit projection used after those rows arrive.
|
|
6
|
+
*/
|
|
7
|
+
import { PROGRESS_STATUS_FIELD, isTerminal, readKindField, } from "./kinds.js";
|
|
8
|
+
import { matchesFilter } from "./query-filter.js";
|
|
9
|
+
export function applyQuerySelectionFilters(rows, params, kinds = []) {
|
|
10
|
+
let out = rows;
|
|
11
|
+
const byGoverns = new Map(kinds.map((kind) => [kind.governs, kind]));
|
|
12
|
+
if (params.field) {
|
|
13
|
+
const eq = params.field.indexOf("=");
|
|
14
|
+
if (eq > 0) {
|
|
15
|
+
const key = params.field.slice(0, eq).trim();
|
|
16
|
+
const values = params.field
|
|
17
|
+
.slice(eq + 1)
|
|
18
|
+
.split(",")
|
|
19
|
+
.map((value) => value.trim())
|
|
20
|
+
.filter(Boolean);
|
|
21
|
+
out = out.filter((row) => {
|
|
22
|
+
if (key !== PROGRESS_STATUS_FIELD) {
|
|
23
|
+
return values.some((value) => matchesFilter(row, { fields: { [key]: value } }));
|
|
24
|
+
}
|
|
25
|
+
const kind = byGoverns.get(String(row.frontmatter.type ?? ""));
|
|
26
|
+
if (!kind)
|
|
27
|
+
return false;
|
|
28
|
+
const raw = readKindField(params.okfVersion, kind, row.frontmatter, key);
|
|
29
|
+
const actual = raw === undefined || raw === null
|
|
30
|
+
? []
|
|
31
|
+
: (Array.isArray(raw) ? raw : [raw]).map((value) => String(value));
|
|
32
|
+
return values.some((value) => actual.includes(value));
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (params.open) {
|
|
37
|
+
out = out.filter((row) => {
|
|
38
|
+
const kind = byGoverns.get(String(row.frontmatter.type ?? ""));
|
|
39
|
+
return !kind || !isTerminal(kind, row.frontmatter);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
const count = out.length;
|
|
43
|
+
if (typeof params.limit === "number" && params.limit > 0) {
|
|
44
|
+
out = out.slice(0, params.limit);
|
|
45
|
+
}
|
|
46
|
+
return { rows: out, count };
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=query-selection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-selection.js","sourceRoot":"","sources":["../src/query-selection.ts"],"names":[],"mappings":"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"}
|