mindoodb-app-sdk 0.0.71 → 0.0.72
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/README.md +70 -1
- package/dist/{chunk-GTNDGA7P.js → chunk-UFP7O4OJ.js} +571 -39
- package/dist/index.d.ts +3 -55
- package/dist/index.js +41 -1
- package/dist/testing/index.d.ts +101 -3
- package/dist/testing/index.js +340 -17
- package/dist/{types-Dff-SyIx.d.ts → types-DN-E0X34.d.ts} +476 -5
- package/package.json +1 -1
|
@@ -66,6 +66,296 @@ function assertValidMindooDBCreateIds(input, methodName = "createDocument") {
|
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
// src/inspection.ts
|
|
70
|
+
var MINDOODB_INSPECT_DOCUMENT = "mindoo.inspect.document@1";
|
|
71
|
+
var MINDOODB_INSPECT_SPREADSHEET = "mindoo.inspect.spreadsheet@1";
|
|
72
|
+
var MINDOODB_INSPECT_SLIDES = "mindoo.inspect.slides@1";
|
|
73
|
+
var MINDOODB_APP_INSPECTION_FIELD = "inspection";
|
|
74
|
+
var MINDOODB_APP_INSPECTION_SUMMARY_MAX_BYTES = 8 * 1024;
|
|
75
|
+
var MINDOODB_APP_INSPECTION_MAX_BYTES = 256 * 1024;
|
|
76
|
+
var MINDOODB_APP_ISSUES_MAX = 100;
|
|
77
|
+
var MindooDBAppEmbedValidationError = class extends Error {
|
|
78
|
+
constructor(issues) {
|
|
79
|
+
const first = issues.find((issue) => issue.severity === "error") ?? issues[0];
|
|
80
|
+
super(first ? first.message : "The document was not saved.");
|
|
81
|
+
this.issues = issues;
|
|
82
|
+
this.name = "MindooDBAppEmbedValidationError";
|
|
83
|
+
}
|
|
84
|
+
issues;
|
|
85
|
+
};
|
|
86
|
+
var SUPPORTS_CAPABILITY = /^[a-z][a-z0-9-]{0,31}$/;
|
|
87
|
+
function mindooDBAppComponentSupports(supports, requirement) {
|
|
88
|
+
const wanted = requirement.trim();
|
|
89
|
+
return (supports ?? []).some((entry) => entry === wanted || !wanted.includes(":") && entry.startsWith(`${wanted}:`));
|
|
90
|
+
}
|
|
91
|
+
function mindooDBAppInspectContracts(supports) {
|
|
92
|
+
return (supports ?? []).filter((entry) => entry.startsWith("inspect:")).map((entry) => entry.slice("inspect:".length));
|
|
93
|
+
}
|
|
94
|
+
function isPlainObject(value) {
|
|
95
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
96
|
+
}
|
|
97
|
+
function normalizeMindooDBAppInspectAnchor(raw) {
|
|
98
|
+
if (!isPlainObject(raw)) {
|
|
99
|
+
return void 0;
|
|
100
|
+
}
|
|
101
|
+
if (raw.kind === "heading" && typeof raw.id === "string" && raw.id && raw.id.length <= 200) {
|
|
102
|
+
return { kind: "heading", id: raw.id };
|
|
103
|
+
}
|
|
104
|
+
if (raw.kind === "cell" && typeof raw.ref === "string" && raw.ref && raw.ref.length <= 200) {
|
|
105
|
+
return { kind: "cell", ref: raw.ref };
|
|
106
|
+
}
|
|
107
|
+
if (raw.kind === "slide" && Number.isInteger(raw.index) && raw.index >= 0) {
|
|
108
|
+
return { kind: "slide", index: raw.index };
|
|
109
|
+
}
|
|
110
|
+
return void 0;
|
|
111
|
+
}
|
|
112
|
+
function normalizeMindooDBAppIssues(raw) {
|
|
113
|
+
if (!Array.isArray(raw)) {
|
|
114
|
+
return [];
|
|
115
|
+
}
|
|
116
|
+
const issues = [];
|
|
117
|
+
for (const entry of raw) {
|
|
118
|
+
if (issues.length >= MINDOODB_APP_ISSUES_MAX) {
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
if (!isPlainObject(entry) || typeof entry.message !== "string" || !entry.message.trim()) {
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
const severity = entry.severity === "warning" || entry.severity === "info" ? entry.severity : entry.severity === "error" ? "error" : null;
|
|
125
|
+
if (!severity) {
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
const anchor = normalizeMindooDBAppInspectAnchor(entry.anchor);
|
|
129
|
+
const code = typeof entry.code === "string" && entry.code.trim() ? entry.code.trim().slice(0, 64) : void 0;
|
|
130
|
+
issues.push({
|
|
131
|
+
severity,
|
|
132
|
+
message: entry.message.trim().slice(0, 500),
|
|
133
|
+
...anchor ? { anchor } : {},
|
|
134
|
+
...code ? { code } : {}
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
return issues;
|
|
138
|
+
}
|
|
139
|
+
function normalizeMindooDBAppInspectRequest(raw) {
|
|
140
|
+
const input = isPlainObject(raw) ? raw : {};
|
|
141
|
+
const strings = (value, max) => Array.isArray(value) ? [...new Set(value.filter((entry) => typeof entry === "string" && !!entry && entry.length <= 200))].slice(0, max) : [];
|
|
142
|
+
const include = strings(input.include, 16);
|
|
143
|
+
const cells = strings(input.cells, 200);
|
|
144
|
+
const maxTextLength = Number(input.maxTextLength);
|
|
145
|
+
return {
|
|
146
|
+
...typeof input.contract === "string" && input.contract ? { contract: input.contract.slice(0, 200) } : {},
|
|
147
|
+
...include.length ? { include } : {},
|
|
148
|
+
...cells.length ? { cells } : {},
|
|
149
|
+
...Number.isFinite(maxTextLength) && maxTextLength > 0 ? { maxTextLength: Math.min(Math.floor(maxTextLength), 5e4) } : {}
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
function normalizeMindooDBAppInspection(raw) {
|
|
153
|
+
let json;
|
|
154
|
+
try {
|
|
155
|
+
json = JSON.stringify(raw);
|
|
156
|
+
} catch {
|
|
157
|
+
throw new Error("An inspection must be plain JSON.");
|
|
158
|
+
}
|
|
159
|
+
if (!json || json.length > MINDOODB_APP_INSPECTION_MAX_BYTES) {
|
|
160
|
+
throw new Error(`An inspection must not be larger than ${MINDOODB_APP_INSPECTION_MAX_BYTES / 1024} KiB.`);
|
|
161
|
+
}
|
|
162
|
+
const value = JSON.parse(json);
|
|
163
|
+
if (!isPlainObject(value) || typeof value.contract !== "string" || !value.contract) {
|
|
164
|
+
throw new Error("An inspection must be an object with a contract.");
|
|
165
|
+
}
|
|
166
|
+
return value;
|
|
167
|
+
}
|
|
168
|
+
var SUMMARY_TEXT_STEPS = [500, 200, 0];
|
|
169
|
+
var SUMMARY_LIST_STEPS = [50, 20, 5, 0];
|
|
170
|
+
function shorten(value, textMax, listMax, marks) {
|
|
171
|
+
if (typeof value === "string") {
|
|
172
|
+
if (value.length <= textMax) return value;
|
|
173
|
+
marks.truncated = true;
|
|
174
|
+
return value.slice(0, textMax);
|
|
175
|
+
}
|
|
176
|
+
if (Array.isArray(value)) {
|
|
177
|
+
if (value.length > listMax) marks.truncated = true;
|
|
178
|
+
return value.slice(0, listMax).map((entry) => shorten(entry, Math.min(textMax || 80, 80), listMax, marks));
|
|
179
|
+
}
|
|
180
|
+
if (isPlainObject(value)) {
|
|
181
|
+
return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, shorten(entry, textMax, listMax, marks)]));
|
|
182
|
+
}
|
|
183
|
+
return value;
|
|
184
|
+
}
|
|
185
|
+
function summarizeMindooDBAppInspection(inspection, maxBytes = MINDOODB_APP_INSPECTION_SUMMARY_MAX_BYTES) {
|
|
186
|
+
const { cells: _cells, ...rest } = inspection;
|
|
187
|
+
const base = JSON.parse(JSON.stringify(rest));
|
|
188
|
+
for (const textMax of SUMMARY_TEXT_STEPS) {
|
|
189
|
+
for (const listMax of SUMMARY_LIST_STEPS) {
|
|
190
|
+
const marks = { truncated: false };
|
|
191
|
+
const next = shorten(base, textMax, listMax, marks);
|
|
192
|
+
if (textMax === 0 && typeof next.text === "string") delete next.text;
|
|
193
|
+
next.contract = inspection.contract;
|
|
194
|
+
if (typeof inspection.subject === "string") next.subject = inspection.subject.slice(0, 200);
|
|
195
|
+
if (marks.truncated || inspection.truncated) next.truncated = true;
|
|
196
|
+
if (JSON.stringify(next).length <= maxBytes) {
|
|
197
|
+
return next;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return { contract: inspection.contract, truncated: true };
|
|
202
|
+
}
|
|
203
|
+
function mindooDBAppInspectionSummaryValue(inspection) {
|
|
204
|
+
return MindooDBAppValue.atomic(JSON.stringify(summarizeMindooDBAppInspection(inspection)));
|
|
205
|
+
}
|
|
206
|
+
function readMindooDBAppInspectionSummary(root) {
|
|
207
|
+
let value = root?.[MINDOODB_APP_INSPECTION_FIELD];
|
|
208
|
+
if (typeof value === "string") {
|
|
209
|
+
try {
|
|
210
|
+
value = JSON.parse(value);
|
|
211
|
+
} catch {
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return isPlainObject(value) && typeof value.contract === "string" ? value : null;
|
|
216
|
+
}
|
|
217
|
+
function outcomeIssues(rule, outcome) {
|
|
218
|
+
if (!outcome) return [];
|
|
219
|
+
if (typeof outcome === "string") {
|
|
220
|
+
return [{ severity: rule.severity ?? "error", message: outcome, code: rule.code }];
|
|
221
|
+
}
|
|
222
|
+
return (Array.isArray(outcome) ? outcome : [outcome]).map((issue) => ({ code: rule.code, ...issue }));
|
|
223
|
+
}
|
|
224
|
+
function defineDocumentRules(definition) {
|
|
225
|
+
const request = normalizeMindooDBAppInspectRequest(definition);
|
|
226
|
+
function check(inspection) {
|
|
227
|
+
if (!inspection || definition.contract && inspection.contract !== definition.contract) {
|
|
228
|
+
return [];
|
|
229
|
+
}
|
|
230
|
+
const issues = definition.rules.flatMap((rule) => {
|
|
231
|
+
try {
|
|
232
|
+
return outcomeIssues(rule, rule.check(inspection));
|
|
233
|
+
} catch (error) {
|
|
234
|
+
return [
|
|
235
|
+
{
|
|
236
|
+
severity: "warning",
|
|
237
|
+
code: rule.code,
|
|
238
|
+
message: `Check "${rule.code}" failed: ${error instanceof Error ? error.message : String(error)}`
|
|
239
|
+
}
|
|
240
|
+
];
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
return normalizeMindooDBAppIssues(issues);
|
|
244
|
+
}
|
|
245
|
+
const rules = {
|
|
246
|
+
request,
|
|
247
|
+
check,
|
|
248
|
+
checkRoot: (root) => check(readMindooDBAppInspectionSummary(root)),
|
|
249
|
+
beforeSave: ({ inspection }) => ({ issues: check(inspection) }),
|
|
250
|
+
attach: (embed) => embed.onBeforeSave(rules.beforeSave, { inspect: request })
|
|
251
|
+
};
|
|
252
|
+
return rules;
|
|
253
|
+
}
|
|
254
|
+
function plural(count, one, many) {
|
|
255
|
+
return `${count} ${count === 1 ? one : many}`;
|
|
256
|
+
}
|
|
257
|
+
var mindooDBAppInspectRules = {
|
|
258
|
+
/** Documents: no placeholder or MERGEFIELD left open. */
|
|
259
|
+
noOpenPlaceholders(severity = "error", message) {
|
|
260
|
+
return {
|
|
261
|
+
code: "open-placeholders",
|
|
262
|
+
severity,
|
|
263
|
+
check: (inspection) => {
|
|
264
|
+
const names = (inspection.placeholders ?? []).map((entry) => entry.name);
|
|
265
|
+
if (!names.length) return null;
|
|
266
|
+
return message?.(names) ?? `${plural(names.length, "placeholder is", "placeholders are")} not filled in: ${names.slice(0, 5).join(", ")}${names.length > 5 ? ", \u2026" : ""}`;
|
|
267
|
+
}
|
|
268
|
+
};
|
|
269
|
+
},
|
|
270
|
+
/** Documents: every comment resolved. */
|
|
271
|
+
noOpenComments(severity = "warning", message) {
|
|
272
|
+
return {
|
|
273
|
+
code: "open-comments",
|
|
274
|
+
severity,
|
|
275
|
+
check: (inspection) => inspection.openComments > 0 ? message?.(inspection.openComments) ?? `${plural(inspection.openComments, "comment is", "comments are")} not resolved.` : null
|
|
276
|
+
};
|
|
277
|
+
},
|
|
278
|
+
/** Documents: every tracked change accepted or rejected. */
|
|
279
|
+
noOpenTrackedChanges(severity = "warning", message) {
|
|
280
|
+
return {
|
|
281
|
+
code: "open-tracked-changes",
|
|
282
|
+
severity,
|
|
283
|
+
check: (inspection) => inspection.openTrackedChanges > 0 ? message?.(inspection.openTrackedChanges) ?? `${plural(inspection.openTrackedChanges, "tracked change is", "tracked changes are")} not accepted or rejected.` : null
|
|
284
|
+
};
|
|
285
|
+
},
|
|
286
|
+
/** Spreadsheets: no formula evaluates to an error; one issue per cell. */
|
|
287
|
+
noFormulaErrors(severity = "error") {
|
|
288
|
+
return {
|
|
289
|
+
code: "formula-errors",
|
|
290
|
+
severity,
|
|
291
|
+
check: (inspection) => (inspection.formulaErrors ?? []).map((entry) => ({
|
|
292
|
+
severity,
|
|
293
|
+
message: `${entry.ref}: ${entry.error}`,
|
|
294
|
+
anchor: { kind: "cell", ref: entry.ref }
|
|
295
|
+
}))
|
|
296
|
+
};
|
|
297
|
+
},
|
|
298
|
+
/** Presentations: no layout placeholder left empty; one issue per slide. */
|
|
299
|
+
noEmptySlidePlaceholders(severity = "warning") {
|
|
300
|
+
return {
|
|
301
|
+
code: "empty-placeholders",
|
|
302
|
+
severity,
|
|
303
|
+
check: (inspection) => {
|
|
304
|
+
const bySlide = /* @__PURE__ */ new Map();
|
|
305
|
+
for (const entry of inspection.emptyPlaceholders ?? []) {
|
|
306
|
+
bySlide.set(entry.slide, [...bySlide.get(entry.slide) ?? [], entry.placeholder]);
|
|
307
|
+
}
|
|
308
|
+
return [...bySlide.entries()].map(([slide, names]) => ({
|
|
309
|
+
severity,
|
|
310
|
+
message: `Slide ${slide + 1}: empty ${names.join(", ")}`,
|
|
311
|
+
anchor: { kind: "slide", index: slide }
|
|
312
|
+
}));
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
function isMindooDBAppSupportsEntry(entry, contractPattern) {
|
|
318
|
+
const [capability, contract, ...rest] = entry.split(":");
|
|
319
|
+
if (rest.length || !capability || !SUPPORTS_CAPABILITY.test(capability)) {
|
|
320
|
+
return false;
|
|
321
|
+
}
|
|
322
|
+
return contract === void 0 || contractPattern.test(contract);
|
|
323
|
+
}
|
|
324
|
+
async function performMindooDBAppEmbeddingSave(steps) {
|
|
325
|
+
const validation = await steps.validate();
|
|
326
|
+
if (!validation.ok) {
|
|
327
|
+
if (validation.issues.length && steps.showIssues) {
|
|
328
|
+
try {
|
|
329
|
+
await steps.showIssues(validation.issues);
|
|
330
|
+
} catch (error) {
|
|
331
|
+
console.warn("[mindoodb-app-sdk] Showing issues failed.", error);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
throw new MindooDBAppEmbedValidationError(validation.issues);
|
|
335
|
+
}
|
|
336
|
+
let inspection = null;
|
|
337
|
+
if (steps.provider) {
|
|
338
|
+
try {
|
|
339
|
+
inspection = mindooDBAppInspectionSummaryValue(normalizeMindooDBAppInspection(await steps.provider({})));
|
|
340
|
+
} catch (error) {
|
|
341
|
+
console.warn("[mindoodb-app-sdk] Could not summarize the document.", error);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
await steps.flush({ inspection, issues: validation.issues });
|
|
345
|
+
await steps.saved();
|
|
346
|
+
return validation;
|
|
347
|
+
}
|
|
348
|
+
async function resolveMindooDBAppEmbedValidation(issues, interactive, confirm) {
|
|
349
|
+
if (issues.some((issue) => issue.severity === "error")) {
|
|
350
|
+
return { ok: false, issues };
|
|
351
|
+
}
|
|
352
|
+
const warnings = issues.filter((issue) => issue.severity === "warning");
|
|
353
|
+
if (!warnings.length || !interactive) {
|
|
354
|
+
return { ok: true, issues };
|
|
355
|
+
}
|
|
356
|
+
return { ok: await confirm(warnings) === true, issues };
|
|
357
|
+
}
|
|
358
|
+
|
|
69
359
|
// src/appDefinition.ts
|
|
70
360
|
var MINDOODB_APP_DEFINITION_FORMAT = "mindoodb.haven.app";
|
|
71
361
|
var MINDOODB_APP_DEFINITION_VERSION = 1;
|
|
@@ -96,7 +386,7 @@ var MINDOODB_APP_AGENT_LIMIT_MAX = 300;
|
|
|
96
386
|
var MINDOODB_APP_AGENT_GUIDE_MAX_BYTES = 8 * 1024;
|
|
97
387
|
var MINDOODB_APP_AGENT_TOOL_NAME_PATTERN = /^[a-z][a-z0-9_]{0,47}$/;
|
|
98
388
|
var LOGICAL_DATABASE_ID_PATTERN = /^[a-z0-9][a-z0-9._-]*$/i;
|
|
99
|
-
function
|
|
389
|
+
function isPlainObject2(value) {
|
|
100
390
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
101
391
|
}
|
|
102
392
|
function readOptionalString(raw, key, errors) {
|
|
@@ -127,7 +417,7 @@ function readStringRecord(raw, key, errors) {
|
|
|
127
417
|
if (value === void 0 || value === null) {
|
|
128
418
|
return void 0;
|
|
129
419
|
}
|
|
130
|
-
if (!
|
|
420
|
+
if (!isPlainObject2(value)) {
|
|
131
421
|
errors.push(`App definition ${key} must be an object of string values.`);
|
|
132
422
|
return void 0;
|
|
133
423
|
}
|
|
@@ -193,7 +483,7 @@ function readDatabases(value, errors) {
|
|
|
193
483
|
const result = [];
|
|
194
484
|
const seen = /* @__PURE__ */ new Set();
|
|
195
485
|
value.forEach((entry, index) => {
|
|
196
|
-
if (!
|
|
486
|
+
if (!isPlainObject2(entry)) {
|
|
197
487
|
errors.push(`App definition database #${index} must be an object.`);
|
|
198
488
|
return;
|
|
199
489
|
}
|
|
@@ -246,7 +536,7 @@ function readLocalizedText(value, label, maxLength, errors) {
|
|
|
246
536
|
}
|
|
247
537
|
return trimmed || void 0;
|
|
248
538
|
}
|
|
249
|
-
if (!
|
|
539
|
+
if (!isPlainObject2(value)) {
|
|
250
540
|
errors.push(`${label} must be a string or an object of per-locale strings.`);
|
|
251
541
|
return void 0;
|
|
252
542
|
}
|
|
@@ -293,7 +583,7 @@ function readAccepts(value, errors) {
|
|
|
293
583
|
const ids = /* @__PURE__ */ new Set();
|
|
294
584
|
value.forEach((entry, index) => {
|
|
295
585
|
const label = `App definition accepts[${index}]`;
|
|
296
|
-
if (!
|
|
586
|
+
if (!isPlainObject2(entry)) {
|
|
297
587
|
errors.push(`${label} must be an object.`);
|
|
298
588
|
return;
|
|
299
589
|
}
|
|
@@ -354,7 +644,7 @@ var COMPONENT_FIELD_PATTERN = /^[A-Za-z_][A-Za-z0-9_]{0,63}$/;
|
|
|
354
644
|
var COMPONENT_INTENTS = ["create", "edit", "view"];
|
|
355
645
|
var COMPONENT_CREATE_MAX_BYTES = 16 * 1024;
|
|
356
646
|
function readComponentFieldMatch(value, label, errors) {
|
|
357
|
-
if (!
|
|
647
|
+
if (!isPlainObject2(value)) {
|
|
358
648
|
errors.push(`${label} must be an object of field values.`);
|
|
359
649
|
return void 0;
|
|
360
650
|
}
|
|
@@ -377,6 +667,28 @@ var MINDOODB_APP_COMPONENT_CONTRACT_PATTERN = /^[a-z][a-z0-9-]*(\.[a-z][a-z0-9-]
|
|
|
377
667
|
var COMPONENT_CONTRACTS_MAX = 8;
|
|
378
668
|
var COMPONENT_REFERENCES_MAX = 8;
|
|
379
669
|
var COMPONENT_REFERENCE_SHOW_MAX = 8;
|
|
670
|
+
var COMPONENT_SUPPORTS_MAX = 16;
|
|
671
|
+
function readComponentSupports(value, label, errors) {
|
|
672
|
+
if (value === void 0) {
|
|
673
|
+
return void 0;
|
|
674
|
+
}
|
|
675
|
+
if (!Array.isArray(value) || value.length > COMPONENT_SUPPORTS_MAX) {
|
|
676
|
+
errors.push(`${label} must be an array of at most ${COMPONENT_SUPPORTS_MAX} entries.`);
|
|
677
|
+
return void 0;
|
|
678
|
+
}
|
|
679
|
+
const result = [];
|
|
680
|
+
for (const entry of value) {
|
|
681
|
+
const text = typeof entry === "string" ? entry.trim() : "";
|
|
682
|
+
if (!isMindooDBAppSupportsEntry(text, MINDOODB_APP_COMPONENT_CONTRACT_PATTERN)) {
|
|
683
|
+
errors.push(`${label} entries must look like "validate" or "inspect:mindoo.inspect.document@1", received ${JSON.stringify(entry)}.`);
|
|
684
|
+
return void 0;
|
|
685
|
+
}
|
|
686
|
+
if (!result.includes(text)) {
|
|
687
|
+
result.push(text);
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
return result.length ? result : void 0;
|
|
691
|
+
}
|
|
380
692
|
function readComponentContracts(value, label, errors) {
|
|
381
693
|
if (value === void 0) {
|
|
382
694
|
return void 0;
|
|
@@ -387,14 +699,14 @@ function readComponentContracts(value, label, errors) {
|
|
|
387
699
|
}
|
|
388
700
|
const result = [];
|
|
389
701
|
for (const [index, entry] of value.entries()) {
|
|
390
|
-
const contract =
|
|
702
|
+
const contract = isPlainObject2(entry) && typeof entry.contract === "string" ? entry.contract.trim() : "";
|
|
391
703
|
if (!MINDOODB_APP_COMPONENT_CONTRACT_PATTERN.test(contract)) {
|
|
392
704
|
errors.push(`${label}[${index}].contract must look like "mindoo.contacts.company@1".`);
|
|
393
705
|
return void 0;
|
|
394
706
|
}
|
|
395
707
|
let fields;
|
|
396
|
-
if (
|
|
397
|
-
if (!
|
|
708
|
+
if (isPlainObject2(entry) && entry.fields !== void 0) {
|
|
709
|
+
if (!isPlainObject2(entry.fields)) {
|
|
398
710
|
errors.push(`${label}[${index}].fields must map contract fields to document fields.`);
|
|
399
711
|
return void 0;
|
|
400
712
|
}
|
|
@@ -423,7 +735,7 @@ function readComponentReferences(value, label, rootMatch, errors) {
|
|
|
423
735
|
const fieldsSeen = /* @__PURE__ */ new Set();
|
|
424
736
|
for (const [index, entry] of value.entries()) {
|
|
425
737
|
const at = `${label}[${index}]`;
|
|
426
|
-
if (!
|
|
738
|
+
if (!isPlainObject2(entry)) {
|
|
427
739
|
errors.push(`${at} must be an object.`);
|
|
428
740
|
return void 0;
|
|
429
741
|
}
|
|
@@ -472,7 +784,7 @@ function readComponents(value, errors) {
|
|
|
472
784
|
value.forEach((entry, index) => {
|
|
473
785
|
const label = `App definition components[${index}]`;
|
|
474
786
|
const errorCount = errors.length;
|
|
475
|
-
if (!
|
|
787
|
+
if (!isPlainObject2(entry)) {
|
|
476
788
|
errors.push(`${label} must be an object.`);
|
|
477
789
|
return;
|
|
478
790
|
}
|
|
@@ -519,7 +831,7 @@ function readComponents(value, errors) {
|
|
|
519
831
|
}
|
|
520
832
|
let create;
|
|
521
833
|
if (entry.create !== void 0) {
|
|
522
|
-
if (!
|
|
834
|
+
if (!isPlainObject2(entry.create)) {
|
|
523
835
|
errors.push(`${label}.create must be an object of initial field values.`);
|
|
524
836
|
return;
|
|
525
837
|
}
|
|
@@ -548,7 +860,7 @@ function readComponents(value, errors) {
|
|
|
548
860
|
}
|
|
549
861
|
let children;
|
|
550
862
|
if (entry.children !== void 0) {
|
|
551
|
-
if (!
|
|
863
|
+
if (!isPlainObject2(entry.children)) {
|
|
552
864
|
errors.push(`${label}.children must be an object.`);
|
|
553
865
|
return;
|
|
554
866
|
}
|
|
@@ -577,6 +889,7 @@ function readComponents(value, errors) {
|
|
|
577
889
|
}
|
|
578
890
|
const provides = readComponentContracts(entry.provides, `${label}.provides`, errors);
|
|
579
891
|
const references = readComponentReferences(entry.references, `${label}.references`, match, errors);
|
|
892
|
+
const supports = readComponentSupports(entry.supports, `${label}.supports`, errors);
|
|
580
893
|
if (errors.length !== errorCount) {
|
|
581
894
|
return;
|
|
582
895
|
}
|
|
@@ -591,7 +904,8 @@ function readComponents(value, errors) {
|
|
|
591
904
|
...children ? { children } : {},
|
|
592
905
|
...category ? { category } : {},
|
|
593
906
|
...provides ? { provides } : {},
|
|
594
|
-
...references ? { references } : {}
|
|
907
|
+
...references ? { references } : {},
|
|
908
|
+
...supports ? { supports } : {}
|
|
595
909
|
});
|
|
596
910
|
});
|
|
597
911
|
return result.length ? result : void 0;
|
|
@@ -631,7 +945,7 @@ function readListing(value, errors) {
|
|
|
631
945
|
if (value === void 0 || value === null) {
|
|
632
946
|
return void 0;
|
|
633
947
|
}
|
|
634
|
-
if (!
|
|
948
|
+
if (!isPlainObject2(value)) {
|
|
635
949
|
errors.push("App definition listing must be an object.");
|
|
636
950
|
return void 0;
|
|
637
951
|
}
|
|
@@ -671,7 +985,7 @@ function readListing(value, errors) {
|
|
|
671
985
|
value.screenshots.forEach((entry, index) => {
|
|
672
986
|
const label = `App definition listing.screenshots[${index}]`;
|
|
673
987
|
const raw = typeof entry === "string" ? { file: entry } : entry;
|
|
674
|
-
if (!
|
|
988
|
+
if (!isPlainObject2(raw)) {
|
|
675
989
|
errors.push(`${label} must be a path or an object with a file.`);
|
|
676
990
|
return;
|
|
677
991
|
}
|
|
@@ -686,7 +1000,7 @@ function readListing(value, errors) {
|
|
|
686
1000
|
}
|
|
687
1001
|
}
|
|
688
1002
|
if (value.publisher !== void 0 && value.publisher !== null) {
|
|
689
|
-
const publisher =
|
|
1003
|
+
const publisher = isPlainObject2(value.publisher) ? value.publisher : {};
|
|
690
1004
|
const name = typeof publisher.name === "string" ? publisher.name.trim() : "";
|
|
691
1005
|
if (!name) {
|
|
692
1006
|
errors.push("App definition listing.publisher must be an object with a non-empty name.");
|
|
@@ -705,7 +1019,7 @@ var AGENT_CAPABILITY_ID_PATTERN = /^[a-z0-9][a-z0-9_-]{0,47}$/;
|
|
|
705
1019
|
var AGENT_LOCALE_PATTERN = /^[a-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$/;
|
|
706
1020
|
var AGENT_GUIDE_PATH_PATTERN = /^[A-Za-z0-9_][A-Za-z0-9_.\/-]{0,199}\.md$/;
|
|
707
1021
|
function readAgentLocaleText(value, label, maxLength, errors) {
|
|
708
|
-
if (!
|
|
1022
|
+
if (!isPlainObject2(value)) {
|
|
709
1023
|
errors.push(`${label} must be an object of per-locale strings with an "en" entry.`);
|
|
710
1024
|
return void 0;
|
|
711
1025
|
}
|
|
@@ -736,7 +1050,7 @@ function readAgentLocaleList(value, label, maxLength, errors) {
|
|
|
736
1050
|
if (value === void 0) {
|
|
737
1051
|
return void 0;
|
|
738
1052
|
}
|
|
739
|
-
if (!
|
|
1053
|
+
if (!isPlainObject2(value)) {
|
|
740
1054
|
errors.push(`${label} must be an object of per-locale string arrays with an "en" entry.`);
|
|
741
1055
|
return void 0;
|
|
742
1056
|
}
|
|
@@ -777,7 +1091,7 @@ function readAgentCapabilities(value, errors) {
|
|
|
777
1091
|
const ids = /* @__PURE__ */ new Set();
|
|
778
1092
|
for (const [index, entry] of value.entries()) {
|
|
779
1093
|
const at = `${label}[${index}]`;
|
|
780
|
-
if (!
|
|
1094
|
+
if (!isPlainObject2(entry)) {
|
|
781
1095
|
errors.push(`${at} must be an object.`);
|
|
782
1096
|
return void 0;
|
|
783
1097
|
}
|
|
@@ -820,7 +1134,7 @@ function readAgentProfile(value, errors) {
|
|
|
820
1134
|
if (value === void 0 || value === null) {
|
|
821
1135
|
return void 0;
|
|
822
1136
|
}
|
|
823
|
-
if (!
|
|
1137
|
+
if (!isPlainObject2(value)) {
|
|
824
1138
|
errors.push("App definition agent must be an object.");
|
|
825
1139
|
return void 0;
|
|
826
1140
|
}
|
|
@@ -883,7 +1197,7 @@ function resolveMindooDBAppListingAssetUrl(path, originUrl) {
|
|
|
883
1197
|
}
|
|
884
1198
|
function validateMindooDBAppDefinition(raw) {
|
|
885
1199
|
const errors = [];
|
|
886
|
-
if (!
|
|
1200
|
+
if (!isPlainObject2(raw)) {
|
|
887
1201
|
return { definition: null, errors: ["App definition must be a JSON object."] };
|
|
888
1202
|
}
|
|
889
1203
|
if (raw.format !== MINDOODB_APP_DEFINITION_FORMAT) {
|
|
@@ -1397,29 +1711,29 @@ function bindDragSource(element, options, start, follow) {
|
|
|
1397
1711
|
}
|
|
1398
1712
|
|
|
1399
1713
|
// src/client/agentInput.ts
|
|
1400
|
-
function
|
|
1714
|
+
function isPlainObject3(value) {
|
|
1401
1715
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1402
1716
|
}
|
|
1403
1717
|
function isPlaceholder(value) {
|
|
1404
1718
|
if (value === null || value === void 0) return true;
|
|
1405
1719
|
if (typeof value === "string") return value.trim() === "";
|
|
1406
1720
|
if (Array.isArray(value)) return value.length === 0;
|
|
1407
|
-
if (
|
|
1721
|
+
if (isPlainObject3(value)) return Object.keys(value).length === 0;
|
|
1408
1722
|
return false;
|
|
1409
1723
|
}
|
|
1410
1724
|
function normalizeValue(value, schema) {
|
|
1411
|
-
if (!
|
|
1725
|
+
if (!isPlainObject3(schema)) return value;
|
|
1412
1726
|
if (Array.isArray(value)) {
|
|
1413
1727
|
const items = schema.items;
|
|
1414
|
-
return
|
|
1728
|
+
return isPlainObject3(items) ? value.map((item) => normalizeValue(item, items)) : value;
|
|
1415
1729
|
}
|
|
1416
|
-
if (
|
|
1730
|
+
if (isPlainObject3(value) && isPlainObject3(schema.properties)) {
|
|
1417
1731
|
return normalizeObject(value, schema);
|
|
1418
1732
|
}
|
|
1419
1733
|
return value;
|
|
1420
1734
|
}
|
|
1421
1735
|
function normalizeObject(input, schema) {
|
|
1422
|
-
const properties =
|
|
1736
|
+
const properties = isPlainObject3(schema.properties) ? schema.properties : {};
|
|
1423
1737
|
const required = new Set(Array.isArray(schema.required) ? schema.required.filter((key) => typeof key === "string") : []);
|
|
1424
1738
|
const result = {};
|
|
1425
1739
|
for (const [key, raw] of Object.entries(input)) {
|
|
@@ -1434,7 +1748,7 @@ function normalizeObject(input, schema) {
|
|
|
1434
1748
|
return result;
|
|
1435
1749
|
}
|
|
1436
1750
|
function normalizeAgentToolInput(input, schema) {
|
|
1437
|
-
return
|
|
1751
|
+
return isPlainObject3(input) ? normalizeObject(input, schema) : input;
|
|
1438
1752
|
}
|
|
1439
1753
|
|
|
1440
1754
|
// src/client/agentTools.ts
|
|
@@ -1651,6 +1965,15 @@ import { parseMindooDBFormulaBooleanExpression } from "mindoodb-view-language";
|
|
|
1651
1965
|
function isEmbedEventMessage(message) {
|
|
1652
1966
|
return message.kind === "embed-event";
|
|
1653
1967
|
}
|
|
1968
|
+
function isEmbedRequestMessage(message) {
|
|
1969
|
+
return message.kind === "embed-request";
|
|
1970
|
+
}
|
|
1971
|
+
function isMethodNotFound(error) {
|
|
1972
|
+
return error instanceof Error && error.name === "method-not-found";
|
|
1973
|
+
}
|
|
1974
|
+
function errorMessage(error) {
|
|
1975
|
+
return error instanceof Error ? error.message : String(error);
|
|
1976
|
+
}
|
|
1654
1977
|
function isEmbeddingRequestMessage(message) {
|
|
1655
1978
|
return message.kind === "embedding-request";
|
|
1656
1979
|
}
|
|
@@ -1717,13 +2040,14 @@ function createComponentFrame(container, url, allow) {
|
|
|
1717
2040
|
return frame;
|
|
1718
2041
|
}
|
|
1719
2042
|
var MindooDBAppEmbedImpl = class {
|
|
1720
|
-
constructor(rpc, embedId, componentKey, databaseId, docId, frame, container) {
|
|
2043
|
+
constructor(rpc, embedId, componentKey, databaseId, docId, frame, container, supports = []) {
|
|
1721
2044
|
this.rpc = rpc;
|
|
1722
2045
|
this.embedId = embedId;
|
|
1723
2046
|
this.componentKey = componentKey;
|
|
1724
2047
|
this.databaseId = databaseId;
|
|
1725
2048
|
this.docId = docId;
|
|
1726
2049
|
this.frame = frame;
|
|
2050
|
+
this.supports = supports;
|
|
1727
2051
|
this.closed = new Promise((resolve) => {
|
|
1728
2052
|
this.resolveClosed = resolve;
|
|
1729
2053
|
});
|
|
@@ -1740,6 +2064,7 @@ var MindooDBAppEmbedImpl = class {
|
|
|
1740
2064
|
databaseId;
|
|
1741
2065
|
docId;
|
|
1742
2066
|
frame;
|
|
2067
|
+
supports;
|
|
1743
2068
|
closed;
|
|
1744
2069
|
resolveClosed;
|
|
1745
2070
|
closedEvent = null;
|
|
@@ -1749,6 +2074,8 @@ var MindooDBAppEmbedImpl = class {
|
|
|
1749
2074
|
tracker = null;
|
|
1750
2075
|
toolsState = null;
|
|
1751
2076
|
toolsListeners = /* @__PURE__ */ new Set();
|
|
2077
|
+
beforeSaveHandler = null;
|
|
2078
|
+
savedListeners = /* @__PURE__ */ new Set();
|
|
1752
2079
|
get placement() {
|
|
1753
2080
|
return this.frame ? "frame" : "overlay";
|
|
1754
2081
|
}
|
|
@@ -1831,6 +2158,88 @@ var MindooDBAppEmbedImpl = class {
|
|
|
1831
2158
|
const stopClosed = this.onClosed(() => finish(null));
|
|
1832
2159
|
});
|
|
1833
2160
|
}
|
|
2161
|
+
async inspect(request) {
|
|
2162
|
+
const result = await this.rpc.call("embeds.inspect", {
|
|
2163
|
+
embedId: this.embedId,
|
|
2164
|
+
request: normalizeMindooDBAppInspectRequest(request)
|
|
2165
|
+
});
|
|
2166
|
+
return normalizeMindooDBAppInspection(result);
|
|
2167
|
+
}
|
|
2168
|
+
onBeforeSave(handler, options) {
|
|
2169
|
+
this.beforeSaveHandler = handler;
|
|
2170
|
+
this.announceBeforeSave(true, options?.inspect);
|
|
2171
|
+
return () => {
|
|
2172
|
+
if (this.beforeSaveHandler === handler) {
|
|
2173
|
+
this.beforeSaveHandler = null;
|
|
2174
|
+
this.announceBeforeSave(false);
|
|
2175
|
+
}
|
|
2176
|
+
};
|
|
2177
|
+
}
|
|
2178
|
+
/** Haven only asks hosts that said they check, and fetches the inspection they want. */
|
|
2179
|
+
announceBeforeSave(enabled, inspect) {
|
|
2180
|
+
if (this.closedEvent) {
|
|
2181
|
+
return;
|
|
2182
|
+
}
|
|
2183
|
+
void this.rpc.call("embeds.setBeforeSave", {
|
|
2184
|
+
embedId: this.embedId,
|
|
2185
|
+
enabled,
|
|
2186
|
+
...enabled ? { inspect: normalizeMindooDBAppInspectRequest(inspect) } : {}
|
|
2187
|
+
}).catch((error) => {
|
|
2188
|
+
if (!isMethodNotFound(error)) {
|
|
2189
|
+
console.warn("[mindoodb-app-sdk] Could not register the save check.", error);
|
|
2190
|
+
}
|
|
2191
|
+
});
|
|
2192
|
+
}
|
|
2193
|
+
/** Haven asks before the component saves: run the handler, never longer than Haven waits. */
|
|
2194
|
+
async answerBeforeSave(params) {
|
|
2195
|
+
const handler = this.beforeSaveHandler;
|
|
2196
|
+
if (!handler || this.closedEvent) {
|
|
2197
|
+
return { issues: [] };
|
|
2198
|
+
}
|
|
2199
|
+
const result = await handler({
|
|
2200
|
+
embedId: this.embedId,
|
|
2201
|
+
inspection: params?.inspection ?? null,
|
|
2202
|
+
root: params?.root ?? null
|
|
2203
|
+
});
|
|
2204
|
+
return { issues: normalizeMindooDBAppIssues(result?.issues) };
|
|
2205
|
+
}
|
|
2206
|
+
onAfterSave(listener) {
|
|
2207
|
+
this.savedListeners.add(listener);
|
|
2208
|
+
return () => {
|
|
2209
|
+
this.savedListeners.delete(listener);
|
|
2210
|
+
};
|
|
2211
|
+
}
|
|
2212
|
+
/** The component reported that it saved. */
|
|
2213
|
+
notifySaved() {
|
|
2214
|
+
if (this.closedEvent) {
|
|
2215
|
+
return;
|
|
2216
|
+
}
|
|
2217
|
+
const event = { embedId: this.embedId };
|
|
2218
|
+
this.savedListeners.forEach((listener) => {
|
|
2219
|
+
try {
|
|
2220
|
+
listener(event);
|
|
2221
|
+
} catch (error) {
|
|
2222
|
+
console.error("MindooDB embed saved listener failed.", error);
|
|
2223
|
+
}
|
|
2224
|
+
});
|
|
2225
|
+
}
|
|
2226
|
+
async showIssues(issues) {
|
|
2227
|
+
await this.rpc.call("embeds.showIssues", { embedId: this.embedId, issues: normalizeMindooDBAppIssues(issues) });
|
|
2228
|
+
}
|
|
2229
|
+
async reveal(anchor) {
|
|
2230
|
+
const normalized = normalizeMindooDBAppInspectAnchor(anchor);
|
|
2231
|
+
if (!normalized) {
|
|
2232
|
+
throw new Error("Invalid anchor.");
|
|
2233
|
+
}
|
|
2234
|
+
await this.rpc.call("embeds.reveal", { embedId: this.embedId, anchor: normalized });
|
|
2235
|
+
}
|
|
2236
|
+
async callTool(name, input) {
|
|
2237
|
+
return await this.rpc.call("embeds.callTool", {
|
|
2238
|
+
embedId: this.embedId,
|
|
2239
|
+
name: String(name),
|
|
2240
|
+
input: input === void 0 ? {} : JSON.parse(JSON.stringify(input))
|
|
2241
|
+
});
|
|
2242
|
+
}
|
|
1834
2243
|
async setRect(rect) {
|
|
1835
2244
|
if (this.closedEvent) {
|
|
1836
2245
|
return;
|
|
@@ -1885,6 +2294,8 @@ var MindooDBAppEmbedImpl = class {
|
|
|
1885
2294
|
});
|
|
1886
2295
|
this.listeners.clear();
|
|
1887
2296
|
this.dirtyListeners.clear();
|
|
2297
|
+
this.savedListeners.clear();
|
|
2298
|
+
this.beforeSaveHandler = null;
|
|
1888
2299
|
this.toolsState = null;
|
|
1889
2300
|
this.toolsListeners.forEach((listener) => {
|
|
1890
2301
|
try {
|
|
@@ -1904,6 +2315,10 @@ var MindooDBAppEmbedsClient = class {
|
|
|
1904
2315
|
void this.answerRequest(message);
|
|
1905
2316
|
return;
|
|
1906
2317
|
}
|
|
2318
|
+
if (isEmbedRequestMessage(message)) {
|
|
2319
|
+
void this.answerEmbedRequest(message);
|
|
2320
|
+
return;
|
|
2321
|
+
}
|
|
1907
2322
|
if (!isEmbedEventMessage(message)) {
|
|
1908
2323
|
return;
|
|
1909
2324
|
}
|
|
@@ -1927,6 +2342,10 @@ var MindooDBAppEmbedsClient = class {
|
|
|
1927
2342
|
}
|
|
1928
2343
|
return;
|
|
1929
2344
|
}
|
|
2345
|
+
if (message.event?.type === "saved") {
|
|
2346
|
+
this.open.get(message.event.embedId)?.notifySaved();
|
|
2347
|
+
return;
|
|
2348
|
+
}
|
|
1930
2349
|
if (message.event?.type !== "closed") {
|
|
1931
2350
|
return;
|
|
1932
2351
|
}
|
|
@@ -1964,7 +2383,8 @@ var MindooDBAppEmbedsClient = class {
|
|
|
1964
2383
|
input.databaseId,
|
|
1965
2384
|
input.docId,
|
|
1966
2385
|
frame,
|
|
1967
|
-
container
|
|
2386
|
+
container,
|
|
2387
|
+
Array.isArray(response.supports) ? response.supports.filter((entry) => typeof entry === "string") : []
|
|
1968
2388
|
);
|
|
1969
2389
|
const earlyDirty = this.earlyDirty.get(embed.embedId);
|
|
1970
2390
|
if (earlyDirty !== void 0) {
|
|
@@ -2040,7 +2460,45 @@ var MindooDBAppEmbedsClient = class {
|
|
|
2040
2460
|
this.saveHandler = null;
|
|
2041
2461
|
}
|
|
2042
2462
|
};
|
|
2043
|
-
}
|
|
2463
|
+
},
|
|
2464
|
+
provideInspection: (provider) => {
|
|
2465
|
+
this.inspectionProvider = provider;
|
|
2466
|
+
return () => {
|
|
2467
|
+
if (this.inspectionProvider === provider) {
|
|
2468
|
+
this.inspectionProvider = null;
|
|
2469
|
+
}
|
|
2470
|
+
};
|
|
2471
|
+
},
|
|
2472
|
+
onShowIssues: (handler) => {
|
|
2473
|
+
this.showIssuesHandler = handler;
|
|
2474
|
+
return () => {
|
|
2475
|
+
if (this.showIssuesHandler === handler) {
|
|
2476
|
+
this.showIssuesHandler = null;
|
|
2477
|
+
}
|
|
2478
|
+
};
|
|
2479
|
+
},
|
|
2480
|
+
onReveal: (handler) => {
|
|
2481
|
+
this.revealHandler = handler;
|
|
2482
|
+
return () => {
|
|
2483
|
+
if (this.revealHandler === handler) {
|
|
2484
|
+
this.revealHandler = null;
|
|
2485
|
+
}
|
|
2486
|
+
};
|
|
2487
|
+
},
|
|
2488
|
+
validate: async (options) => await this.validate(options),
|
|
2489
|
+
save: async (flush, options) => await performMindooDBAppEmbeddingSave({
|
|
2490
|
+
validate: () => this.validate(options),
|
|
2491
|
+
provider: this.inspectionProvider,
|
|
2492
|
+
showIssues: this.showIssuesHandler,
|
|
2493
|
+
flush,
|
|
2494
|
+
// Only news for the host: a lost message must not fail a save that happened.
|
|
2495
|
+
saved: () => this.rpc.call("embedding.saved", {}).then(
|
|
2496
|
+
() => {
|
|
2497
|
+
},
|
|
2498
|
+
() => {
|
|
2499
|
+
}
|
|
2500
|
+
)
|
|
2501
|
+
})
|
|
2044
2502
|
};
|
|
2045
2503
|
}
|
|
2046
2504
|
rpc;
|
|
@@ -2055,18 +2513,53 @@ var MindooDBAppEmbedsClient = class {
|
|
|
2055
2513
|
stopListening;
|
|
2056
2514
|
/** This app as a component: what to do when its host asks it to save. */
|
|
2057
2515
|
saveHandler = null;
|
|
2058
|
-
|
|
2516
|
+
inspectionProvider = null;
|
|
2517
|
+
showIssuesHandler = null;
|
|
2518
|
+
revealHandler = null;
|
|
2519
|
+
/** `embedding.validate`; ok when Haven cannot check (not embedded, older Haven). */
|
|
2520
|
+
async validate(options) {
|
|
2521
|
+
try {
|
|
2522
|
+
const result = await this.rpc.call("embedding.validate", {
|
|
2523
|
+
interactive: options?.interactive !== false
|
|
2524
|
+
});
|
|
2525
|
+
return {
|
|
2526
|
+
ok: result?.ok !== false,
|
|
2527
|
+
issues: normalizeMindooDBAppIssues(result?.issues),
|
|
2528
|
+
...result?.timedOut ? { timedOut: true } : {}
|
|
2529
|
+
};
|
|
2530
|
+
} catch (error) {
|
|
2531
|
+
if (isMethodNotFound(error) || error instanceof Error && error.name === "unsupported") {
|
|
2532
|
+
return { ok: true, issues: [] };
|
|
2533
|
+
}
|
|
2534
|
+
throw error;
|
|
2535
|
+
}
|
|
2536
|
+
}
|
|
2537
|
+
/** Runs the matching handler and tells Haven how it went; Haven answers the host. */
|
|
2059
2538
|
async answerRequest(message) {
|
|
2060
2539
|
let response;
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
try {
|
|
2540
|
+
try {
|
|
2541
|
+
const params = message.params ?? {};
|
|
2542
|
+
if (message.request === "save" && this.saveHandler) {
|
|
2065
2543
|
await this.saveHandler();
|
|
2066
2544
|
response = { ok: true };
|
|
2067
|
-
}
|
|
2068
|
-
|
|
2545
|
+
} else if (message.request === "inspect" && this.inspectionProvider) {
|
|
2546
|
+
const inspection = await this.inspectionProvider(normalizeMindooDBAppInspectRequest(params.request));
|
|
2547
|
+
response = { ok: true, result: normalizeMindooDBAppInspection(inspection) };
|
|
2548
|
+
} else if (message.request === "showIssues" && this.showIssuesHandler) {
|
|
2549
|
+
await this.showIssuesHandler(normalizeMindooDBAppIssues(params.issues));
|
|
2550
|
+
response = { ok: true };
|
|
2551
|
+
} else if (message.request === "reveal" && this.revealHandler) {
|
|
2552
|
+
const anchor = normalizeMindooDBAppInspectAnchor(params.anchor);
|
|
2553
|
+
if (!anchor) {
|
|
2554
|
+
throw new Error("Invalid anchor.");
|
|
2555
|
+
}
|
|
2556
|
+
await this.revealHandler(anchor);
|
|
2557
|
+
response = { ok: true };
|
|
2558
|
+
} else {
|
|
2559
|
+
response = { ok: false, error: "unsupported" };
|
|
2069
2560
|
}
|
|
2561
|
+
} catch (error) {
|
|
2562
|
+
response = { ok: false, error: errorMessage(error) };
|
|
2070
2563
|
}
|
|
2071
2564
|
try {
|
|
2072
2565
|
await this.rpc.call("embedding.respond", { requestId: message.requestId, ...response });
|
|
@@ -2074,6 +2567,24 @@ var MindooDBAppEmbedsClient = class {
|
|
|
2074
2567
|
console.warn("[mindoodb-app-sdk] Could not answer the host's request.", error);
|
|
2075
2568
|
}
|
|
2076
2569
|
}
|
|
2570
|
+
/** This app as a host: Haven asks before one of its components saves. */
|
|
2571
|
+
async answerEmbedRequest(message) {
|
|
2572
|
+
let response;
|
|
2573
|
+
const embed = this.open.get(message.embedId);
|
|
2574
|
+
try {
|
|
2575
|
+
response = message.request === "beforeSave" ? { ok: true, result: embed ? await embed.answerBeforeSave(message.params) : { issues: [] } } : { ok: false, error: "unsupported" };
|
|
2576
|
+
} catch (error) {
|
|
2577
|
+
response = {
|
|
2578
|
+
ok: true,
|
|
2579
|
+
result: { issues: [{ severity: "warning", message: `The check failed: ${errorMessage(error)}`, code: "check-failed" }] }
|
|
2580
|
+
};
|
|
2581
|
+
}
|
|
2582
|
+
try {
|
|
2583
|
+
await this.rpc.call("embeds.respond", { requestId: message.requestId, ...response });
|
|
2584
|
+
} catch (error) {
|
|
2585
|
+
console.warn("[mindoodb-app-sdk] Could not answer Haven's request.", error);
|
|
2586
|
+
}
|
|
2587
|
+
}
|
|
2077
2588
|
dispose() {
|
|
2078
2589
|
this.stopListening();
|
|
2079
2590
|
}
|
|
@@ -3907,6 +4418,27 @@ export {
|
|
|
3907
4418
|
isValidMindooDBDocumentId,
|
|
3908
4419
|
mindooDBDocumentId,
|
|
3909
4420
|
assertValidMindooDBCreateIds,
|
|
4421
|
+
MINDOODB_INSPECT_DOCUMENT,
|
|
4422
|
+
MINDOODB_INSPECT_SPREADSHEET,
|
|
4423
|
+
MINDOODB_INSPECT_SLIDES,
|
|
4424
|
+
MINDOODB_APP_INSPECTION_FIELD,
|
|
4425
|
+
MINDOODB_APP_INSPECTION_SUMMARY_MAX_BYTES,
|
|
4426
|
+
MINDOODB_APP_INSPECTION_MAX_BYTES,
|
|
4427
|
+
MINDOODB_APP_ISSUES_MAX,
|
|
4428
|
+
MindooDBAppEmbedValidationError,
|
|
4429
|
+
mindooDBAppComponentSupports,
|
|
4430
|
+
mindooDBAppInspectContracts,
|
|
4431
|
+
normalizeMindooDBAppInspectAnchor,
|
|
4432
|
+
normalizeMindooDBAppIssues,
|
|
4433
|
+
normalizeMindooDBAppInspectRequest,
|
|
4434
|
+
normalizeMindooDBAppInspection,
|
|
4435
|
+
summarizeMindooDBAppInspection,
|
|
4436
|
+
mindooDBAppInspectionSummaryValue,
|
|
4437
|
+
readMindooDBAppInspectionSummary,
|
|
4438
|
+
defineDocumentRules,
|
|
4439
|
+
mindooDBAppInspectRules,
|
|
4440
|
+
performMindooDBAppEmbeddingSave,
|
|
4441
|
+
resolveMindooDBAppEmbedValidation,
|
|
3910
4442
|
MINDOODB_APP_DEFINITION_FORMAT,
|
|
3911
4443
|
MINDOODB_APP_DEFINITION_VERSION,
|
|
3912
4444
|
MINDOODB_APP_DEFINITION_FILE_NAME,
|