@agentshouse/mdmodel 0.1.0-cd90851746292 → 0.1.0-cdbd463e01dc2
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/API.md +90 -81
- package/README.md +6 -4
- package/dist/definition.d.ts +1 -1
- package/dist/definition.d.ts.map +1 -1
- package/dist/definition.js +13 -9
- package/dist/event.d.ts +78 -0
- package/dist/event.d.ts.map +1 -0
- package/dist/event.js +230 -0
- package/dist/facts.d.ts +15 -0
- package/dist/facts.d.ts.map +1 -0
- package/dist/facts.js +39 -0
- package/dist/index.d.ts +17 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -3
- package/dist/kinds.d.ts +19 -0
- package/dist/kinds.d.ts.map +1 -0
- package/dist/kinds.js +161 -0
- package/dist/query/language.d.ts +223 -0
- package/dist/query/language.d.ts.map +1 -0
- package/dist/query/language.js +565 -0
- package/dist/query/match.d.ts +14 -0
- package/dist/query/match.d.ts.map +1 -0
- package/dist/query/match.js +121 -0
- package/dist/query/rows.d.ts +32 -0
- package/dist/query/rows.d.ts.map +1 -0
- package/dist/query/rows.js +161 -0
- package/dist/query/sql.d.ts +39 -0
- package/dist/query/sql.d.ts.map +1 -0
- package/dist/query/sql.js +279 -0
- package/dist/reserved.d.ts +5 -0
- package/dist/reserved.d.ts.map +1 -0
- package/dist/reserved.js +20 -0
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/validate.d.ts +4 -3
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +103 -36
- package/fixtures/README.md +17 -2
- package/fixtures/cases/link-into-a-reserved-name/context.json +1 -0
- package/fixtures/cases/link-into-a-reserved-name/expected.json +5 -0
- package/fixtures/cases/link-into-a-reserved-name/library/notes/a.md +6 -0
- package/fixtures/cases/link-into-a-reserved-name/schema.yaml +3 -0
- package/fixtures/cases/link-into-a-reserved-name-from-an-untyped-document/context.json +1 -0
- package/fixtures/cases/link-into-a-reserved-name-from-an-untyped-document/expected.json +5 -0
- package/fixtures/cases/link-into-a-reserved-name-from-an-untyped-document/library/notes/b.md +5 -0
- package/fixtures/cases/member-on-an-untyped-document/context.json +1 -0
- package/fixtures/cases/member-on-an-untyped-document/expected.json +6 -0
- package/fixtures/cases/member-on-an-untyped-document/library/note.md +4 -0
- package/fixtures/cases/member-on-another-type/context.json +1 -0
- package/fixtures/cases/member-on-another-type/expected.json +6 -0
- package/fixtures/cases/member-on-another-type/library/note.md +4 -0
- package/fixtures/cases/member-on-another-type/schema.yaml +7 -0
- package/fixtures/cases/reference-into-a-reserved-name/context.json +1 -0
- package/fixtures/cases/reference-into-a-reserved-name/expected.json +6 -0
- package/fixtures/cases/reference-into-a-reserved-name/library/notes/a.md +4 -0
- package/fixtures/cases/reference-into-a-reserved-name/library/settings/brief.md +1 -0
- package/fixtures/cases/reference-into-a-reserved-name/schema.yaml +3 -0
- package/fixtures/cases/room-md-declares-a-type/context.json +1 -0
- package/fixtures/cases/room-md-declares-a-type/expected.json +6 -0
- package/fixtures/cases/room-md-declares-a-type/library/ROOM.md +5 -0
- package/fixtures/cases/typed-path-names-another-type/context.json +11 -0
- package/fixtures/cases/typed-path-names-another-type/expected.json +6 -0
- package/fixtures/cases/typed-path-names-another-type/library/settings/prefs/one.md +3 -0
- package/fixtures/cases/typed-path-names-another-type/schema.yaml +6 -0
- package/fixtures/cases/typed-path-names-its-type/context.json +11 -0
- package/fixtures/cases/typed-path-names-its-type/expected.json +3 -0
- package/fixtures/cases/typed-path-names-its-type/library/settings/prefs/deeper/two.md +1 -0
- package/fixtures/cases/typed-path-names-its-type/library/settings/prefs/one.md +4 -0
- package/fixtures/cases/typed-path-names-its-type/schema.yaml +6 -0
- package/fixtures/cases/typed-path-names-no-type/context.json +11 -0
- package/fixtures/cases/typed-path-names-no-type/expected.json +6 -0
- package/fixtures/cases/typed-path-names-no-type/library/settings/prefs/one.md +1 -0
- package/fixtures/cases/typed-path-names-no-type/schema.yaml +6 -0
- package/fixtures/cases/unnamed-typed-path-checks-its-fields/context.json +11 -0
- package/fixtures/cases/unnamed-typed-path-checks-its-fields/expected.json +6 -0
- package/fixtures/cases/unnamed-typed-path-checks-its-fields/library/rooms/team/tasks/plan.md +4 -0
- package/fixtures/cases/unnamed-typed-path-checks-its-fields/schema.yaml +5 -0
- package/fixtures/cases/unnamed-typed-path-names-a-type/context.json +11 -0
- package/fixtures/cases/unnamed-typed-path-names-a-type/expected.json +6 -0
- package/fixtures/cases/unnamed-typed-path-names-a-type/library/rooms/team/tasks/plan.md +6 -0
- package/fixtures/cases/unnamed-typed-path-names-a-type/schema.yaml +5 -0
- package/fixtures/cases/unnamed-typed-path-reads-its-type/context.json +11 -0
- package/fixtures/cases/unnamed-typed-path-reads-its-type/expected.json +3 -0
- package/fixtures/cases/unnamed-typed-path-reads-its-type/library/rooms/team/plan.md +1 -0
- package/fixtures/cases/unnamed-typed-path-reads-its-type/library/rooms/team/tasks/plan.md +5 -0
- package/fixtures/cases/unnamed-typed-path-reads-its-type/schema.yaml +5 -0
- package/fixtures/cases/unnamed-typed-path-without-a-body/context.json +11 -0
- package/fixtures/cases/unnamed-typed-path-without-a-body/expected.json +5 -0
- package/fixtures/cases/unnamed-typed-path-without-a-body/library/rooms/team/tasks/plan.md +5 -0
- package/fixtures/cases/unnamed-typed-path-without-a-body/schema.yaml +5 -0
- package/fixtures/queries.json +913 -0
- package/package.json +1 -1
- package/dist/condition.d.ts +0 -180
- package/dist/condition.d.ts.map +0 -1
- package/dist/condition.js +0 -633
package/dist/event.js
ADDED
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { ARRAY_INDEX, escapePointer, fieldFacts, itemFacts, memberFacts, pointerFacts, pointerSegments, } from './definition.js';
|
|
2
|
+
import { dated, instant, kindOf } from './kinds.js';
|
|
3
|
+
import { roomPath, target } from './paths.js';
|
|
4
|
+
import { plain } from './yaml.js';
|
|
5
|
+
export const TEXT_FIELD = '/text';
|
|
6
|
+
export const WRITE_DOORS = ['browser', 'agent', 'client', 'function'];
|
|
7
|
+
const PROSE = { kind: 'prose' };
|
|
8
|
+
const NULL = { kind: 'null' };
|
|
9
|
+
const UNREADABLE = { kind: 'unreadable' };
|
|
10
|
+
function factKind(facts) {
|
|
11
|
+
const kind = kindOf(facts);
|
|
12
|
+
if (kind === 'integer')
|
|
13
|
+
return 'number';
|
|
14
|
+
if (kind === 'date-time')
|
|
15
|
+
return 'time';
|
|
16
|
+
if (kind === 'time')
|
|
17
|
+
return 'string';
|
|
18
|
+
return kind;
|
|
19
|
+
}
|
|
20
|
+
function scalar(value) {
|
|
21
|
+
return (typeof value === 'string' ||
|
|
22
|
+
typeof value === 'boolean' ||
|
|
23
|
+
(typeof value === 'number' && Number.isFinite(value)));
|
|
24
|
+
}
|
|
25
|
+
function fits(kind, facts, value) {
|
|
26
|
+
if (!scalar(value))
|
|
27
|
+
return false;
|
|
28
|
+
if (kind === 'enum')
|
|
29
|
+
return (facts.values ?? []).includes(value);
|
|
30
|
+
if (kind === 'number')
|
|
31
|
+
return typeof value === 'number';
|
|
32
|
+
if (kind === 'boolean')
|
|
33
|
+
return typeof value === 'boolean';
|
|
34
|
+
if (typeof value !== 'string')
|
|
35
|
+
return false;
|
|
36
|
+
if (kind === 'date')
|
|
37
|
+
return dated(value);
|
|
38
|
+
if (kind === 'time')
|
|
39
|
+
return instant(value) !== undefined;
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
function factOf(value, declared, place) {
|
|
43
|
+
if (value === null)
|
|
44
|
+
return NULL;
|
|
45
|
+
if (Array.isArray(value)) {
|
|
46
|
+
if (declared?.type !== undefined && declared.type !== 'array')
|
|
47
|
+
return UNREADABLE;
|
|
48
|
+
return {
|
|
49
|
+
kind: 'list',
|
|
50
|
+
items: value.map((item, index) => factOf(item, declared === undefined ? undefined : itemFacts(declared, index), place)),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
if (plain(value)) {
|
|
54
|
+
if (declared?.type !== undefined && declared.type !== 'object')
|
|
55
|
+
return UNREADABLE;
|
|
56
|
+
const fields = Object.create(null);
|
|
57
|
+
for (const [key, held] of Object.entries(value))
|
|
58
|
+
fields[key] = factOf(held, declared === undefined ? undefined : memberFacts(declared, key), place);
|
|
59
|
+
return { kind: 'object', fields };
|
|
60
|
+
}
|
|
61
|
+
if (declared?.type === 'array' || declared?.type === 'object')
|
|
62
|
+
return UNREADABLE;
|
|
63
|
+
const kind = declared === undefined || declared.prose ? null : factKind(declared);
|
|
64
|
+
if (kind === null)
|
|
65
|
+
return PROSE;
|
|
66
|
+
if (!fits(kind, declared, value))
|
|
67
|
+
return UNREADABLE;
|
|
68
|
+
if (kind !== 'reference')
|
|
69
|
+
return { kind, value };
|
|
70
|
+
const reached = target(place.path, value) ?? roomPath(value);
|
|
71
|
+
const resolved = reached === null ? undefined : place.resolve(reached);
|
|
72
|
+
if (resolved === undefined)
|
|
73
|
+
return UNREADABLE;
|
|
74
|
+
return resolved.member === undefined
|
|
75
|
+
? { kind, value: resolved.id }
|
|
76
|
+
: { kind, value: resolved.id, member: resolved.member };
|
|
77
|
+
}
|
|
78
|
+
export function facts(document, at, model, resolve) {
|
|
79
|
+
const type = document.type ?? null;
|
|
80
|
+
const definition = type !== null && Object.hasOwn(model.types, type) ? model.types[type] : null;
|
|
81
|
+
const fields = Object.create(null);
|
|
82
|
+
const place = { path: at.path, resolve };
|
|
83
|
+
for (const [name, value] of Object.entries(document.fields)) {
|
|
84
|
+
const declared = definition === null ? undefined : fieldFacts(definition, name);
|
|
85
|
+
if (declared !== undefined)
|
|
86
|
+
fields[name] = factOf(value, declared, place);
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
id: at.id,
|
|
90
|
+
path: `/${at.path}`,
|
|
91
|
+
type,
|
|
92
|
+
fields,
|
|
93
|
+
sections: Object.keys(document.sections).sort(),
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
function rootOf(facts, prefix) {
|
|
97
|
+
return { pointer: prefix, fact: { kind: 'object', fields: facts.fields } };
|
|
98
|
+
}
|
|
99
|
+
export function prosePaths(facts) {
|
|
100
|
+
const paths = facts.sections.map((heading) => `/sections/${heading}`);
|
|
101
|
+
const visit = ({ pointer, fact }) => {
|
|
102
|
+
if (fact.kind === 'prose')
|
|
103
|
+
paths.push(pointer);
|
|
104
|
+
if (fact.kind === 'list')
|
|
105
|
+
fact.items.forEach((item, index) => visit({ pointer: `${pointer}/${index}`, fact: item }));
|
|
106
|
+
if (fact.kind === 'object')
|
|
107
|
+
for (const [key, held] of Object.entries(fact.fields))
|
|
108
|
+
visit({ pointer: `${pointer}/${escapePointer(key)}`, fact: held });
|
|
109
|
+
};
|
|
110
|
+
visit(rootOf(facts, '/fields'));
|
|
111
|
+
return paths.sort();
|
|
112
|
+
}
|
|
113
|
+
function walked(start, pointer) {
|
|
114
|
+
let reached = [start];
|
|
115
|
+
for (const token of pointerSegments(pointer)) {
|
|
116
|
+
const step = ({ pointer: at, fact }) => {
|
|
117
|
+
if (fact.kind === 'object')
|
|
118
|
+
return Object.hasOwn(fact.fields, token)
|
|
119
|
+
? [{ pointer: `${at}/${escapePointer(token)}`, fact: fact.fields[token] }]
|
|
120
|
+
: [];
|
|
121
|
+
if (fact.kind !== 'list')
|
|
122
|
+
return [];
|
|
123
|
+
if (ARRAY_INDEX.test(token)) {
|
|
124
|
+
const item = fact.items[Number(token)];
|
|
125
|
+
return item === undefined ? [] : [{ pointer: `${at}/${token}`, fact: item }];
|
|
126
|
+
}
|
|
127
|
+
return fact.items
|
|
128
|
+
.map((item, index) => ({ pointer: `${at}/${index}`, fact: item }))
|
|
129
|
+
.flatMap(step);
|
|
130
|
+
};
|
|
131
|
+
reached = reached.flatMap(step);
|
|
132
|
+
}
|
|
133
|
+
return reached;
|
|
134
|
+
}
|
|
135
|
+
function expand(fact) {
|
|
136
|
+
return fact.kind === 'list' ? fact.items.flatMap(expand) : [fact];
|
|
137
|
+
}
|
|
138
|
+
export function members(document, path) {
|
|
139
|
+
if (!path.startsWith('/members/'))
|
|
140
|
+
return [];
|
|
141
|
+
return [
|
|
142
|
+
...new Set(walked(rootOf(document, '/members'), path.slice('/members'.length))
|
|
143
|
+
.flatMap(({ fact }) => expand(fact))
|
|
144
|
+
.flatMap((fact) => fact.kind === 'reference' && fact.member !== undefined ? [fact.member] : [])),
|
|
145
|
+
].sort();
|
|
146
|
+
}
|
|
147
|
+
export function pointed(value, pointer) {
|
|
148
|
+
let reached = value;
|
|
149
|
+
for (const token of pointerSegments(pointer)) {
|
|
150
|
+
if (Array.isArray(reached)) {
|
|
151
|
+
if (!ARRAY_INDEX.test(token))
|
|
152
|
+
return undefined;
|
|
153
|
+
reached = reached[Number(token)];
|
|
154
|
+
}
|
|
155
|
+
else if (plain(reached) && Object.hasOwn(reached, token)) {
|
|
156
|
+
reached = reached[token];
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
return undefined;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return reached;
|
|
163
|
+
}
|
|
164
|
+
export function valuedChange(definition, pointer) {
|
|
165
|
+
const reached = pointerFacts(definition, pointer);
|
|
166
|
+
return (reached !== undefined &&
|
|
167
|
+
!reached.through &&
|
|
168
|
+
reached.facts.type !== 'array' &&
|
|
169
|
+
!reached.facts.prose &&
|
|
170
|
+
kindOf(reached.facts) !== null);
|
|
171
|
+
}
|
|
172
|
+
export function datePointers(definition) {
|
|
173
|
+
return Object.entries(definition.fields)
|
|
174
|
+
.filter(([, held]) => kindOf(held) === 'date')
|
|
175
|
+
.map(([name]) => `/${escapePointer(name)}`)
|
|
176
|
+
.sort();
|
|
177
|
+
}
|
|
178
|
+
export function memberPointers(definition, memberType) {
|
|
179
|
+
return Object.entries(definition.fields)
|
|
180
|
+
.filter(([, held]) => (held.type === 'array' ? held.items : held)?.reference?.includes(memberType) === true)
|
|
181
|
+
.map(([name]) => `/members/${escapePointer(name)}`);
|
|
182
|
+
}
|
|
183
|
+
function plainOf(fact) {
|
|
184
|
+
if (fact.kind === 'list')
|
|
185
|
+
return fact.items.map(plainOf);
|
|
186
|
+
if (fact.kind === 'object')
|
|
187
|
+
return Object.fromEntries(Object.entries(fact.fields).flatMap(([key, held]) => {
|
|
188
|
+
const value = plainOf(held);
|
|
189
|
+
return value === undefined ? [] : [[key, value]];
|
|
190
|
+
}));
|
|
191
|
+
if (fact.kind === 'prose')
|
|
192
|
+
return true;
|
|
193
|
+
if (fact.kind === 'null')
|
|
194
|
+
return null;
|
|
195
|
+
if (fact.kind === 'unreadable')
|
|
196
|
+
return undefined;
|
|
197
|
+
return fact.value;
|
|
198
|
+
}
|
|
199
|
+
function shapeOf(fact) {
|
|
200
|
+
if (fact.kind === 'list')
|
|
201
|
+
return { type: 'array', prose: false, prefix: fact.items.map(shapeOf) };
|
|
202
|
+
if (fact.kind === 'object')
|
|
203
|
+
return {
|
|
204
|
+
type: 'object',
|
|
205
|
+
prose: false,
|
|
206
|
+
properties: Object.fromEntries(Object.entries(fact.fields).map(([key, held]) => [key, shapeOf(held)])),
|
|
207
|
+
};
|
|
208
|
+
if (fact.kind === 'time')
|
|
209
|
+
return { type: 'string', format: 'date-time', prose: false };
|
|
210
|
+
return { prose: false };
|
|
211
|
+
}
|
|
212
|
+
export function candidateOf(document) {
|
|
213
|
+
const fields = {};
|
|
214
|
+
const properties = {};
|
|
215
|
+
for (const [name, fact] of Object.entries(document.fields)) {
|
|
216
|
+
const value = plainOf(fact);
|
|
217
|
+
if (value === undefined)
|
|
218
|
+
continue;
|
|
219
|
+
fields[name] = value;
|
|
220
|
+
properties[name] = shapeOf(fact);
|
|
221
|
+
}
|
|
222
|
+
return {
|
|
223
|
+
path: document.path.slice(1),
|
|
224
|
+
type: document.type,
|
|
225
|
+
fileId: document.id,
|
|
226
|
+
fields,
|
|
227
|
+
definition: { frontmatter: { type: 'object', prose: false, properties } },
|
|
228
|
+
text: null,
|
|
229
|
+
};
|
|
230
|
+
}
|
package/dist/facts.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Document, VerifiedModel } from './types.js';
|
|
2
|
+
export type SavedFacts = {
|
|
3
|
+
readonly type: string;
|
|
4
|
+
readonly fields: Readonly<Record<string, unknown>>;
|
|
5
|
+
readonly links: readonly string[];
|
|
6
|
+
};
|
|
7
|
+
export type ReferenceTarget = {
|
|
8
|
+
readonly location: string;
|
|
9
|
+
readonly to: readonly string[];
|
|
10
|
+
readonly target: string;
|
|
11
|
+
};
|
|
12
|
+
export declare function referenceTarget(file: string, value: string): string | null;
|
|
13
|
+
export declare function referenceTargets(document: Document, file: string, model: VerifiedModel): readonly ReferenceTarget[];
|
|
14
|
+
export declare function documentFacts(file: string, content: string, model: VerifiedModel): SavedFacts | null;
|
|
15
|
+
//# sourceMappingURL=facts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"facts.d.ts","sourceRoot":"","sources":["../src/facts.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE1D,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACnD,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB,CAAC;AAIF,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAK1E;AAED,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,aAAa,GACnB,SAAS,eAAe,EAAE,CAO5B;AAED,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,aAAa,GACnB,UAAU,GAAG,IAAI,CAgBnB"}
|
package/dist/facts.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { BUILT_IN_TYPE } from './definition.js';
|
|
2
|
+
import { links, parse } from './document.js';
|
|
3
|
+
import { references } from './references.js';
|
|
4
|
+
const SETTINGS_AREA = 'settings/';
|
|
5
|
+
export function referenceTarget(file, value) {
|
|
6
|
+
if (value.trim() === '' || /[<>\n\r]/.test(value))
|
|
7
|
+
return null;
|
|
8
|
+
const parsed = parse(`[](<${value}>)\n`, file);
|
|
9
|
+
if (!parsed.ok)
|
|
10
|
+
return null;
|
|
11
|
+
return links(parsed.document, file)[0]?.target ?? null;
|
|
12
|
+
}
|
|
13
|
+
export function referenceTargets(document, file, model) {
|
|
14
|
+
const type = document.type;
|
|
15
|
+
if (type === undefined || !Object.hasOwn(model.types, type))
|
|
16
|
+
return [];
|
|
17
|
+
return references(document, model.types[type]).flatMap(({ pointer, value, to }) => {
|
|
18
|
+
const target = referenceTarget(file, value);
|
|
19
|
+
return target === null ? [] : [{ location: pointer, to, target }];
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
export function documentFacts(file, content, model) {
|
|
23
|
+
const parsed = parse(content, file);
|
|
24
|
+
if (!parsed.ok)
|
|
25
|
+
return null;
|
|
26
|
+
const { document } = parsed;
|
|
27
|
+
return {
|
|
28
|
+
type: document.type ?? BUILT_IN_TYPE,
|
|
29
|
+
fields: document.fields,
|
|
30
|
+
links: file.startsWith(SETTINGS_AREA)
|
|
31
|
+
? []
|
|
32
|
+
: [
|
|
33
|
+
...new Set([
|
|
34
|
+
...links(document, file).map((link) => link.target),
|
|
35
|
+
...referenceTargets(document, file, model).map(({ target }) => target),
|
|
36
|
+
]),
|
|
37
|
+
].sort(),
|
|
38
|
+
};
|
|
39
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,21 +1,33 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export type { Actor,
|
|
1
|
+
export { candidateOf, datePointers, facts, memberPointers, members, pointed, prosePaths, TEXT_FIELD, valuedChange, WRITE_DOORS, } from './event.js';
|
|
2
|
+
export type { Actor, DocumentEvent, DocumentFacts, Fact, FactKind, ItemFacts, MessageFacts, Resolved, WriteDoor, } from './event.js';
|
|
3
|
+
export { byCodePoint, compared, dated, fitsKind, instant, instantKey, KINDS, kindOf, kindWords, } from './kinds.js';
|
|
4
|
+
export type { Kind, Ordering } from './kinds.js';
|
|
5
|
+
export { bodied, cursorOf, decodedCursor, identityOf, invalid, known, placeText, planOf, QueryError, queryKey, } from './query/language.js';
|
|
6
|
+
export type { Clause, Continuation, Direction, DocumentQuery, DocumentShape, Filter, GroupQuery, GroupShape, HeldRooms, Key, KeyPlan, LocalQuery, OrderOptions, Place, Predicate, QueryErrorCode, QueryPlan, Related, RoomFacts, Scope, Select, Test, Value, Where, } from './query/language.js';
|
|
7
|
+
export { heldAt, matches } from './query/match.js';
|
|
8
|
+
export type { Candidate } from './query/match.js';
|
|
9
|
+
export { heldKind, indexed } from './query/rows.js';
|
|
10
|
+
export type { HeldKind, HeldLink, HeldValue, Indexed, Reach } from './query/rows.js';
|
|
11
|
+
export * as sql from './query/sql.js';
|
|
3
12
|
export { headingLines } from './blocks.js';
|
|
4
13
|
export type { HeadingLine } from './blocks.js';
|
|
5
14
|
export { divide } from './divide.js';
|
|
6
15
|
export { apply, bodyLinks, links, parse, parseFrontmatter, relativize, relativizeBody, relinkBody, serialize, } from './document.js';
|
|
16
|
+
export { documentFacts, referenceTarget, referenceTargets } from './facts.js';
|
|
17
|
+
export type { ReferenceTarget, SavedFacts } from './facts.js';
|
|
7
18
|
export { HOUSE_FIELDS, MEMBER_FIELD, RECEIVED_FIELD, SITE_FIELD, TYPE_FIELD } from './fields.js';
|
|
8
19
|
export { relative, retarget, roomPath, roomTarget, target } from './paths.js';
|
|
9
20
|
export type { RoomTarget } from './paths.js';
|
|
10
21
|
export { MARKDOWN_SYNTAX_PROFILE } from './profile.js';
|
|
11
22
|
export { project } from './project.js';
|
|
12
23
|
export { references } from './references.js';
|
|
24
|
+
export { isDocumentPath, isReservedName, RESERVED_NAMES, ROOM_DESCRIPTION } from './reserved.js';
|
|
13
25
|
export { ARRAY_INDEX, ATTACHMENT, crossedFacts, escapePointer, itemFacts, JSON_POINTER, memberFacts, pointerFacts, pointerSegments, } from './definition.js';
|
|
14
26
|
export type { Definition, FieldRules, JsonType, PatternFacts, PointerFacts, RuleValue, SectionSpec, Shape, Transition, ValueFacts, } from './definition.js';
|
|
15
|
-
export type { ApplyResult, BodyResult, Change, Division, DivisionContext, Document, DocumentCheck, Frontmatter, FrontmatterResult, Library, ModelVerification, Link, ParseResult, Projection, ProjectionContext, Reached, Reference, Refusal, RoomReference, Span, Validation, ValidationContext, ValidationStep, VerifiedModel, } from './types.js';
|
|
16
|
-
export { assess, bodyRoomLinks, checkDocument, resolves, roomReferences,
|
|
27
|
+
export type { ApplyResult, BodyResult, Change, Division, DivisionContext, Document, DocumentCheck, Frontmatter, FrontmatterResult, Library, ModelVerification, Link, ParseResult, Projection, ProjectionContext, Reached, Reference, Refusal, RoomReference, Span, TypedPath, Validation, ValidationContext, ValidationStep, VerifiedModel, } from './types.js';
|
|
28
|
+
export { assess, bodyRoomLinks, checkDocument, readTypes, resolves, roomReferences, validate, validating, verdicts, verify, } from './validate.js';
|
|
17
29
|
export type { Assessment, Verdicts } from './validate.js';
|
|
18
30
|
export { VERSION } from './version.js';
|
|
19
|
-
export { bodyAfterFrontmatter, equalValue, frontmatterValue } from './yaml.js';
|
|
31
|
+
export { bodyAfterFrontmatter, equalValue, frontmatterValue, plain } from './yaml.js';
|
|
20
32
|
export type { FrontmatterValue } from './yaml.js';
|
|
21
33
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,cAAc,EACd,YAAY,EACZ,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { candidateOf, datePointers, facts, memberPointers, members, pointed, prosePaths, TEXT_FIELD, valuedChange, WRITE_DOORS, } from './event.js';
|
|
2
|
+
export { byCodePoint, compared, dated, fitsKind, instant, instantKey, KINDS, kindOf, kindWords, } from './kinds.js';
|
|
3
|
+
export { bodied, cursorOf, decodedCursor, identityOf, invalid, known, placeText, planOf, QueryError, queryKey, } from './query/language.js';
|
|
4
|
+
export { heldAt, matches } from './query/match.js';
|
|
5
|
+
export { heldKind, indexed } from './query/rows.js';
|
|
6
|
+
export * as sql from './query/sql.js';
|
|
2
7
|
export { headingLines } from './blocks.js';
|
|
3
8
|
export { divide } from './divide.js';
|
|
4
9
|
export { apply, bodyLinks, links, parse, parseFrontmatter, relativize, relativizeBody, relinkBody, serialize, } from './document.js';
|
|
10
|
+
export { documentFacts, referenceTarget, referenceTargets } from './facts.js';
|
|
5
11
|
export { HOUSE_FIELDS, MEMBER_FIELD, RECEIVED_FIELD, SITE_FIELD, TYPE_FIELD } from './fields.js';
|
|
6
12
|
export { relative, retarget, roomPath, roomTarget, target } from './paths.js';
|
|
7
13
|
export { MARKDOWN_SYNTAX_PROFILE } from './profile.js';
|
|
8
14
|
export { project } from './project.js';
|
|
9
15
|
export { references } from './references.js';
|
|
16
|
+
export { isDocumentPath, isReservedName, RESERVED_NAMES, ROOM_DESCRIPTION } from './reserved.js';
|
|
10
17
|
export { ARRAY_INDEX, ATTACHMENT, crossedFacts, escapePointer, itemFacts, JSON_POINTER, memberFacts, pointerFacts, pointerSegments, } from './definition.js';
|
|
11
|
-
export { assess, bodyRoomLinks, checkDocument, resolves, roomReferences,
|
|
18
|
+
export { assess, bodyRoomLinks, checkDocument, readTypes, resolves, roomReferences, validate, validating, verdicts, verify, } from './validate.js';
|
|
12
19
|
export { VERSION } from './version.js';
|
|
13
|
-
export { bodyAfterFrontmatter, equalValue, frontmatterValue } from './yaml.js';
|
|
20
|
+
export { bodyAfterFrontmatter, equalValue, frontmatterValue, plain } from './yaml.js';
|
package/dist/kinds.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ValueFacts } from './definition.js';
|
|
2
|
+
export declare const KINDS: readonly ['string', 'number', 'integer', 'boolean', 'date', 'date-time', 'time', 'enum', 'reference'];
|
|
3
|
+
export type Kind = (typeof KINDS)[number];
|
|
4
|
+
export type Ordering = {
|
|
5
|
+
readonly direction: 'asc' | 'desc';
|
|
6
|
+
readonly nulls: 'first' | 'last';
|
|
7
|
+
readonly stringSort: 'lexical' | 'locale';
|
|
8
|
+
readonly locale: string | undefined;
|
|
9
|
+
readonly localeOptions: Intl.CollatorOptions | undefined;
|
|
10
|
+
};
|
|
11
|
+
export declare function kindOf(facts: ValueFacts): Kind | null;
|
|
12
|
+
export declare function fitsKind(kind: Kind, facts: ValueFacts, value: unknown): boolean;
|
|
13
|
+
export declare function kindWords(facts: ValueFacts | undefined): readonly string[];
|
|
14
|
+
export declare function dated(value: unknown): value is string;
|
|
15
|
+
export declare function instant(value: unknown): bigint | undefined;
|
|
16
|
+
export declare function instantKey(value: unknown): string | null;
|
|
17
|
+
export declare function byCodePoint(left: string, right: string): number;
|
|
18
|
+
export declare function compared(left: unknown, right: unknown, ordering: Ordering): number;
|
|
19
|
+
//# sourceMappingURL=kinds.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kinds.d.ts","sourceRoot":"","sources":["../src/kinds.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAGlD,eAAO,MAAM,KAAK,YAChB,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,SAAS,EACT,MAAM,EACN,WAAW,EACX,MAAM,EACN,MAAM,EACN,WAAW,CACH,CAAC;AAEX,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1C,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,CAAC,SAAS,EAAE,KAAK,GAAG,MAAM,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC1C,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,aAAa,EAAE,IAAI,CAAC,eAAe,GAAG,SAAS,CAAC;CAC1D,CAAC;AASF,wBAAgB,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI,CAWrD;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAW/E;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,SAAS,GAAG,SAAS,MAAM,EAAE,CAe1E;AAED,wBAAgB,KAAK,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAErD;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAqB1D;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAGxD;AAaD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAO/D;AA4BD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAMlF"}
|
package/dist/kinds.js
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { format } from '@cfworker/json-schema';
|
|
2
|
+
import { normalize } from './paths.js';
|
|
3
|
+
export const KINDS = [
|
|
4
|
+
'string',
|
|
5
|
+
'number',
|
|
6
|
+
'integer',
|
|
7
|
+
'boolean',
|
|
8
|
+
'date',
|
|
9
|
+
'date-time',
|
|
10
|
+
'time',
|
|
11
|
+
'enum',
|
|
12
|
+
'reference',
|
|
13
|
+
];
|
|
14
|
+
const DATE_TIME = /^(\d{4})-(\d{2})-(\d{2})[Tt\s](\d{2}):(\d{2}):(\d{2})(?:\.(\d+))?(?:[Zz]|([+-])(\d{2})(?::?(\d{2}))?)$/u;
|
|
15
|
+
const BEFORE_YEAR_ZERO = 62200000000000000000n;
|
|
16
|
+
const INSTANT_DIGITS = 21;
|
|
17
|
+
export function kindOf(facts) {
|
|
18
|
+
if (facts.reference !== undefined)
|
|
19
|
+
return 'reference';
|
|
20
|
+
if (facts.values !== undefined)
|
|
21
|
+
return 'enum';
|
|
22
|
+
if (facts.type === 'number')
|
|
23
|
+
return 'number';
|
|
24
|
+
if (facts.type === 'integer')
|
|
25
|
+
return 'integer';
|
|
26
|
+
if (facts.type === 'boolean')
|
|
27
|
+
return 'boolean';
|
|
28
|
+
if (facts.type !== 'string')
|
|
29
|
+
return null;
|
|
30
|
+
if (facts.format === 'date')
|
|
31
|
+
return 'date';
|
|
32
|
+
if (facts.format === 'date-time')
|
|
33
|
+
return 'date-time';
|
|
34
|
+
if (facts.format === 'time')
|
|
35
|
+
return 'time';
|
|
36
|
+
return 'string';
|
|
37
|
+
}
|
|
38
|
+
export function fitsKind(kind, facts, value) {
|
|
39
|
+
if (kind === 'enum')
|
|
40
|
+
return (facts.values ?? []).includes(value);
|
|
41
|
+
if (kind === 'number')
|
|
42
|
+
return typeof value === 'number' && Number.isFinite(value);
|
|
43
|
+
if (kind === 'integer')
|
|
44
|
+
return Number.isSafeInteger(value);
|
|
45
|
+
if (kind === 'boolean')
|
|
46
|
+
return typeof value === 'boolean';
|
|
47
|
+
if (typeof value !== 'string')
|
|
48
|
+
return false;
|
|
49
|
+
if (kind === 'reference')
|
|
50
|
+
return value !== '' && normalize(value) === value;
|
|
51
|
+
if (kind === 'date')
|
|
52
|
+
return dated(value);
|
|
53
|
+
if (kind === 'date-time')
|
|
54
|
+
return instant(value) !== undefined;
|
|
55
|
+
if (kind === 'time')
|
|
56
|
+
return format.time(value);
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
export function kindWords(facts) {
|
|
60
|
+
const kind = facts === undefined ? null : kindOf(facts);
|
|
61
|
+
if (kind === 'enum')
|
|
62
|
+
return (facts.values ?? []).map((value) => typeof value === 'string' ? value : JSON.stringify(value));
|
|
63
|
+
if (kind === 'number')
|
|
64
|
+
return ['a number'];
|
|
65
|
+
if (kind === 'integer')
|
|
66
|
+
return ['an integer'];
|
|
67
|
+
if (kind === 'boolean')
|
|
68
|
+
return ['true', 'false'];
|
|
69
|
+
if (kind === 'date')
|
|
70
|
+
return ['a date as YYYY-MM-DD'];
|
|
71
|
+
if (kind === 'date-time')
|
|
72
|
+
return ['a date-time with its offset, such as 2026-10-10T09:30:00Z'];
|
|
73
|
+
if (kind === 'time')
|
|
74
|
+
return ['a time as HH:MM:SS'];
|
|
75
|
+
if (kind === 'reference')
|
|
76
|
+
return [`the Room Path of a ${facts.reference.join(' or ')} document, such as notes/a.md`];
|
|
77
|
+
return kind === 'string' ? ['a string'] : [];
|
|
78
|
+
}
|
|
79
|
+
export function dated(value) {
|
|
80
|
+
return typeof value === 'string' && format.date(value);
|
|
81
|
+
}
|
|
82
|
+
export function instant(value) {
|
|
83
|
+
if (typeof value !== 'string' || !format['date-time'](value))
|
|
84
|
+
return undefined;
|
|
85
|
+
const parts = DATE_TIME.exec(value);
|
|
86
|
+
const [year, month, day, hour, minute, second, offsetHours, offsetMinutes] = [
|
|
87
|
+
1, 2, 3, 4, 5, 6, 9, 10,
|
|
88
|
+
].map((at) => Number(parts[at] ?? 0));
|
|
89
|
+
const at = new Date(0);
|
|
90
|
+
at.setUTCFullYear(year, month - 1, day);
|
|
91
|
+
at.setUTCHours(hour, minute, second);
|
|
92
|
+
const offset = (parts[8] === '-' ? -1 : 1) * (offsetHours * 60 + offsetMinutes);
|
|
93
|
+
const fraction = (parts[7] ?? '').padEnd(9, '0').slice(0, 9);
|
|
94
|
+
return (BigInt(at.getTime()) - BigInt(offset) * 60000n) * 1000000n + BigInt(fraction);
|
|
95
|
+
}
|
|
96
|
+
export function instantKey(value) {
|
|
97
|
+
const at = instant(value);
|
|
98
|
+
return at === undefined ? null : (at + BEFORE_YEAR_ZERO).toString().padStart(INSTANT_DIGITS, '0');
|
|
99
|
+
}
|
|
100
|
+
function rank(value) {
|
|
101
|
+
if (typeof value === 'boolean' || typeof value === 'number')
|
|
102
|
+
return 1;
|
|
103
|
+
if (typeof value === 'string')
|
|
104
|
+
return 2;
|
|
105
|
+
return Array.isArray(value) ? 3 : 4;
|
|
106
|
+
}
|
|
107
|
+
function unit(code) {
|
|
108
|
+
if (code >= 0xd800 && code < 0xe000)
|
|
109
|
+
return code + 0x2000;
|
|
110
|
+
return code >= 0xe000 ? code - 0x800 : code;
|
|
111
|
+
}
|
|
112
|
+
export function byCodePoint(left, right) {
|
|
113
|
+
for (let at = 0; at < Math.min(left.length, right.length); at += 1) {
|
|
114
|
+
const ours = left.charCodeAt(at);
|
|
115
|
+
const theirs = right.charCodeAt(at);
|
|
116
|
+
if (ours !== theirs)
|
|
117
|
+
return unit(ours) - unit(theirs);
|
|
118
|
+
}
|
|
119
|
+
return left.length - right.length;
|
|
120
|
+
}
|
|
121
|
+
function ascending(left, right, ordering) {
|
|
122
|
+
if (left == null && right == null)
|
|
123
|
+
return 0;
|
|
124
|
+
if (left == null)
|
|
125
|
+
return ordering.nulls === 'first' ? -1 : 1;
|
|
126
|
+
if (right == null)
|
|
127
|
+
return ordering.nulls === 'first' ? 1 : -1;
|
|
128
|
+
const ranked = rank(left) - rank(right);
|
|
129
|
+
if (ranked !== 0)
|
|
130
|
+
return ranked;
|
|
131
|
+
if (typeof left === 'string' && typeof right === 'string') {
|
|
132
|
+
return ordering.stringSort === 'locale'
|
|
133
|
+
? left.localeCompare(right, ordering.locale, ordering.localeOptions)
|
|
134
|
+
: byCodePoint(left, right);
|
|
135
|
+
}
|
|
136
|
+
if (Array.isArray(left) && Array.isArray(right)) {
|
|
137
|
+
for (let at = 0; at < Math.min(left.length, right.length); at += 1) {
|
|
138
|
+
const result = ascending(left[at], right[at], ordering);
|
|
139
|
+
if (result !== 0)
|
|
140
|
+
return result;
|
|
141
|
+
}
|
|
142
|
+
return left.length - right.length;
|
|
143
|
+
}
|
|
144
|
+
if (typeof left === 'object')
|
|
145
|
+
return 0;
|
|
146
|
+
const held = left;
|
|
147
|
+
const other = right;
|
|
148
|
+
if (held < other)
|
|
149
|
+
return -1;
|
|
150
|
+
if (held > other)
|
|
151
|
+
return 1;
|
|
152
|
+
return 0;
|
|
153
|
+
}
|
|
154
|
+
export function compared(left, right, ordering) {
|
|
155
|
+
if (ordering.direction === 'asc')
|
|
156
|
+
return ascending(left, right, ordering);
|
|
157
|
+
return ascending(right, left, {
|
|
158
|
+
...ordering,
|
|
159
|
+
nulls: ordering.nulls === 'first' ? 'last' : 'first',
|
|
160
|
+
});
|
|
161
|
+
}
|