@xano/xanoscript-language-server 12.18.0 → 12.20.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/lexer/mcp.js +26 -1
- package/onHover/functions.md +45 -0
- package/package.json +1 -1
- package/parser/functions/api/apiCallFn.js +4 -0
- package/parser/functions/mcp/mcpOauthFn.js +140 -0
- package/parser/functions/mcp/register.js +10 -0
- package/parser/functions/mcpFn.js +2 -1
- package/parser/mcp_server_parser.js +48 -1
- package/parser/policy/catalogue.js +1 -1
- package/parser/policy/catalogueSnapshot.js +3613 -2167
- package/parser/policy/policyDocs.js +29 -0
- package/parser/policy/validatePolicyRule.js +18 -0
|
@@ -43,10 +43,39 @@ export function checkMarkdown(check, catalogue) {
|
|
|
43
43
|
if (applicable.length) {
|
|
44
44
|
lines.push("", `Scope fields: ${applicable.map(code).join(", ")}.`);
|
|
45
45
|
}
|
|
46
|
+
const uses = useLines(check.uses);
|
|
47
|
+
if (uses.length) lines.push("", "Uses:", ...uses);
|
|
46
48
|
if (check.fix_hint) lines.push("", `Fix: ${check.fix_hint}`);
|
|
47
49
|
return lines.join("\n");
|
|
48
50
|
}
|
|
49
51
|
|
|
52
|
+
/**
|
|
53
|
+
* A check's `uses` as a list: each goal, then the `params = { ... }` line that achieves it, written
|
|
54
|
+
* as a rule writes it, then its note when it has one.
|
|
55
|
+
*/
|
|
56
|
+
function useLines(uses) {
|
|
57
|
+
if (!Array.isArray(uses)) return [];
|
|
58
|
+
return uses
|
|
59
|
+
.filter((use) => typeof use?.goal === "string" && use.goal !== "")
|
|
60
|
+
.flatMap((use) => [
|
|
61
|
+
`- ${use.goal}`,
|
|
62
|
+
` ${code(`params = ${policyValue(Array.isArray(use.params) ? {} : (use.params ?? {}))}`)}`,
|
|
63
|
+
...(typeof use.note === "string" && use.note !== "" ? [` ${use.note}`] : []),
|
|
64
|
+
]);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** A value as a policy file writes it: `{ key: value }` with bare keys, JSON strings and lists. */
|
|
68
|
+
function policyValue(value) {
|
|
69
|
+
if (Array.isArray(value)) return `[${value.map(policyValue).join(", ")}]`;
|
|
70
|
+
if (value && typeof value === "object") {
|
|
71
|
+
const entries = Object.entries(value);
|
|
72
|
+
if (!entries.length) return "{}";
|
|
73
|
+
const key = (name) => (/^[A-Za-z_][A-Za-z0-9_]*$/.test(name) ? name : JSON.stringify(name));
|
|
74
|
+
return `{ ${entries.map(([name, item]) => `${key(name)}: ${policyValue(item)}`).join(", ")} }`;
|
|
75
|
+
}
|
|
76
|
+
return JSON.stringify(value) ?? "null";
|
|
77
|
+
}
|
|
78
|
+
|
|
50
79
|
/**
|
|
51
80
|
* @param {string} checkId
|
|
52
81
|
* @param {string} path the param name, or `name.field` for a field of an object param
|
|
@@ -124,6 +124,10 @@ function coerce(node, spec, checkId, name) {
|
|
|
124
124
|
if (!whole || (minimum !== undefined && node.value < minimum)) {
|
|
125
125
|
return fail(`be a whole number${minimum !== undefined ? ` of at least ${minimum}` : ""}`);
|
|
126
126
|
}
|
|
127
|
+
// `Registry::INTEGER_MAX`: past 2^53 - 1 a whole number is no longer exact.
|
|
128
|
+
if (Math.abs(node.value) > Number.MAX_SAFE_INTEGER) {
|
|
129
|
+
return fail(`be a whole number no larger than ${Number.MAX_SAFE_INTEGER}`);
|
|
130
|
+
}
|
|
127
131
|
return null;
|
|
128
132
|
}
|
|
129
133
|
case "number":
|
|
@@ -319,5 +323,19 @@ export function validatePolicyRule(rule, catalogue) {
|
|
|
319
323
|
}
|
|
320
324
|
}
|
|
321
325
|
|
|
326
|
+
// A param set for a value of the check's kind param it does not apply to (`applies_when` on the
|
|
327
|
+
// param: object.naming's version_required applies to name_kind endpoint_path only). The platform
|
|
328
|
+
// refuses it on save.
|
|
329
|
+
for (const [name, entry] of given) {
|
|
330
|
+
const conditions = Object.hasOwn(schema, name) ? schema[name]?.applies_when : null;
|
|
331
|
+
if (!conditions || catalogue.scopeFields?.has(name) || !provided(literal[name])) continue;
|
|
332
|
+
for (const [param, values] of Object.entries(conditions)) {
|
|
333
|
+
if (Array.isArray(values) && !values.includes(String(inForce(literal, schema, param) ?? ""))) {
|
|
334
|
+
advise(entry.keyToken, `check "${id}": ${name} applies only when ${param} is ${values.join(", ").replace(/, ([^,]*)$/, " or $1")}.`);
|
|
335
|
+
break;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
322
340
|
return out;
|
|
323
341
|
}
|