@dotit/core 1.0.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/LICENSE +21 -0
- package/README.md +229 -0
- package/dist/aliases.d.ts +1 -0
- package/dist/aliases.js +8 -0
- package/dist/ask.d.ts +7 -0
- package/dist/ask.js +55 -0
- package/dist/browser.d.ts +12 -0
- package/dist/browser.js +32 -0
- package/dist/diff.d.ts +17 -0
- package/dist/diff.js +179 -0
- package/dist/document-css.d.ts +1 -0
- package/dist/document-css.js +290 -0
- package/dist/executor.d.ts +40 -0
- package/dist/executor.js +501 -0
- package/dist/history.d.ts +10 -0
- package/dist/history.js +297 -0
- package/dist/html-to-it.d.ts +1 -0
- package/dist/html-to-it.js +288 -0
- package/dist/index-builder.d.ts +62 -0
- package/dist/index-builder.js +228 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.js +94 -0
- package/dist/language-registry.d.ts +39 -0
- package/dist/language-registry.js +530 -0
- package/dist/markdown.d.ts +1 -0
- package/dist/markdown.js +123 -0
- package/dist/merge.d.ts +6 -0
- package/dist/merge.js +255 -0
- package/dist/parser.d.ts +29 -0
- package/dist/parser.js +1562 -0
- package/dist/query.d.ts +32 -0
- package/dist/query.js +293 -0
- package/dist/renderer.d.ts +16 -0
- package/dist/renderer.js +1286 -0
- package/dist/schema.d.ts +47 -0
- package/dist/schema.js +574 -0
- package/dist/source.d.ts +3 -0
- package/dist/source.js +223 -0
- package/dist/theme.d.ts +49 -0
- package/dist/theme.js +113 -0
- package/dist/themes/corporate.json +86 -0
- package/dist/themes/dark.json +64 -0
- package/dist/themes/editorial.json +54 -0
- package/dist/themes/legal.json +57 -0
- package/dist/themes/minimal.json +50 -0
- package/dist/themes/print.json +54 -0
- package/dist/themes/technical.json +59 -0
- package/dist/themes/warm.json +53 -0
- package/dist/trust.d.ts +66 -0
- package/dist/trust.js +200 -0
- package/dist/types.d.ts +234 -0
- package/dist/types.js +19 -0
- package/dist/utils.d.ts +2 -0
- package/dist/utils.js +13 -0
- package/dist/validate.d.ts +13 -0
- package/dist/validate.js +711 -0
- package/dist/workflow.d.ts +18 -0
- package/dist/workflow.js +160 -0
- package/package.json +51 -0
package/dist/query.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { IntentDocument, IntentBlock } from "./types";
|
|
2
|
+
export interface QueryClause {
|
|
3
|
+
field: string;
|
|
4
|
+
operator: "=" | "!=" | "<" | ">" | "<=" | ">=" | "contains" | "startsWith" | "exists";
|
|
5
|
+
value?: string | number | boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface QuerySort {
|
|
8
|
+
field: string;
|
|
9
|
+
direction: "asc" | "desc";
|
|
10
|
+
}
|
|
11
|
+
export interface QueryOptions {
|
|
12
|
+
where?: QueryClause[];
|
|
13
|
+
sort?: QuerySort[];
|
|
14
|
+
limit?: number;
|
|
15
|
+
offset?: number;
|
|
16
|
+
}
|
|
17
|
+
export interface QueryResult {
|
|
18
|
+
blocks: IntentBlock[];
|
|
19
|
+
total: number;
|
|
20
|
+
matched: number;
|
|
21
|
+
}
|
|
22
|
+
export declare function parseQuery(queryString: string): QueryOptions;
|
|
23
|
+
export declare function queryBlocks(document: IntentDocument, options: QueryOptions | string): QueryResult;
|
|
24
|
+
export declare function formatQueryResult(result: QueryResult, format?: "json" | "table" | "simple"): string;
|
|
25
|
+
export interface SimpleQueryOptions {
|
|
26
|
+
type?: string | string[];
|
|
27
|
+
content?: string | RegExp;
|
|
28
|
+
properties?: Record<string, string | RegExp>;
|
|
29
|
+
section?: string | RegExp;
|
|
30
|
+
limit?: number;
|
|
31
|
+
}
|
|
32
|
+
export declare function queryDocument(doc: IntentDocument, query?: SimpleQueryOptions): IntentBlock[];
|
package/dist/query.js
ADDED
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseQuery = parseQuery;
|
|
4
|
+
exports.queryBlocks = queryBlocks;
|
|
5
|
+
exports.formatQueryResult = formatQueryResult;
|
|
6
|
+
exports.queryDocument = queryDocument;
|
|
7
|
+
const utils_1 = require("./utils");
|
|
8
|
+
function parseQuery(queryString) {
|
|
9
|
+
const options = { where: [], sort: [] };
|
|
10
|
+
if (typeof queryString !== "string" || queryString.length === 0)
|
|
11
|
+
return options;
|
|
12
|
+
const capped = queryString.length > 10000 ? queryString.slice(0, 10000) : queryString;
|
|
13
|
+
const parts = capped.trim().split(/\s+/);
|
|
14
|
+
for (const part of parts) {
|
|
15
|
+
if (part.startsWith("sort:")) {
|
|
16
|
+
const sortMatch = part.match(/^sort:([^:]+)(?::(asc|desc))?$/i);
|
|
17
|
+
if (sortMatch) {
|
|
18
|
+
options.sort.push({
|
|
19
|
+
field: sortMatch[1],
|
|
20
|
+
direction: sortMatch[2] || "asc",
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
if (part.startsWith("limit:")) {
|
|
26
|
+
const limitMatch = part.match(/^limit:(\d+)$/i);
|
|
27
|
+
if (limitMatch) {
|
|
28
|
+
options.limit = parseInt(limitMatch[1], 10);
|
|
29
|
+
}
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
if (part.startsWith("offset:")) {
|
|
33
|
+
const offsetMatch = part.match(/^offset:(\d+)$/i);
|
|
34
|
+
if (offsetMatch) {
|
|
35
|
+
options.offset = parseInt(offsetMatch[1], 10);
|
|
36
|
+
}
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
const clauseMatch = part.match(/^([^:=<>!?]+)(=|!=|<=|>=|<|>|:contains|:startsWith|\?)(.*)$/);
|
|
40
|
+
if (clauseMatch) {
|
|
41
|
+
const field = clauseMatch[1];
|
|
42
|
+
const op = clauseMatch[2];
|
|
43
|
+
const val = clauseMatch[3];
|
|
44
|
+
let operator;
|
|
45
|
+
switch (op) {
|
|
46
|
+
case "=":
|
|
47
|
+
operator = "=";
|
|
48
|
+
break;
|
|
49
|
+
case "!=":
|
|
50
|
+
operator = "!=";
|
|
51
|
+
break;
|
|
52
|
+
case "<":
|
|
53
|
+
operator = "<";
|
|
54
|
+
break;
|
|
55
|
+
case ">":
|
|
56
|
+
operator = ">";
|
|
57
|
+
break;
|
|
58
|
+
case "<=":
|
|
59
|
+
operator = "<=";
|
|
60
|
+
break;
|
|
61
|
+
case ">=":
|
|
62
|
+
operator = ">=";
|
|
63
|
+
break;
|
|
64
|
+
case ":contains":
|
|
65
|
+
operator = "contains";
|
|
66
|
+
break;
|
|
67
|
+
case ":startsWith":
|
|
68
|
+
operator = "startsWith";
|
|
69
|
+
break;
|
|
70
|
+
case "?":
|
|
71
|
+
operator = "exists";
|
|
72
|
+
break;
|
|
73
|
+
default:
|
|
74
|
+
operator = "=";
|
|
75
|
+
}
|
|
76
|
+
options.where.push({
|
|
77
|
+
field,
|
|
78
|
+
operator,
|
|
79
|
+
value: operator === "exists"
|
|
80
|
+
? undefined
|
|
81
|
+
: parseValue((op === ":contains" || op === ":startsWith") &&
|
|
82
|
+
val.startsWith("=")
|
|
83
|
+
? val.slice(1)
|
|
84
|
+
: val),
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return options;
|
|
89
|
+
}
|
|
90
|
+
function parseValue(val) {
|
|
91
|
+
const trimmed = val.trim();
|
|
92
|
+
if (trimmed === "true")
|
|
93
|
+
return true;
|
|
94
|
+
if (trimmed === "false")
|
|
95
|
+
return false;
|
|
96
|
+
if (/^-?\d+$/.test(trimmed))
|
|
97
|
+
return parseInt(trimmed, 10);
|
|
98
|
+
if (/^-?\d+\.\d+$/.test(trimmed))
|
|
99
|
+
return parseFloat(trimmed);
|
|
100
|
+
if ((trimmed.startsWith('"') && trimmed.endsWith('"')) ||
|
|
101
|
+
(trimmed.startsWith("'") && trimmed.endsWith("'"))) {
|
|
102
|
+
return trimmed.slice(1, -1);
|
|
103
|
+
}
|
|
104
|
+
return trimmed;
|
|
105
|
+
}
|
|
106
|
+
function getFieldValue(block, field) {
|
|
107
|
+
if (field === "type")
|
|
108
|
+
return block.type;
|
|
109
|
+
if (field === "content")
|
|
110
|
+
return block.content;
|
|
111
|
+
if (field === "id")
|
|
112
|
+
return block.id;
|
|
113
|
+
if (block.properties && field in block.properties) {
|
|
114
|
+
return block.properties[field];
|
|
115
|
+
}
|
|
116
|
+
if (field === "hasHeaders" && block.table) {
|
|
117
|
+
return !!block.table.headers;
|
|
118
|
+
}
|
|
119
|
+
if (field === "rowCount" && block.table) {
|
|
120
|
+
return block.table.rows.length;
|
|
121
|
+
}
|
|
122
|
+
return undefined;
|
|
123
|
+
}
|
|
124
|
+
function evaluateClause(block, clause) {
|
|
125
|
+
const value = getFieldValue(block, clause.field);
|
|
126
|
+
switch (clause.operator) {
|
|
127
|
+
case "exists":
|
|
128
|
+
return value !== undefined;
|
|
129
|
+
case "=":
|
|
130
|
+
return String(value).toLowerCase() === String(clause.value).toLowerCase();
|
|
131
|
+
case "!=":
|
|
132
|
+
return String(value).toLowerCase() !== String(clause.value).toLowerCase();
|
|
133
|
+
case "<":
|
|
134
|
+
return compareValues(value, clause.value) < 0;
|
|
135
|
+
case ">":
|
|
136
|
+
return compareValues(value, clause.value) > 0;
|
|
137
|
+
case "<=":
|
|
138
|
+
return compareValues(value, clause.value) <= 0;
|
|
139
|
+
case ">=":
|
|
140
|
+
return compareValues(value, clause.value) >= 0;
|
|
141
|
+
case "contains":
|
|
142
|
+
return String(value)
|
|
143
|
+
.toLowerCase()
|
|
144
|
+
.includes(String(clause.value).toLowerCase());
|
|
145
|
+
case "startsWith":
|
|
146
|
+
return String(value)
|
|
147
|
+
.toLowerCase()
|
|
148
|
+
.startsWith(String(clause.value).toLowerCase());
|
|
149
|
+
default:
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
function compareValues(a, b) {
|
|
154
|
+
if (typeof a === "number" && typeof b === "number") {
|
|
155
|
+
return a - b;
|
|
156
|
+
}
|
|
157
|
+
const dateA = new Date(String(a));
|
|
158
|
+
const dateB = new Date(String(b));
|
|
159
|
+
if (!isNaN(dateA.getTime()) && !isNaN(dateB.getTime())) {
|
|
160
|
+
return dateA.getTime() - dateB.getTime();
|
|
161
|
+
}
|
|
162
|
+
return String(a).localeCompare(String(b));
|
|
163
|
+
}
|
|
164
|
+
function queryBlocks(document, options) {
|
|
165
|
+
if (!document || !document.blocks) {
|
|
166
|
+
return { blocks: [], total: 0, matched: 0 };
|
|
167
|
+
}
|
|
168
|
+
const opts = typeof options === "string" ? parseQuery(options) : options;
|
|
169
|
+
let blocks = (0, utils_1.flattenBlocks)(document.blocks);
|
|
170
|
+
if (opts.where && opts.where.length > 0) {
|
|
171
|
+
blocks = blocks.filter((block) => opts.where.every((clause) => evaluateClause(block, clause)));
|
|
172
|
+
}
|
|
173
|
+
if (opts.sort && opts.sort.length > 0) {
|
|
174
|
+
blocks.sort((a, b) => {
|
|
175
|
+
for (const sort of opts.sort) {
|
|
176
|
+
const valA = getFieldValue(a, sort.field);
|
|
177
|
+
const valB = getFieldValue(b, sort.field);
|
|
178
|
+
const cmp = compareValues(valA, valB);
|
|
179
|
+
if (cmp !== 0) {
|
|
180
|
+
return sort.direction === "desc" ? -cmp : cmp;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return 0;
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
const matched = blocks.length;
|
|
187
|
+
if (opts.offset && opts.offset > 0) {
|
|
188
|
+
blocks = blocks.slice(opts.offset);
|
|
189
|
+
}
|
|
190
|
+
if (opts.limit !== undefined && opts.limit >= 0) {
|
|
191
|
+
blocks = blocks.slice(0, opts.limit);
|
|
192
|
+
}
|
|
193
|
+
return {
|
|
194
|
+
blocks,
|
|
195
|
+
total: (0, utils_1.flattenBlocks)(document.blocks).length,
|
|
196
|
+
matched,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
function formatQueryResult(result, format = "simple") {
|
|
200
|
+
switch (format) {
|
|
201
|
+
case "json":
|
|
202
|
+
return JSON.stringify(result, null, 2);
|
|
203
|
+
case "table":
|
|
204
|
+
return formatAsTable(result.blocks);
|
|
205
|
+
case "simple":
|
|
206
|
+
default:
|
|
207
|
+
return result.blocks
|
|
208
|
+
.map((b) => `[${b.type}] ${b.content}${b.properties
|
|
209
|
+
? " | " +
|
|
210
|
+
Object.entries(b.properties)
|
|
211
|
+
.map(([k, v]) => `${k}:${v}`)
|
|
212
|
+
.join(" | ")
|
|
213
|
+
: ""}`)
|
|
214
|
+
.join("\n");
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
function formatAsTable(blocks) {
|
|
218
|
+
if (blocks.length === 0)
|
|
219
|
+
return "No results";
|
|
220
|
+
const headers = ["ID", "Type", "Content", "Properties"];
|
|
221
|
+
const rows = blocks.map((b) => [
|
|
222
|
+
b.id.slice(0, 8),
|
|
223
|
+
b.type,
|
|
224
|
+
b.content.slice(0, 40),
|
|
225
|
+
Object.entries(b.properties || {})
|
|
226
|
+
.map(([k, v]) => `${k}:${String(v).slice(0, 15)}`)
|
|
227
|
+
.join(", ") || "-",
|
|
228
|
+
]);
|
|
229
|
+
const colWidths = headers.map((h, i) => Math.max(h.length, ...rows.map((r) => String(r[i]).length)));
|
|
230
|
+
const separator = "+" + colWidths.map((w) => "-".repeat(w + 2)).join("+") + "+";
|
|
231
|
+
const headerRow = "| " + headers.map((h, i) => h.padEnd(colWidths[i])).join(" | ") + " |";
|
|
232
|
+
const dataRows = rows.map((row) => "| " +
|
|
233
|
+
row.map((cell, i) => String(cell).padEnd(colWidths[i])).join(" | ") +
|
|
234
|
+
" |");
|
|
235
|
+
return [separator, headerRow, separator, ...dataRows, separator].join("\n");
|
|
236
|
+
}
|
|
237
|
+
function queryDocument(doc, query = {}) {
|
|
238
|
+
if (!doc || !Array.isArray(doc.blocks))
|
|
239
|
+
return [];
|
|
240
|
+
const allBlocks = (0, utils_1.flattenBlocks)(doc.blocks);
|
|
241
|
+
if (Object.keys(query).length === 0)
|
|
242
|
+
return [...allBlocks];
|
|
243
|
+
let sectionBlocks = null;
|
|
244
|
+
if (query.section !== undefined) {
|
|
245
|
+
sectionBlocks = new Set();
|
|
246
|
+
let inMatchingSection = false;
|
|
247
|
+
for (const block of allBlocks) {
|
|
248
|
+
if (block.type === "section") {
|
|
249
|
+
inMatchingSection = matchValue(block.content, query.section);
|
|
250
|
+
}
|
|
251
|
+
else if (inMatchingSection) {
|
|
252
|
+
sectionBlocks.add(block.id);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
let results = [];
|
|
257
|
+
for (const block of allBlocks) {
|
|
258
|
+
if (sectionBlocks !== null && !sectionBlocks.has(block.id))
|
|
259
|
+
continue;
|
|
260
|
+
if (query.type !== undefined) {
|
|
261
|
+
const types = Array.isArray(query.type) ? query.type : [query.type];
|
|
262
|
+
if (!types.includes(block.type))
|
|
263
|
+
continue;
|
|
264
|
+
}
|
|
265
|
+
if (query.content !== undefined) {
|
|
266
|
+
if (!matchValue(block.content || "", query.content))
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
269
|
+
if (query.properties !== undefined) {
|
|
270
|
+
let allMatch = true;
|
|
271
|
+
for (const [key, expected] of Object.entries(query.properties)) {
|
|
272
|
+
const actual = block.properties?.[key];
|
|
273
|
+
if (actual === undefined || !matchValue(String(actual), expected)) {
|
|
274
|
+
allMatch = false;
|
|
275
|
+
break;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
if (!allMatch)
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
results.push(block);
|
|
282
|
+
}
|
|
283
|
+
if (query.limit !== undefined && query.limit >= 0) {
|
|
284
|
+
results = results.slice(0, query.limit);
|
|
285
|
+
}
|
|
286
|
+
return results;
|
|
287
|
+
}
|
|
288
|
+
function matchValue(text, pattern) {
|
|
289
|
+
if (typeof pattern === "string") {
|
|
290
|
+
return text.toLowerCase().includes(pattern.toLowerCase());
|
|
291
|
+
}
|
|
292
|
+
return pattern.test(text);
|
|
293
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { IntentDocument, PrintLayout } from "./types";
|
|
2
|
+
import { IntentTheme } from "./theme";
|
|
3
|
+
export interface RenderOptions {
|
|
4
|
+
theme?: string | IntentTheme;
|
|
5
|
+
}
|
|
6
|
+
export declare function collectPrintLayout(doc: IntentDocument): PrintLayout;
|
|
7
|
+
export declare function cssContentValue(text: string): string;
|
|
8
|
+
export declare const DOC_STYLE_TARGETS: Record<string, string[]>;
|
|
9
|
+
export interface DocumentStyleRule {
|
|
10
|
+
target: string;
|
|
11
|
+
declarations: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function collectDocumentStyles(doc: IntentDocument): DocumentStyleRule[];
|
|
14
|
+
export declare function documentStyleCSS(doc: IntentDocument, selectorMap?: Record<string, string[]>, selectorPrefix?: string): string;
|
|
15
|
+
export declare function renderHTML(document: IntentDocument, options?: RenderOptions): string;
|
|
16
|
+
export declare function renderPrint(doc: IntentDocument, options?: RenderOptions): string;
|