@anubhav-choubey/web-for-agents 0.1.0 → 0.2.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/README.md +74 -515
- package/dist/bin.js +4 -4
- package/dist/chunk-CGIIB6AF.js +127 -0
- package/dist/{chunk-AZG5MLNG.js → chunk-F7PN5R25.js} +2 -0
- package/dist/chunk-LCVPXUFN.js +245 -0
- package/dist/{chunk-IF32TPGR.js → chunk-P6JSPAA2.js} +169 -124
- package/dist/{chunk-5TNG4QMP.js → chunk-PGZH33B5.js} +20 -2
- package/dist/chunk-PHTV5NAY.js +44 -0
- package/dist/{chunk-ZYMNO5AO.js → chunk-PSNLS4GL.js} +93 -57
- package/dist/{chunk-HONWT6GK.js → chunk-SMFRAZAA.js} +66 -34
- package/dist/cli.js +4 -4
- package/dist/{happyDom-XVDHYJDM.js → happyDom-WTYQ5UAC.js} +3 -3
- package/dist/index.js +41 -235
- package/dist/overlay.js +7 -32
- package/dist/{renderChild-Y2RFSYY4.js → renderChild-H6TR4SGV.js} +27 -4
- package/dist/vite.d.ts +88 -2
- package/dist/vite.js +628 -146
- package/package.json +1 -1
- package/dist/chunk-CKXHTGGT.js +0 -25
- package/dist/chunk-LCVI2PRP.js +0 -13
package/dist/bin.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
runCli
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-P6JSPAA2.js";
|
|
5
|
+
import "./chunk-CGIIB6AF.js";
|
|
6
|
+
import "./chunk-PHTV5NAY.js";
|
|
7
7
|
import "./chunk-LCLDQ3A3.js";
|
|
8
8
|
import "./chunk-FEAKVNMG.js";
|
|
9
|
-
import "./chunk-
|
|
9
|
+
import "./chunk-F7PN5R25.js";
|
|
10
10
|
import "./chunk-JJN6FNJD.js";
|
|
11
11
|
|
|
12
12
|
// src/cli/bin.ts
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
// src/shared/bots.ts
|
|
2
|
+
var AI_BOTS = {
|
|
3
|
+
training: [
|
|
4
|
+
"GPTBot",
|
|
5
|
+
"ClaudeBot",
|
|
6
|
+
"CCBot",
|
|
7
|
+
"Google-Extended",
|
|
8
|
+
"Applebot-Extended",
|
|
9
|
+
"Meta-ExternalAgent",
|
|
10
|
+
"Bytespider",
|
|
11
|
+
"cohere-training-data-crawler"
|
|
12
|
+
],
|
|
13
|
+
search: [
|
|
14
|
+
"OAI-SearchBot",
|
|
15
|
+
"ChatGPT-User",
|
|
16
|
+
"Claude-SearchBot",
|
|
17
|
+
"Claude-User",
|
|
18
|
+
"PerplexityBot",
|
|
19
|
+
"Perplexity-User"
|
|
20
|
+
]
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// src/shared/htmlScan.ts
|
|
24
|
+
var isSpace = (c) => c === 32 || c === 9 || c === 10 || c === 12 || c === 13;
|
|
25
|
+
var isAlpha = (c) => c >= 65 && c <= 90 || c >= 97 && c <= 122;
|
|
26
|
+
function findRawEnd(html, name, from) {
|
|
27
|
+
let i = html.indexOf("</", from);
|
|
28
|
+
while (i !== -1) {
|
|
29
|
+
if (html.slice(i + 2, i + 2 + name.length).toLowerCase() === name) return i;
|
|
30
|
+
i = html.indexOf("</", i + 2);
|
|
31
|
+
}
|
|
32
|
+
return -1;
|
|
33
|
+
}
|
|
34
|
+
function* scanHtml(html, rawText) {
|
|
35
|
+
const n = html.length;
|
|
36
|
+
let i = 0;
|
|
37
|
+
while (i < n) {
|
|
38
|
+
const lt = html.indexOf("<", i);
|
|
39
|
+
if (lt === -1) return;
|
|
40
|
+
const c1 = lt + 1 < n ? html.charCodeAt(lt + 1) : 0;
|
|
41
|
+
if (c1 === 33 || c1 === 63) {
|
|
42
|
+
let end;
|
|
43
|
+
if (html.startsWith("<!--", lt)) {
|
|
44
|
+
const close = html.indexOf("-->", lt + 4);
|
|
45
|
+
end = close === -1 ? n : close + 3;
|
|
46
|
+
} else {
|
|
47
|
+
const close = html.indexOf(">", lt + 2);
|
|
48
|
+
end = close === -1 ? n : close + 1;
|
|
49
|
+
}
|
|
50
|
+
yield { type: "comment", start: lt, end };
|
|
51
|
+
i = end;
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
const closing = c1 === 47;
|
|
55
|
+
const nameStart = lt + (closing ? 2 : 1);
|
|
56
|
+
if (!isAlpha(nameStart < n ? html.charCodeAt(nameStart) : 0)) {
|
|
57
|
+
i = lt + 1;
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
let p = nameStart;
|
|
61
|
+
while (p < n) {
|
|
62
|
+
const c = html.charCodeAt(p);
|
|
63
|
+
if (isSpace(c) || c === 62 || c === 47) break;
|
|
64
|
+
p++;
|
|
65
|
+
}
|
|
66
|
+
const name = html.slice(nameStart, p).toLowerCase();
|
|
67
|
+
const attrs = [];
|
|
68
|
+
let selfClosing = false;
|
|
69
|
+
while (p < n) {
|
|
70
|
+
const c = html.charCodeAt(p);
|
|
71
|
+
if (isSpace(c)) {
|
|
72
|
+
p++;
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (c === 62) {
|
|
76
|
+
p++;
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
if (c === 47) {
|
|
80
|
+
selfClosing = p + 1 < n && html.charCodeAt(p + 1) === 62;
|
|
81
|
+
p++;
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
const as = p;
|
|
85
|
+
while (p < n) {
|
|
86
|
+
const d = html.charCodeAt(p);
|
|
87
|
+
if (isSpace(d) || d === 62 || d === 47 || d === 61) break;
|
|
88
|
+
p++;
|
|
89
|
+
}
|
|
90
|
+
if (p === as) {
|
|
91
|
+
p++;
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
const attr = { name: html.slice(as, p).toLowerCase(), value: "", valueStart: -1, valueEnd: -1, quote: "" };
|
|
95
|
+
while (p < n && isSpace(html.charCodeAt(p))) p++;
|
|
96
|
+
if (p < n && html.charCodeAt(p) === 61) {
|
|
97
|
+
p++;
|
|
98
|
+
while (p < n && isSpace(html.charCodeAt(p))) p++;
|
|
99
|
+
const q = p < n ? html[p] : "";
|
|
100
|
+
if (q === '"' || q === "'") {
|
|
101
|
+
const close = html.indexOf(q, p + 1);
|
|
102
|
+
const stop = close === -1 ? n : close;
|
|
103
|
+
Object.assign(attr, { value: html.slice(p + 1, stop), valueStart: p + 1, valueEnd: stop, quote: q });
|
|
104
|
+
p = close === -1 ? n : close + 1;
|
|
105
|
+
} else {
|
|
106
|
+
const vs = p;
|
|
107
|
+
while (p < n && !isSpace(html.charCodeAt(p)) && html.charCodeAt(p) !== 62) p++;
|
|
108
|
+
Object.assign(attr, { value: html.slice(vs, p), valueStart: vs, valueEnd: p });
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
attrs.push(attr);
|
|
112
|
+
}
|
|
113
|
+
yield { type: "tag", closing, name, attrs, selfClosing, start: lt, end: p };
|
|
114
|
+
i = p;
|
|
115
|
+
if (!closing && !selfClosing && rawText.has(name)) {
|
|
116
|
+
const end = findRawEnd(html, name, i);
|
|
117
|
+
const stop = end === -1 ? n : end;
|
|
118
|
+
yield { type: "raw", name, start: i, end: stop };
|
|
119
|
+
i = stop;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export {
|
|
125
|
+
AI_BOTS,
|
|
126
|
+
scanHtml
|
|
127
|
+
};
|
|
@@ -47,6 +47,7 @@ var PRERENDERED_ATTR = "data-wfa-prerendered";
|
|
|
47
47
|
var READY_GLOBAL = "__WFA_READY__";
|
|
48
48
|
var HIDDEN_SELECTOR = '[hidden], [aria-hidden="true"]';
|
|
49
49
|
var HEAD_OWNED_ATTR = "data-wfa";
|
|
50
|
+
var MARKDOWN_LINK_KEY = "markdown";
|
|
50
51
|
function markdownPathFor(pathname) {
|
|
51
52
|
const p = normalizeRoute(pathname);
|
|
52
53
|
return p === "/" ? "/index.md" : p + ".md";
|
|
@@ -81,6 +82,7 @@ export {
|
|
|
81
82
|
READY_GLOBAL,
|
|
82
83
|
HIDDEN_SELECTOR,
|
|
83
84
|
HEAD_OWNED_ATTR,
|
|
85
|
+
MARKDOWN_LINK_KEY,
|
|
84
86
|
markdownPathFor,
|
|
85
87
|
ACTION_ATTR,
|
|
86
88
|
ACTION_DESCRIPTION_ATTR,
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import {
|
|
2
|
+
collapseWhitespace
|
|
3
|
+
} from "./chunk-FEAKVNMG.js";
|
|
4
|
+
import {
|
|
5
|
+
ACTION_PARAM_ATTR,
|
|
6
|
+
HIDDEN_SELECTOR,
|
|
7
|
+
WEBMCP_TOOLPARAMDESCRIPTION_ATTR
|
|
8
|
+
} from "./chunk-F7PN5R25.js";
|
|
9
|
+
|
|
10
|
+
// src/shared/object.ts
|
|
11
|
+
var hasOwn = (o, k) => Object.prototype.hasOwnProperty.call(o, k);
|
|
12
|
+
|
|
13
|
+
// src/runtime/agent/dom.ts
|
|
14
|
+
var INERT_OR_CLOSED = "[inert], dialog:not([open]), details:not([open]) > :not(summary)";
|
|
15
|
+
var CONCEALED = `${HIDDEN_SELECTOR}, ${INERT_OR_CLOSED}`;
|
|
16
|
+
function inDisabledFieldset(el) {
|
|
17
|
+
for (let child = el, p = el.parentElement; p; child = p, p = p.parentElement) {
|
|
18
|
+
if (p.matches("fieldset[disabled]") && child !== p.querySelector(":scope > legend")) return true;
|
|
19
|
+
}
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
function isDisabled(el) {
|
|
23
|
+
return el.hasAttribute("disabled") || el.getAttribute("aria-disabled") === "true" || inDisabledFieldset(el);
|
|
24
|
+
}
|
|
25
|
+
function isConcealed(el) {
|
|
26
|
+
if (!el.closest(CONCEALED)) return false;
|
|
27
|
+
const labels = el.tagName === "INPUT" && /^(checkbox|radio)$/.test(el.type) ? el.labels : null;
|
|
28
|
+
return !(labels && el.getAttribute("aria-hidden") !== "true" && !el.matches(INERT_OR_CLOSED) && !el.parentElement?.closest(CONCEALED) && Array.from(labels).some((l) => !isConcealed(l) && !isDisabled(l)));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// src/runtime/agent/formSchema.ts
|
|
32
|
+
var EMPTY_OBJECT_SCHEMA = Object.freeze({
|
|
33
|
+
type: "object",
|
|
34
|
+
properties: Object.freeze({}),
|
|
35
|
+
additionalProperties: false
|
|
36
|
+
});
|
|
37
|
+
var EXCLUDED_TYPES = /* @__PURE__ */ new Set(["hidden", "password", "file", "submit", "button", "reset", "image"]);
|
|
38
|
+
function isAgentField(e) {
|
|
39
|
+
const tag = e.tagName;
|
|
40
|
+
if (tag !== "INPUT" && tag !== "SELECT" && tag !== "TEXTAREA") return false;
|
|
41
|
+
if (!e.getAttribute("name")) return false;
|
|
42
|
+
if (e.hasAttribute("disabled") || e.hasAttribute("readonly") || inDisabledFieldset(e)) return false;
|
|
43
|
+
if (tag === "INPUT" && EXCLUDED_TYPES.has((e.getAttribute("type") ?? "text").toLowerCase())) return false;
|
|
44
|
+
return !isConcealed(e);
|
|
45
|
+
}
|
|
46
|
+
function agentFields(form) {
|
|
47
|
+
const groups = /* @__PURE__ */ new Map();
|
|
48
|
+
for (const el of Array.from(form.elements)) {
|
|
49
|
+
if (!isAgentField(el)) continue;
|
|
50
|
+
const name = el.getAttribute("name");
|
|
51
|
+
const list = groups.get(name);
|
|
52
|
+
if (list) list.push(el);
|
|
53
|
+
else groups.set(name, [el]);
|
|
54
|
+
}
|
|
55
|
+
return groups;
|
|
56
|
+
}
|
|
57
|
+
function labelText(el) {
|
|
58
|
+
const labels = el.labels ? Array.from(el.labels) : [];
|
|
59
|
+
if (labels.length === 0) {
|
|
60
|
+
const wrap = el.closest("label");
|
|
61
|
+
if (wrap) labels.push(wrap);
|
|
62
|
+
}
|
|
63
|
+
return collapseWhitespace(
|
|
64
|
+
labels.map((l) => {
|
|
65
|
+
const c = l.cloneNode(true);
|
|
66
|
+
c.querySelectorAll("input,select,textarea,button").forEach((n) => n.remove());
|
|
67
|
+
return c.textContent;
|
|
68
|
+
}).join(" ")
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
function describe(el) {
|
|
72
|
+
return collapseWhitespace(el.getAttribute(ACTION_PARAM_ATTR)) || collapseWhitespace(el.getAttribute(WEBMCP_TOOLPARAMDESCRIPTION_ATTR)) || labelText(el) || collapseWhitespace(el.getAttribute("aria-label")) || collapseWhitespace(el.getAttribute("placeholder"));
|
|
73
|
+
}
|
|
74
|
+
function num(el, attr) {
|
|
75
|
+
const v = el.getAttribute(attr);
|
|
76
|
+
if (v === null || v.trim() === "") return void 0;
|
|
77
|
+
const n = Number(v);
|
|
78
|
+
return Number.isFinite(n) ? n : void 0;
|
|
79
|
+
}
|
|
80
|
+
function inputSchema(el) {
|
|
81
|
+
const type = el.tagName === "TEXTAREA" ? "textarea" : (el.getAttribute("type") ?? "text").toLowerCase();
|
|
82
|
+
const s = {};
|
|
83
|
+
if (type === "checkbox") {
|
|
84
|
+
s.type = "boolean";
|
|
85
|
+
return s;
|
|
86
|
+
}
|
|
87
|
+
if (type === "number" || type === "range") {
|
|
88
|
+
const step = el.getAttribute("step");
|
|
89
|
+
s.type = step === null || /^\d+$/.test(step.trim()) ? "integer" : "number";
|
|
90
|
+
const min = num(el, "min");
|
|
91
|
+
const max = num(el, "max");
|
|
92
|
+
if (min !== void 0) s.minimum = min;
|
|
93
|
+
if (max !== void 0) s.maximum = max;
|
|
94
|
+
return s;
|
|
95
|
+
}
|
|
96
|
+
s.type = "string";
|
|
97
|
+
if (type === "email") s.format = "email";
|
|
98
|
+
else if (type === "url") s.format = "uri";
|
|
99
|
+
else if (type === "date") s.format = "date";
|
|
100
|
+
else if (type === "time") s.format = "time";
|
|
101
|
+
const minLength = num(el, "minlength");
|
|
102
|
+
const maxLength = num(el, "maxlength");
|
|
103
|
+
if (minLength !== void 0) s.minLength = minLength;
|
|
104
|
+
if (maxLength !== void 0) s.maxLength = maxLength;
|
|
105
|
+
const pattern = el.getAttribute("pattern");
|
|
106
|
+
if (pattern) s.pattern = `^(?:${pattern})$`;
|
|
107
|
+
return s;
|
|
108
|
+
}
|
|
109
|
+
function withDescription(s, desc) {
|
|
110
|
+
if (desc) s.description = desc;
|
|
111
|
+
return s;
|
|
112
|
+
}
|
|
113
|
+
function selectSchema(sel, desc) {
|
|
114
|
+
const opts = Array.from(sel.querySelectorAll("option")).filter((o) => !o.hasAttribute("disabled") && !o.hasAttribute("hidden") && !o.closest("optgroup[disabled]")).map((o) => ({ value: o.getAttribute("value") ?? collapseWhitespace(o.textContent), label: collapseWhitespace(o.textContent) })).filter((o) => o.value !== "");
|
|
115
|
+
const values = opts.map((o) => o.value);
|
|
116
|
+
const list = opts.map((o) => o.label && o.label !== o.value ? `${o.value} (${o.label})` : o.value).join(", ");
|
|
117
|
+
const schema = sel.hasAttribute("multiple") ? { type: "array", items: { type: "string", enum: values } } : { type: "string", enum: values };
|
|
118
|
+
return withDescription(schema, [desc, `Options: ${list}`].filter(Boolean).join(". "));
|
|
119
|
+
}
|
|
120
|
+
var isType = (e, t) => e.tagName === "INPUT" && (e.getAttribute("type") ?? "").toLowerCase() === t;
|
|
121
|
+
function groupSchema(els) {
|
|
122
|
+
const first = els[0];
|
|
123
|
+
const desc = els.map(describe).find(Boolean) ?? "";
|
|
124
|
+
if (first.tagName === "SELECT") return selectSchema(first, desc);
|
|
125
|
+
const values = () => els.map((e) => e.getAttribute("value") ?? "on");
|
|
126
|
+
if (els.every((e) => isType(e, "radio"))) return withDescription({ type: "string", enum: values() }, desc);
|
|
127
|
+
if (els.length > 1 && els.every((e) => isType(e, "checkbox"))) {
|
|
128
|
+
return withDescription({ type: "array", items: { type: "string", enum: values() } }, desc);
|
|
129
|
+
}
|
|
130
|
+
return withDescription(inputSchema(first), desc);
|
|
131
|
+
}
|
|
132
|
+
function schemaFromForm(form) {
|
|
133
|
+
const properties = /* @__PURE__ */ Object.create(null);
|
|
134
|
+
const required = [];
|
|
135
|
+
for (const [name, els] of agentFields(form)) {
|
|
136
|
+
properties[name] = groupSchema(els);
|
|
137
|
+
if (els.some((e) => e.hasAttribute("required"))) required.push(name);
|
|
138
|
+
}
|
|
139
|
+
const out = { type: "object", properties, additionalProperties: false };
|
|
140
|
+
if (required.length) out.required = required;
|
|
141
|
+
return out;
|
|
142
|
+
}
|
|
143
|
+
var MAX_REGEX_INPUT = 1e4;
|
|
144
|
+
function checkValue(s, v, field, errors) {
|
|
145
|
+
const bad = (message) => {
|
|
146
|
+
errors.push({ field, message });
|
|
147
|
+
};
|
|
148
|
+
switch (s.type) {
|
|
149
|
+
case "string":
|
|
150
|
+
if (typeof v !== "string") return bad("must be string");
|
|
151
|
+
break;
|
|
152
|
+
case "number":
|
|
153
|
+
if (typeof v !== "number" || !Number.isFinite(v)) return bad("must be number");
|
|
154
|
+
break;
|
|
155
|
+
case "integer":
|
|
156
|
+
if (typeof v !== "number" || !Number.isInteger(v)) return bad("must be integer");
|
|
157
|
+
break;
|
|
158
|
+
case "boolean":
|
|
159
|
+
if (typeof v !== "boolean") return bad("must be boolean");
|
|
160
|
+
break;
|
|
161
|
+
case "array":
|
|
162
|
+
if (!Array.isArray(v)) return bad("must be array");
|
|
163
|
+
break;
|
|
164
|
+
case "object":
|
|
165
|
+
if (!isPlainObject(v)) return bad("must be object");
|
|
166
|
+
checkObject(s, v, `${field}.`, errors);
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
if (s.enum && !s.enum.includes(v)) {
|
|
170
|
+
return bad(`must be one of: ${s.enum.join(", ")}`);
|
|
171
|
+
}
|
|
172
|
+
if (typeof v === "string") {
|
|
173
|
+
if (s.minLength !== void 0 && v.length < s.minLength) bad(`must be at least ${s.minLength} characters`);
|
|
174
|
+
if (s.maxLength !== void 0 && v.length > s.maxLength) bad(`must be at most ${s.maxLength} characters`);
|
|
175
|
+
if ((s.pattern !== void 0 || s.format === "email") && v.length > MAX_REGEX_INPUT) {
|
|
176
|
+
return bad(`must be at most ${MAX_REGEX_INPUT} characters to be checked`);
|
|
177
|
+
}
|
|
178
|
+
if (s.pattern !== void 0) {
|
|
179
|
+
let ok = false;
|
|
180
|
+
try {
|
|
181
|
+
ok = new RegExp(s.pattern).test(v);
|
|
182
|
+
} catch {
|
|
183
|
+
ok = false;
|
|
184
|
+
}
|
|
185
|
+
if (!ok) bad(`must match pattern ${s.pattern}`);
|
|
186
|
+
}
|
|
187
|
+
if (s.format === "email" && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v)) bad("must be a valid email");
|
|
188
|
+
if (s.format === "uri") {
|
|
189
|
+
try {
|
|
190
|
+
new URL(v);
|
|
191
|
+
} catch {
|
|
192
|
+
bad("must be a valid URI");
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
if (typeof v === "number") {
|
|
197
|
+
if (s.minimum !== void 0 && v < s.minimum) bad(`must be >= ${s.minimum}`);
|
|
198
|
+
if (s.maximum !== void 0 && v > s.maximum) bad(`must be <= ${s.maximum}`);
|
|
199
|
+
}
|
|
200
|
+
if (Array.isArray(v) && s.items) {
|
|
201
|
+
v.forEach((item, i) => checkValue(s.items, item, `${field}[${i}]`, errors));
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
function isPlainObject(v) {
|
|
205
|
+
if (typeof v !== "object" || v === null) return false;
|
|
206
|
+
const proto = Object.getPrototypeOf(v);
|
|
207
|
+
return proto === Object.prototype || proto === null;
|
|
208
|
+
}
|
|
209
|
+
function checkObject(schema, obj, prefix, errors) {
|
|
210
|
+
const props = schema.properties ?? {};
|
|
211
|
+
for (const name of schema.required ?? []) {
|
|
212
|
+
if (!hasOwn(obj, name) || obj[name] === void 0) errors.push({ field: prefix + name, message: "is required" });
|
|
213
|
+
}
|
|
214
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
215
|
+
const prop = props[key];
|
|
216
|
+
if (!hasOwn(props, key) || !prop) {
|
|
217
|
+
if (schema.additionalProperties !== true) errors.push({ field: prefix + key, message: "is not an allowed field" });
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
if (value === void 0) continue;
|
|
221
|
+
checkValue(prop, value, prefix + key, errors);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
function validateInput(schema, input) {
|
|
225
|
+
if (!isPlainObject(input)) return { ok: false, errors: [{ field: "", message: "input must be an object" }] };
|
|
226
|
+
const errors = [];
|
|
227
|
+
checkObject(schema, input, "", errors);
|
|
228
|
+
return errors.length ? { ok: false, errors } : { ok: true, value: input };
|
|
229
|
+
}
|
|
230
|
+
function validateFormInput(schema, input) {
|
|
231
|
+
const r = validateInput({ ...schema, additionalProperties: true }, input);
|
|
232
|
+
return r.ok ? r : validateInput(schema, input);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export {
|
|
236
|
+
hasOwn,
|
|
237
|
+
inDisabledFieldset,
|
|
238
|
+
isDisabled,
|
|
239
|
+
isConcealed,
|
|
240
|
+
EMPTY_OBJECT_SCHEMA,
|
|
241
|
+
agentFields,
|
|
242
|
+
schemaFromForm,
|
|
243
|
+
validateInput,
|
|
244
|
+
validateFormInput
|
|
245
|
+
};
|