@mcp-b/webmcp-polyfill 4.0.0 → 5.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/dist/schema.js CHANGED
@@ -1,14 +1,47 @@
1
- import { Validator } from "@cfworker/json-schema";
2
-
3
1
  //#region src/schema.ts
4
2
  const DEFAULT_INPUT_SCHEMA = {
5
3
  type: "object",
6
4
  properties: {}
7
5
  };
6
+ const FAILED_TO_PARSE_INPUT_ARGUMENTS_MESSAGE = "Failed to parse input arguments";
7
+ const TOOL_INVOCATION_FAILED_MESSAGE = "Tool was executed but the invocation failed. For example, the script function threw an error";
8
8
  const STANDARD_JSON_SCHEMA_TARGETS = ["draft-2020-12", "draft-07"];
9
+ const VALID_TOOL_NAME_RE = /^[A-Za-z0-9_.-]{1,128}$/u;
9
10
  function isPlainObject(value) {
10
11
  return typeof value === "object" && value !== null && !Array.isArray(value);
11
12
  }
13
+ function toDomString(value) {
14
+ if (typeof value === "symbol") throw new TypeError("Symbol values cannot be converted to a DOMString");
15
+ return String(value);
16
+ }
17
+ function coerceWebMcpToolDescriptor(tool) {
18
+ const name = Reflect.get(tool, "name");
19
+ const description = Reflect.get(tool, "description");
20
+ const title = Reflect.get(tool, "title");
21
+ if (name === void 0) throw new TypeError("Tool \"name\" is required");
22
+ if (description === void 0) throw new TypeError("Tool \"description\" is required");
23
+ const annotations = Reflect.get(tool, "annotations");
24
+ const annotationMembers = isPlainObject(annotations) ? annotations : {};
25
+ const inputSchema = Reflect.get(tool, "inputSchema");
26
+ const outputSchema = Reflect.get(tool, "outputSchema");
27
+ const execute = Reflect.get(tool, "execute");
28
+ return {
29
+ name: toDomString(name),
30
+ ...title === void 0 ? {} : { title: toDomString(title).toWellFormed() },
31
+ description: toDomString(description),
32
+ ...inputSchema === void 0 ? {} : { inputSchema },
33
+ ...outputSchema === void 0 ? {} : { outputSchema },
34
+ execute,
35
+ ...annotations === void 0 ? {} : { annotations: {
36
+ ...annotationMembers.title === void 0 ? {} : { title: toDomString(annotationMembers.title).toWellFormed() },
37
+ readOnlyHint: Boolean(annotationMembers.readOnlyHint),
38
+ ...annotationMembers.destructiveHint === void 0 ? {} : { destructiveHint: Boolean(annotationMembers.destructiveHint) },
39
+ ...annotationMembers.idempotentHint === void 0 ? {} : { idempotentHint: Boolean(annotationMembers.idempotentHint) },
40
+ ...annotationMembers.openWorldHint === void 0 ? {} : { openWorldHint: Boolean(annotationMembers.openWorldHint) },
41
+ untrustedContentHint: Boolean(annotationMembers.untrustedContentHint)
42
+ } }
43
+ };
44
+ }
12
45
  function isJsonObjectRecord(value) {
13
46
  if (!isPlainObject(value)) return false;
14
47
  const prototype = Object.getPrototypeOf(value);
@@ -31,6 +64,148 @@ function isJsonValue(value, seen = /* @__PURE__ */ new WeakSet()) {
31
64
  function toJsonValue(value) {
32
65
  return isJsonValue(value) ? value : void 0;
33
66
  }
67
+ function hasCallToolResultShape(value) {
68
+ return isPlainObject(value) && Array.isArray(value.content);
69
+ }
70
+ function serializeTextContent(value) {
71
+ if (typeof value === "string") return value;
72
+ try {
73
+ return JSON.stringify(value) ?? String(value);
74
+ } catch {
75
+ return String(value);
76
+ }
77
+ }
78
+ function normalizeToolResponse(value) {
79
+ if (hasCallToolResultShape(value)) return value;
80
+ const structuredContent = toJsonValue(value);
81
+ return {
82
+ content: [{
83
+ type: "text",
84
+ text: serializeTextContent(value)
85
+ }],
86
+ ...structuredContent === void 0 ? {} : { structuredContent },
87
+ isError: false
88
+ };
89
+ }
90
+ function createUnknownError(message) {
91
+ return new DOMException(message, "UnknownError");
92
+ }
93
+ function createToolInvocationFailedError(error) {
94
+ return createUnknownError(error instanceof Error ? `${TOOL_INVOCATION_FAILED_MESSAGE}: ${error.message}` : TOOL_INVOCATION_FAILED_MESSAGE);
95
+ }
96
+ function createInvalidStateError(message) {
97
+ return new DOMException(message, "InvalidStateError");
98
+ }
99
+ function validateWebMcpToolDescriptor(tool) {
100
+ if (tool.name === "") throw createInvalidStateError("Tool \"name\" must be a non-empty string");
101
+ if (typeof tool.name !== "string" || !VALID_TOOL_NAME_RE.test(tool.name)) throw createInvalidStateError("Tool \"name\" must be 1–128 characters and contain only ASCII alphanumeric, underscore, hyphen, or period");
102
+ if (typeof tool.description !== "string" || tool.description.length === 0) throw createInvalidStateError("Tool \"description\" must be a non-empty string");
103
+ if (typeof tool.execute !== "function") throw new TypeError("Tool \"execute\" must be a function");
104
+ }
105
+ function toWebMcpAnnotations(annotations) {
106
+ return {
107
+ readOnlyHint: annotations.readOnlyHint ?? false,
108
+ untrustedContentHint: annotations.untrustedContentHint ?? false
109
+ };
110
+ }
111
+ function parseChromeToolInput(input) {
112
+ try {
113
+ const value = JSON.parse(input);
114
+ if (Array.isArray(value) || isPlainObject(value)) return value;
115
+ } catch {}
116
+ throw createUnknownError(FAILED_TO_PARSE_INPUT_ARGUMENTS_MESSAGE);
117
+ }
118
+ function serializeChromeToolResult(value) {
119
+ if (typeof value === "object" && value !== null || typeof value === "function") try {
120
+ const serialized = JSON.stringify(value);
121
+ if (serialized) return serialized;
122
+ } catch {}
123
+ return String(value) || "Operation succeeded";
124
+ }
125
+ function withAbortSignal(operation, signal, getAbortReason = () => signal?.reason) {
126
+ if (!signal) return operation;
127
+ if (signal.aborted) return Promise.reject(getAbortReason());
128
+ return new Promise((resolve, reject) => {
129
+ const onAbort = () => {
130
+ cleanup();
131
+ reject(getAbortReason());
132
+ };
133
+ const cleanup = () => signal.removeEventListener("abort", onAbort);
134
+ signal.addEventListener("abort", onAbort, { once: true });
135
+ operation.then((value) => {
136
+ cleanup();
137
+ resolve(value);
138
+ }, (error) => {
139
+ cleanup();
140
+ reject(error);
141
+ });
142
+ });
143
+ }
144
+ function isPotentiallyTrustworthyOrigin(url) {
145
+ const originUrl = url.origin === "null" ? url : new URL(url.origin);
146
+ const protocol = originUrl.protocol;
147
+ if ([
148
+ "https:",
149
+ "wss:",
150
+ "file:",
151
+ "chrome-extension:",
152
+ "moz-extension:"
153
+ ].includes(protocol)) return true;
154
+ const hostname = originUrl.hostname.toLowerCase();
155
+ const ipv4 = hostname.split(".");
156
+ const isLoopbackIpv4 = ipv4.length === 4 && ipv4.every((part) => /^\d{1,3}$/u.test(part) && Number(part) <= 255) && Number(ipv4[0]) === 127;
157
+ return hostname === "::1" || hostname === "[::1]" || hostname === "localhost" || hostname === "localhost." || hostname.endsWith(".localhost") || hostname.endsWith(".localhost.") || isLoopbackIpv4;
158
+ }
159
+ function validatePotentiallyTrustworthyOrigins(origins) {
160
+ for (const origin of origins ?? []) {
161
+ let parsed;
162
+ try {
163
+ parsed = new URL(origin);
164
+ } catch {
165
+ throw new DOMException(`Invalid or untrustworthy origin: ${String(origin)}`, "SecurityError");
166
+ }
167
+ if (!isPotentiallyTrustworthyOrigin(parsed)) throw new DOMException(`Invalid or untrustworthy origin: ${origin}`, "SecurityError");
168
+ }
169
+ }
170
+ function validateWebMcpAccess(ownerDocument) {
171
+ validateOriginAgentCluster();
172
+ if (!ownerDocument) return;
173
+ const DOMExceptionConstructor = ownerDocument.defaultView?.DOMException ?? DOMException;
174
+ let fullyActive = false;
175
+ try {
176
+ const ownerWindow = ownerDocument.defaultView;
177
+ fullyActive = Boolean(ownerWindow && ownerWindow.document === ownerDocument);
178
+ } catch {}
179
+ if (!fullyActive) throw new DOMExceptionConstructor("The associated document is not fully active", "InvalidStateError");
180
+ const policy = Reflect.get(ownerDocument, "permissionsPolicy") ?? Reflect.get(ownerDocument, "featurePolicy");
181
+ if (policy && typeof policy === "object") {
182
+ const features = Reflect.get(policy, "features");
183
+ const allowsFeature = Reflect.get(policy, "allowsFeature");
184
+ if (typeof features === "function" && typeof allowsFeature === "function") {
185
+ const supported = Reflect.apply(features, policy, []);
186
+ if (Array.isArray(supported) && supported.includes("tools")) {
187
+ if (Reflect.apply(allowsFeature, policy, ["tools"]) === true) return;
188
+ throw new DOMExceptionConstructor("WebMCP is disabled by Permissions Policy", "NotAllowedError");
189
+ }
190
+ }
191
+ }
192
+ const ownerWindow = ownerDocument.defaultView;
193
+ if (!ownerWindow || ownerWindow.parent === ownerWindow) return;
194
+ try {
195
+ ownerWindow.parent.document;
196
+ return;
197
+ } catch {}
198
+ throw new DOMExceptionConstructor("WebMCP in cross-origin frames requires native Permissions Policy support", "NotAllowedError");
199
+ }
200
+ function validateOriginAgentCluster() {
201
+ if (globalThis.originAgentCluster === false && globalThis.location?.protocol !== "file:") throw new DOMException("", "SecurityError");
202
+ }
203
+ function validateExecutableOrigin(origin) {
204
+ try {
205
+ if (new URL(String(origin)).origin !== "null") return;
206
+ } catch {}
207
+ throw new DOMException(`Unsupported tool origin: ${String(origin)}`, "NotSupportedError");
208
+ }
34
209
  function getStandardProps(value) {
35
210
  if (!isPlainObject(value)) return null;
36
211
  const standard = value["~standard"];
@@ -46,122 +221,54 @@ function isStandardInputJsonSchema(value) {
46
221
  if (!standard || standard.version !== 1 || !isPlainObject(standard.jsonSchema)) return false;
47
222
  return typeof standard.jsonSchema.input === "function";
48
223
  }
49
- function createStandardValidatorFromJsonSchema(schema) {
50
- return { "~standard": {
51
- version: 1,
52
- vendor: "@mcp-b/webmcp-polyfill-json-schema",
53
- validate(value) {
54
- if (!isPlainObject(value)) return { issues: [{ message: "expected object arguments" }] };
55
- const issue = validateValueWithSchema(value, schema);
56
- if (issue) return { issues: [issue] };
57
- return { value };
58
- }
59
- } };
224
+ function preserveStandardSchema(inputSchema, standardSchema) {
225
+ const normalized = { ...inputSchema };
226
+ Object.defineProperty(normalized, "~standard", { value: standardSchema["~standard"] });
227
+ return normalized;
60
228
  }
61
229
  function convertStandardInputSchema(schema) {
62
- const failures = [];
63
230
  for (const target of STANDARD_JSON_SCHEMA_TARGETS) try {
64
- const converted = schema["~standard"].jsonSchema.input({ target });
65
- validateInputSchema(converted);
66
- return converted;
67
- } catch (error) {
68
- failures.push({
69
- target,
70
- error
71
- });
72
- }
73
- console.warn("[WebMCPPolyfill] Standard JSON Schema conversion failed:", failures);
231
+ const serialized = serializeInputSchema(schema["~standard"].jsonSchema.input({ target }));
232
+ const parsed = JSON.parse(serialized);
233
+ if (!isPlainObject(parsed)) throw new TypeError("inputSchema must serialize to an object");
234
+ return parsed;
235
+ } catch {}
74
236
  throw new Error("Failed to convert Standard JSON Schema inputSchema to a JSON Schema object");
75
237
  }
76
238
  function normalizeInputSchema(inputSchema) {
77
- if (inputSchema === void 0) {
78
- const normalized = DEFAULT_INPUT_SCHEMA;
79
- return {
80
- inputSchema: normalized,
81
- standardValidator: createStandardValidatorFromJsonSchema(normalized)
82
- };
83
- }
239
+ if (inputSchema === void 0) return { inputSchema: DEFAULT_INPUT_SCHEMA };
84
240
  if (isStandardInputJsonSchema(inputSchema)) {
85
241
  const converted = convertStandardInputSchema(inputSchema);
242
+ const registeredInputSchema = serializeInputSchema(converted);
86
243
  return {
87
- inputSchema: converted,
88
- standardValidator: createStandardValidatorFromJsonSchema(converted)
244
+ inputSchema: isStandardInputValidatorSchema(inputSchema) ? preserveStandardSchema(converted, inputSchema) : converted,
245
+ registeredInputSchema
89
246
  };
90
247
  }
91
- if (isStandardInputValidatorSchema(inputSchema)) return {
92
- inputSchema: DEFAULT_INPUT_SCHEMA,
93
- standardValidator: inputSchema
94
- };
95
- validateInputSchema(inputSchema);
96
- if (Object.keys(inputSchema).length === 0) return {
248
+ if (isStandardInputValidatorSchema(inputSchema)) throw new Error("Standard Schema inputSchema must provide ~standard.jsonSchema.input() for tool metadata");
249
+ if (inputSchema === null || typeof inputSchema !== "object" && typeof inputSchema !== "function") throw new TypeError("inputSchema must be an object");
250
+ const registeredInputSchema = serializeInputSchema(inputSchema);
251
+ const serializedValue = JSON.parse(registeredInputSchema);
252
+ const jsonSchema = isPlainObject(serializedValue) ? serializedValue : void 0;
253
+ if (!jsonSchema || Object.keys(jsonSchema).length === 0) return {
97
254
  inputSchema: DEFAULT_INPUT_SCHEMA,
98
- standardValidator: createStandardValidatorFromJsonSchema(DEFAULT_INPUT_SCHEMA)
255
+ registeredInputSchema
99
256
  };
100
- const normalizedSchema = inputSchema.type === void 0 ? {
101
- type: "object",
102
- ...inputSchema
103
- } : inputSchema;
104
257
  return {
105
- inputSchema: normalizedSchema,
106
- standardValidator: createStandardValidatorFromJsonSchema(normalizedSchema)
258
+ inputSchema: jsonSchema.type === void 0 ? {
259
+ type: "object",
260
+ ...jsonSchema
261
+ } : jsonSchema,
262
+ registeredInputSchema
107
263
  };
108
264
  }
109
- function validateInputSchema(schema) {
110
- if (!isPlainObject(schema)) throw new Error("inputSchema must be a JSON Schema object");
111
- validateJsonSchemaNode(schema, "$");
112
- }
113
- function validateJsonSchemaNode(node, path) {
114
- const typeValue = node.type;
115
- if (typeValue !== void 0 && typeof typeValue !== "string" && !(Array.isArray(typeValue) && typeValue.every((entry) => typeof entry === "string" && entry.length > 0))) throw new Error(`Invalid JSON Schema at ${path}: "type" must be a string or string[]`);
116
- const requiredValue = node.required;
117
- if (requiredValue !== void 0 && !(Array.isArray(requiredValue) && requiredValue.every((entry) => typeof entry === "string"))) throw new Error(`Invalid JSON Schema at ${path}: "required" must be an array of strings`);
118
- const propertiesValue = node.properties;
119
- if (propertiesValue !== void 0) {
120
- if (!isPlainObject(propertiesValue)) throw new Error(`Invalid JSON Schema at ${path}: "properties" must be an object`);
121
- for (const [key, value] of Object.entries(propertiesValue)) {
122
- if (!isPlainObject(value)) throw new Error(`Invalid JSON Schema at ${path}.properties.${key}: expected object schema`);
123
- validateJsonSchemaNode(value, `${path}.properties.${key}`);
124
- }
125
- }
126
- const itemsValue = node.items;
127
- if (itemsValue !== void 0) if (Array.isArray(itemsValue)) for (const [index, value] of itemsValue.entries()) {
128
- if (!isPlainObject(value)) throw new Error(`Invalid JSON Schema at ${path}.items[${index}]: expected object schema`);
129
- validateJsonSchemaNode(value, `${path}.items[${index}]`);
130
- }
131
- else if (isPlainObject(itemsValue)) validateJsonSchemaNode(itemsValue, `${path}.items`);
132
- else throw new Error(`Invalid JSON Schema at ${path}: "items" must be an object or object[]`);
133
- for (const keyword of [
134
- "allOf",
135
- "anyOf",
136
- "oneOf"
137
- ]) {
138
- const value = node[keyword];
139
- if (value === void 0) continue;
140
- if (!Array.isArray(value)) throw new Error(`Invalid JSON Schema at ${path}: "${keyword}" must be an array`);
141
- for (const [index, entry] of value.entries()) {
142
- if (!isPlainObject(entry)) throw new Error(`Invalid JSON Schema at ${path}.${keyword}[${index}]: expected object schema`);
143
- validateJsonSchemaNode(entry, `${path}.${keyword}[${index}]`);
144
- }
145
- }
146
- const notValue = node.not;
147
- if (notValue !== void 0) {
148
- if (!isPlainObject(notValue)) throw new Error(`Invalid JSON Schema at ${path}: "not" must be an object schema`);
149
- validateJsonSchemaNode(notValue, `${path}.not`);
150
- }
151
- try {
152
- JSON.stringify(node);
153
- } catch {
154
- throw new Error(`Invalid JSON Schema at ${path}: schema must be JSON-serializable`);
155
- }
156
- }
157
- function validateValueWithSchema(value, schema) {
158
- const result = new Validator(schema, "2020-12", true).validate(value);
159
- if (result.valid) return null;
160
- const error = result.errors[result.errors.length - 1];
161
- if (!error) return { message: "Input validation failed" };
162
- return { message: error.error };
265
+ function serializeInputSchema(schema) {
266
+ if (schema === null || typeof schema !== "object" && typeof schema !== "function") throw new TypeError("inputSchema must be an object");
267
+ const serialized = JSON.stringify(schema);
268
+ if (serialized === void 0) throw new TypeError("inputSchema must be JSON-serializable");
269
+ return serialized;
163
270
  }
164
271
 
165
272
  //#endregion
166
- export { isPlainObject, normalizeInputSchema, toJsonValue, validateValueWithSchema };
273
+ export { coerceWebMcpToolDescriptor, createInvalidStateError, createToolInvocationFailedError, createUnknownError, isPlainObject, normalizeInputSchema, normalizeToolResponse, parseChromeToolInput, serializeChromeToolResult, serializeInputSchema, toWebMcpAnnotations, validateExecutableOrigin, validateOriginAgentCluster, validatePotentiallyTrustworthyOrigins, validateWebMcpAccess, validateWebMcpToolDescriptor, withAbortSignal };
167
274
  //# sourceMappingURL=schema.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","names":[],"sources":["../src/schema.ts"],"sourcesContent":["import { type Schema, Validator } from '@cfworker/json-schema';\nimport type { InputSchema, JsonSchemaForInference, JsonValue } from '@mcp-b/webmcp-types';\nimport type { StandardJSONSchemaV1, StandardSchemaV1 } from '@standard-schema/spec';\nexport type { StandardJSONSchemaV1 } from '@standard-schema/spec';\n\nconst DEFAULT_INPUT_SCHEMA: InputSchema = { type: 'object', properties: {} };\nconst STANDARD_JSON_SCHEMA_TARGETS = ['draft-2020-12', 'draft-07'] as const;\n\nexport type StandardInputValidatorSchema = StandardSchemaV1<\n Record<string, unknown>,\n Record<string, unknown>\n>;\nexport type StandardInputJsonSchema = StandardJSONSchemaV1<\n Record<string, unknown>,\n Record<string, unknown>\n>;\nexport type ToolInputSchema = InputSchema | StandardInputValidatorSchema | StandardInputJsonSchema;\nexport type ToolOutputSchema = InputSchema | StandardInputJsonSchema;\n\nexport type StandardValidationResult = Awaited<\n ReturnType<StandardInputValidatorSchema['~standard']['validate']>\n>;\nexport type StandardValidationIssue = NonNullable<StandardValidationResult['issues']>[number];\n\nexport interface NormalizedInputSchema {\n inputSchema: InputSchema;\n standardValidator: StandardInputValidatorSchema;\n}\n\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isJsonObjectRecord(value: unknown): value is Record<string, unknown> {\n if (!isPlainObject(value)) {\n return false;\n }\n\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n\nfunction isJsonValue(value: unknown, seen = new WeakSet<object>()): value is JsonValue {\n if (value === null || typeof value === 'string' || typeof value === 'boolean') {\n return true;\n }\n\n if (typeof value === 'number') {\n return Number.isFinite(value);\n }\n\n if (typeof value !== 'object') {\n return false;\n }\n\n if (seen.has(value)) {\n return false;\n }\n\n seen.add(value);\n try {\n const entries = Array.isArray(value)\n ? value\n : isJsonObjectRecord(value)\n ? Object.values(value)\n : null;\n return entries?.every((entry) => isJsonValue(entry, seen)) ?? false;\n } catch {\n return false;\n } finally {\n seen.delete(value);\n }\n}\n\nexport function toJsonValue(value: unknown): JsonValue | undefined {\n return isJsonValue(value) ? value : undefined;\n}\n\nfunction getStandardProps(value: unknown): Record<string, unknown> | null {\n if (!isPlainObject(value)) {\n return null;\n }\n\n const standard = value['~standard'];\n if (!isPlainObject(standard)) {\n return null;\n }\n\n return standard;\n}\n\nfunction isStandardInputValidatorSchema(value: unknown): value is StandardInputValidatorSchema {\n const standard = getStandardProps(value);\n return Boolean(standard && standard.version === 1 && typeof standard.validate === 'function');\n}\n\nfunction isStandardInputJsonSchema(value: unknown): value is StandardInputJsonSchema {\n const standard = getStandardProps(value);\n if (!standard || standard.version !== 1 || !isPlainObject(standard.jsonSchema)) {\n return false;\n }\n\n return typeof standard.jsonSchema.input === 'function';\n}\n\nfunction createStandardValidatorFromJsonSchema(schema: InputSchema): StandardInputValidatorSchema {\n return {\n '~standard': {\n version: 1,\n vendor: '@mcp-b/webmcp-polyfill-json-schema',\n validate(value: unknown): StandardValidationResult {\n if (!isPlainObject(value)) {\n return {\n issues: [{ message: 'expected object arguments' }],\n };\n }\n\n const issue = validateValueWithSchema(value, schema);\n if (issue) {\n return {\n issues: [issue],\n };\n }\n\n return {\n value,\n };\n },\n },\n };\n}\n\nfunction convertStandardInputSchema(schema: StandardInputJsonSchema): InputSchema {\n const failures: Array<{ error: unknown; target: (typeof STANDARD_JSON_SCHEMA_TARGETS)[number] }> =\n [];\n\n for (const target of STANDARD_JSON_SCHEMA_TARGETS) {\n try {\n const converted = schema['~standard'].jsonSchema.input({ target });\n validateInputSchema(converted);\n return converted;\n } catch (error) {\n failures.push({ target, error });\n }\n }\n\n console.warn('[WebMCPPolyfill] Standard JSON Schema conversion failed:', failures);\n throw new Error('Failed to convert Standard JSON Schema inputSchema to a JSON Schema object');\n}\n\nexport function normalizeInputSchema(\n inputSchema: ToolInputSchema | undefined\n): NormalizedInputSchema {\n if (inputSchema === undefined) {\n const normalized = DEFAULT_INPUT_SCHEMA;\n return {\n inputSchema: normalized,\n standardValidator: createStandardValidatorFromJsonSchema(normalized),\n };\n }\n\n if (isStandardInputJsonSchema(inputSchema)) {\n // Prefer JSON conversion for parity across JSON and Standard Schema inputs.\n const converted = convertStandardInputSchema(inputSchema);\n return {\n inputSchema: converted,\n standardValidator: createStandardValidatorFromJsonSchema(converted),\n };\n }\n\n if (isStandardInputValidatorSchema(inputSchema)) {\n return {\n inputSchema: DEFAULT_INPUT_SCHEMA,\n standardValidator: inputSchema,\n };\n }\n\n validateInputSchema(inputSchema);\n\n // Empty {} is valid JSON Schema but lacks type:\"object\" required by MCP.\n if (Object.keys(inputSchema as Record<string, unknown>).length === 0) {\n return {\n inputSchema: DEFAULT_INPUT_SCHEMA,\n standardValidator: createStandardValidatorFromJsonSchema(DEFAULT_INPUT_SCHEMA),\n };\n }\n\n const normalizedSchema =\n inputSchema.type === undefined\n ? ({ type: 'object', ...inputSchema } as InputSchema)\n : inputSchema;\n return {\n inputSchema: normalizedSchema,\n standardValidator: createStandardValidatorFromJsonSchema(normalizedSchema),\n };\n}\n\nfunction validateInputSchema(schema: unknown): asserts schema is InputSchema {\n if (!isPlainObject(schema)) {\n throw new Error('inputSchema must be a JSON Schema object');\n }\n\n validateJsonSchemaNode(schema, '$');\n}\n\nfunction validateJsonSchemaNode(node: Record<string, unknown>, path: string): void {\n const typeValue = node.type;\n if (\n typeValue !== undefined &&\n typeof typeValue !== 'string' &&\n !(\n Array.isArray(typeValue) &&\n typeValue.every((entry) => typeof entry === 'string' && entry.length > 0)\n )\n ) {\n throw new Error(`Invalid JSON Schema at ${path}: \"type\" must be a string or string[]`);\n }\n\n const requiredValue = node.required;\n if (\n requiredValue !== undefined &&\n !(Array.isArray(requiredValue) && requiredValue.every((entry) => typeof entry === 'string'))\n ) {\n throw new Error(`Invalid JSON Schema at ${path}: \"required\" must be an array of strings`);\n }\n\n const propertiesValue = node.properties;\n if (propertiesValue !== undefined) {\n if (!isPlainObject(propertiesValue)) {\n throw new Error(`Invalid JSON Schema at ${path}: \"properties\" must be an object`);\n }\n\n for (const [key, value] of Object.entries(propertiesValue)) {\n if (!isPlainObject(value)) {\n throw new Error(`Invalid JSON Schema at ${path}.properties.${key}: expected object schema`);\n }\n validateJsonSchemaNode(value, `${path}.properties.${key}`);\n }\n }\n\n const itemsValue = node.items;\n if (itemsValue !== undefined) {\n if (Array.isArray(itemsValue)) {\n for (const [index, value] of itemsValue.entries()) {\n if (!isPlainObject(value)) {\n throw new Error(`Invalid JSON Schema at ${path}.items[${index}]: expected object schema`);\n }\n validateJsonSchemaNode(value, `${path}.items[${index}]`);\n }\n } else if (isPlainObject(itemsValue)) {\n validateJsonSchemaNode(itemsValue, `${path}.items`);\n } else {\n throw new Error(`Invalid JSON Schema at ${path}: \"items\" must be an object or object[]`);\n }\n }\n\n for (const keyword of ['allOf', 'anyOf', 'oneOf'] as const) {\n const value = node[keyword];\n if (value === undefined) {\n continue;\n }\n\n if (!Array.isArray(value)) {\n throw new Error(`Invalid JSON Schema at ${path}: \"${keyword}\" must be an array`);\n }\n\n for (const [index, entry] of value.entries()) {\n if (!isPlainObject(entry)) {\n throw new Error(\n `Invalid JSON Schema at ${path}.${keyword}[${index}]: expected object schema`\n );\n }\n validateJsonSchemaNode(entry, `${path}.${keyword}[${index}]`);\n }\n }\n\n const notValue = node.not;\n if (notValue !== undefined) {\n if (!isPlainObject(notValue)) {\n throw new Error(`Invalid JSON Schema at ${path}: \"not\" must be an object schema`);\n }\n validateJsonSchemaNode(notValue, `${path}.not`);\n }\n\n try {\n JSON.stringify(node);\n } catch {\n throw new Error(`Invalid JSON Schema at ${path}: schema must be JSON-serializable`);\n }\n}\n\nexport function validateValueWithSchema(\n value: unknown,\n schema: InputSchema | JsonSchemaForInference\n): StandardValidationIssue | null {\n const validator = new Validator(schema as Schema, '2020-12', true);\n const result = validator.validate(value);\n\n if (result.valid) {\n return null;\n }\n\n // Use the deepest (last) error for the most specific message.\n const error = result.errors[result.errors.length - 1];\n if (!error) {\n return { message: 'Input validation failed' };\n }\n\n return { message: error.error };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"schema.js","names":[],"sources":["../src/schema.ts"],"sourcesContent":["import type {\n CallToolResult,\n InputSchema,\n JsonValue,\n ToolDescriptor,\n WebMcpToolInput,\n WebMcpToolAnnotations,\n} from '@mcp-b/webmcp-types';\nimport type { StandardJSONSchemaV1, StandardSchemaV1 } from '@standard-schema/spec';\n\ntype StandardInputValidatorSchema = StandardSchemaV1<WebMcpToolInput, WebMcpToolInput>;\ntype StandardInputJsonSchema = StandardJSONSchemaV1<WebMcpToolInput, WebMcpToolInput>;\n\nconst DEFAULT_INPUT_SCHEMA: InputSchema = { type: 'object', properties: {} };\nconst FAILED_TO_PARSE_INPUT_ARGUMENTS_MESSAGE = 'Failed to parse input arguments';\nconst TOOL_INVOCATION_FAILED_MESSAGE =\n 'Tool was executed but the invocation failed. For example, the script function threw an error';\nconst STANDARD_JSON_SCHEMA_TARGETS = ['draft-2020-12', 'draft-07'] as const;\nconst VALID_TOOL_NAME_RE = /^[A-Za-z0-9_.-]{1,128}$/u;\n\nexport type ToolInputSchema = InputSchema | StandardInputJsonSchema;\n\nexport interface NormalizedInputSchema {\n inputSchema: InputSchema;\n registeredInputSchema?: string;\n}\n\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction toDomString(value: unknown): string {\n if (typeof value === 'symbol') {\n throw new TypeError('Symbol values cannot be converted to a DOMString');\n }\n return String(value);\n}\n\nexport function coerceWebMcpToolDescriptor<TArgs extends WebMcpToolInput>(\n tool: ToolDescriptor<TArgs>\n): ToolDescriptor<TArgs>;\nexport function coerceWebMcpToolDescriptor(\n tool: Record<string, unknown>\n): ToolDescriptor<WebMcpToolInput>;\nexport function coerceWebMcpToolDescriptor(tool: object): ToolDescriptor<WebMcpToolInput> {\n const name: unknown = Reflect.get(tool, 'name');\n const description: unknown = Reflect.get(tool, 'description');\n const title: unknown = Reflect.get(tool, 'title');\n if (name === undefined) {\n throw new TypeError('Tool \"name\" is required');\n }\n if (description === undefined) {\n throw new TypeError('Tool \"description\" is required');\n }\n\n const annotations: unknown = Reflect.get(tool, 'annotations');\n const annotationMembers = isPlainObject(annotations) ? annotations : {};\n const inputSchema: unknown = Reflect.get(tool, 'inputSchema');\n const outputSchema: unknown = Reflect.get(tool, 'outputSchema');\n const execute: unknown = Reflect.get(tool, 'execute');\n\n // Web IDL dictionaries read known members without retaining the caller's object.\n // The cast is load-bearing: `execute` stays unnarrowed until validateWebMcpToolDescriptor().\n return {\n name: toDomString(name),\n ...(title === undefined\n ? {}\n : {\n title: toDomString(title).toWellFormed(),\n }),\n description: toDomString(description),\n ...(inputSchema === undefined ? {} : { inputSchema }),\n ...(outputSchema === undefined ? {} : { outputSchema }),\n execute,\n ...(annotations === undefined\n ? {}\n : {\n annotations: {\n ...(annotationMembers.title === undefined\n ? {}\n : { title: toDomString(annotationMembers.title).toWellFormed() }),\n readOnlyHint: Boolean(annotationMembers.readOnlyHint),\n ...(annotationMembers.destructiveHint === undefined\n ? {}\n : { destructiveHint: Boolean(annotationMembers.destructiveHint) }),\n ...(annotationMembers.idempotentHint === undefined\n ? {}\n : { idempotentHint: Boolean(annotationMembers.idempotentHint) }),\n ...(annotationMembers.openWorldHint === undefined\n ? {}\n : { openWorldHint: Boolean(annotationMembers.openWorldHint) }),\n untrustedContentHint: Boolean(annotationMembers.untrustedContentHint),\n },\n }),\n } as ToolDescriptor<WebMcpToolInput>;\n}\n\nfunction isJsonObjectRecord(value: unknown): value is Record<string, unknown> {\n if (!isPlainObject(value)) {\n return false;\n }\n\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n\nfunction isJsonValue(value: unknown, seen = new WeakSet<object>()): value is JsonValue {\n if (value === null || typeof value === 'string' || typeof value === 'boolean') {\n return true;\n }\n\n if (typeof value === 'number') {\n return Number.isFinite(value);\n }\n\n if (typeof value !== 'object') {\n return false;\n }\n\n if (seen.has(value)) {\n return false;\n }\n\n seen.add(value);\n try {\n const entries = Array.isArray(value)\n ? value\n : isJsonObjectRecord(value)\n ? Object.values(value)\n : null;\n return entries?.every((entry) => isJsonValue(entry, seen)) ?? false;\n } catch {\n return false;\n } finally {\n seen.delete(value);\n }\n}\n\nfunction toJsonValue(value: unknown): JsonValue | undefined {\n return isJsonValue(value) ? value : undefined;\n}\n\nfunction hasCallToolResultShape(\n value: unknown\n): value is Record<string, unknown> & { content: unknown[] } {\n return isPlainObject(value) && Array.isArray(value.content);\n}\n\nfunction serializeTextContent(value: unknown): string {\n if (typeof value === 'string') return value;\n try {\n return JSON.stringify(value) ?? String(value);\n } catch {\n return String(value);\n }\n}\n\nexport function normalizeToolResponse(value: unknown): CallToolResult {\n // Preserve protocol-evolving content blocks at this compatibility boundary.\n if (hasCallToolResultShape(value)) return value as CallToolResult;\n const structuredContent = toJsonValue(value);\n return {\n content: [{ type: 'text', text: serializeTextContent(value) }],\n ...(structuredContent === undefined ? {} : { structuredContent }),\n isError: false,\n };\n}\n\nexport function createUnknownError(message: string): Error {\n return new DOMException(message, 'UnknownError');\n}\n\nexport function createToolInvocationFailedError(error: unknown): Error {\n return createUnknownError(\n error instanceof Error\n ? `${TOOL_INVOCATION_FAILED_MESSAGE}: ${error.message}`\n : TOOL_INVOCATION_FAILED_MESSAGE\n );\n}\n\nexport function createInvalidStateError(message: string): Error {\n return new DOMException(message, 'InvalidStateError');\n}\n\nexport function validateWebMcpToolDescriptor<TArgs extends WebMcpToolInput>(\n tool: ToolDescriptor<TArgs>\n): void {\n if (tool.name === '') {\n throw createInvalidStateError('Tool \"name\" must be a non-empty string');\n }\n if (typeof tool.name !== 'string' || !VALID_TOOL_NAME_RE.test(tool.name)) {\n throw createInvalidStateError(\n 'Tool \"name\" must be 1–128 characters and contain only ASCII alphanumeric, underscore, hyphen, or period'\n );\n }\n if (typeof tool.description !== 'string' || tool.description.length === 0) {\n throw createInvalidStateError('Tool \"description\" must be a non-empty string');\n }\n if (typeof tool.execute !== 'function') {\n throw new TypeError('Tool \"execute\" must be a function');\n }\n}\n\nexport function toWebMcpAnnotations(annotations: WebMcpToolAnnotations): WebMcpToolAnnotations {\n return {\n readOnlyHint: annotations.readOnlyHint ?? false,\n untrustedContentHint: annotations.untrustedContentHint ?? false,\n };\n}\n\nexport function parseChromeToolInput(input: string): WebMcpToolInput {\n try {\n const value: unknown = JSON.parse(input);\n if (Array.isArray(value) || isPlainObject(value)) return value;\n } catch {\n // Chrome reports invalid JSON and non-object inputs as UnknownError.\n }\n throw createUnknownError(FAILED_TO_PARSE_INPUT_ARGUMENTS_MESSAGE);\n}\n\nexport function serializeChromeToolResult(value: unknown): string {\n if ((typeof value === 'object' && value !== null) || typeof value === 'function') {\n try {\n const serialized = JSON.stringify(value);\n if (serialized) return serialized;\n } catch {\n // Chromium falls back to string conversion when JSON serialization fails.\n }\n }\n return String(value) || 'Operation succeeded';\n}\n\nexport function withAbortSignal<T>(\n operation: Promise<T>,\n signal?: AbortSignal,\n getAbortReason: () => unknown = () => signal?.reason\n): Promise<T> {\n if (!signal) return operation;\n if (signal.aborted) return Promise.reject(getAbortReason());\n return new Promise<T>((resolve, reject) => {\n const onAbort = () => {\n cleanup();\n reject(getAbortReason());\n };\n const cleanup = () => signal.removeEventListener('abort', onAbort);\n\n signal.addEventListener('abort', onAbort, { once: true });\n operation.then(\n (value) => {\n cleanup();\n resolve(value);\n },\n (error: unknown) => {\n cleanup();\n reject(error);\n }\n );\n });\n}\n\nfunction isPotentiallyTrustworthyOrigin(url: URL): boolean {\n const originUrl = url.origin === 'null' ? url : new URL(url.origin);\n const protocol = originUrl.protocol;\n if (['https:', 'wss:', 'file:', 'chrome-extension:', 'moz-extension:'].includes(protocol)) {\n return true;\n }\n\n const hostname = originUrl.hostname.toLowerCase();\n const ipv4 = hostname.split('.');\n const isLoopbackIpv4 =\n ipv4.length === 4 &&\n ipv4.every((part) => /^\\d{1,3}$/u.test(part) && Number(part) <= 255) &&\n Number(ipv4[0]) === 127;\n return (\n hostname === '::1' ||\n hostname === '[::1]' ||\n hostname === 'localhost' ||\n hostname === 'localhost.' ||\n hostname.endsWith('.localhost') ||\n hostname.endsWith('.localhost.') ||\n isLoopbackIpv4\n );\n}\n\nexport function validatePotentiallyTrustworthyOrigins(\n origins: readonly string[] | undefined\n): void {\n for (const origin of origins ?? []) {\n let parsed: URL;\n try {\n parsed = new URL(origin);\n } catch {\n throw new DOMException(`Invalid or untrustworthy origin: ${String(origin)}`, 'SecurityError');\n }\n if (!isPotentiallyTrustworthyOrigin(parsed)) {\n throw new DOMException(`Invalid or untrustworthy origin: ${origin}`, 'SecurityError');\n }\n }\n}\n\nexport function validateWebMcpAccess(ownerDocument: Document | null): void {\n validateOriginAgentCluster();\n if (!ownerDocument) return;\n\n const DOMExceptionConstructor = ownerDocument.defaultView?.DOMException ?? DOMException;\n let fullyActive = false;\n try {\n const ownerWindow = ownerDocument.defaultView;\n fullyActive = Boolean(ownerWindow && ownerWindow.document === ownerDocument);\n } catch {\n // A navigated cross-origin WindowProxy is not the document's active window.\n }\n if (!fullyActive) {\n throw new DOMExceptionConstructor(\n 'The associated document is not fully active',\n 'InvalidStateError'\n );\n }\n\n const policy: unknown =\n Reflect.get(ownerDocument, 'permissionsPolicy') ?? Reflect.get(ownerDocument, 'featurePolicy');\n if (policy && typeof policy === 'object') {\n const features = Reflect.get(policy, 'features');\n const allowsFeature = Reflect.get(policy, 'allowsFeature');\n if (typeof features === 'function' && typeof allowsFeature === 'function') {\n const supported: unknown = Reflect.apply(features, policy, []);\n if (Array.isArray(supported) && supported.includes('tools')) {\n if (Reflect.apply(allowsFeature, policy, ['tools']) === true) return;\n throw new DOMExceptionConstructor(\n 'WebMCP is disabled by Permissions Policy',\n 'NotAllowedError'\n );\n }\n }\n }\n\n const ownerWindow = ownerDocument.defaultView;\n if (!ownerWindow || ownerWindow.parent === ownerWindow) return;\n try {\n void ownerWindow.parent.document;\n return;\n } catch {\n // Without native policy support, cross-origin frames fail closed.\n }\n throw new DOMExceptionConstructor(\n 'WebMCP in cross-origin frames requires native Permissions Policy support',\n 'NotAllowedError'\n );\n}\n\nexport function validateOriginAgentCluster(): void {\n if (globalThis.originAgentCluster === false && globalThis.location?.protocol !== 'file:') {\n throw new DOMException('', 'SecurityError');\n }\n}\n\nexport function validateExecutableOrigin(origin: unknown): void {\n try {\n if (new URL(String(origin)).origin !== 'null') return;\n } catch {\n // Invalid and opaque origins share the WebMCP NotSupportedError result.\n }\n throw new DOMException(`Unsupported tool origin: ${String(origin)}`, 'NotSupportedError');\n}\n\nfunction getStandardProps(value: unknown): Record<string, unknown> | null {\n if (!isPlainObject(value)) {\n return null;\n }\n\n const standard = value['~standard'];\n if (!isPlainObject(standard)) {\n return null;\n }\n\n return standard;\n}\n\nfunction isStandardInputValidatorSchema(value: unknown): value is StandardInputValidatorSchema {\n const standard = getStandardProps(value);\n return Boolean(standard && standard.version === 1 && typeof standard.validate === 'function');\n}\n\nfunction isStandardInputJsonSchema(value: unknown): value is StandardInputJsonSchema {\n const standard = getStandardProps(value);\n if (!standard || standard.version !== 1 || !isPlainObject(standard.jsonSchema)) {\n return false;\n }\n\n return typeof standard.jsonSchema.input === 'function';\n}\n\nfunction preserveStandardSchema(\n inputSchema: InputSchema,\n standardSchema: StandardInputValidatorSchema\n): InputSchema {\n const normalized = { ...inputSchema };\n Object.defineProperty(normalized, '~standard', {\n value: standardSchema['~standard'],\n });\n return normalized;\n}\n\nfunction convertStandardInputSchema(schema: StandardInputJsonSchema): InputSchema {\n for (const target of STANDARD_JSON_SCHEMA_TARGETS) {\n try {\n const converted = schema['~standard'].jsonSchema.input({ target });\n const serialized = serializeInputSchema(converted);\n const parsed: unknown = JSON.parse(serialized);\n if (!isPlainObject(parsed)) throw new TypeError('inputSchema must serialize to an object');\n return parsed;\n } catch {}\n }\n\n throw new Error('Failed to convert Standard JSON Schema inputSchema to a JSON Schema object');\n}\n\nexport function normalizeInputSchema(\n inputSchema: ToolInputSchema | undefined\n): NormalizedInputSchema {\n if (inputSchema === undefined) {\n return { inputSchema: DEFAULT_INPUT_SCHEMA };\n }\n\n if (isStandardInputJsonSchema(inputSchema)) {\n const converted = convertStandardInputSchema(inputSchema);\n const registeredInputSchema = serializeInputSchema(converted);\n return {\n inputSchema: isStandardInputValidatorSchema(inputSchema)\n ? preserveStandardSchema(converted, inputSchema)\n : converted,\n registeredInputSchema,\n };\n }\n\n if (isStandardInputValidatorSchema(inputSchema)) {\n throw new Error(\n 'Standard Schema inputSchema must provide ~standard.jsonSchema.input() for tool metadata'\n );\n }\n\n if (\n inputSchema === null ||\n (typeof inputSchema !== 'object' && typeof inputSchema !== 'function')\n ) {\n throw new TypeError('inputSchema must be an object');\n }\n const registeredInputSchema = serializeInputSchema(inputSchema);\n const serializedValue: unknown = JSON.parse(registeredInputSchema);\n const jsonSchema = isPlainObject(serializedValue) ? serializedValue : undefined;\n\n // Empty {} is valid JSON Schema but lacks type:\"object\" required by MCP.\n if (!jsonSchema || Object.keys(jsonSchema).length === 0) {\n return {\n inputSchema: DEFAULT_INPUT_SCHEMA,\n registeredInputSchema,\n };\n }\n\n const normalizedSchema: InputSchema =\n jsonSchema.type === undefined ? { type: 'object', ...jsonSchema } : jsonSchema;\n return {\n inputSchema: normalizedSchema,\n registeredInputSchema,\n };\n}\n\nexport function serializeInputSchema(schema: unknown): string {\n if (schema === null || (typeof schema !== 'object' && typeof schema !== 'function')) {\n throw new TypeError('inputSchema must be an object');\n }\n const serialized = JSON.stringify(schema);\n if (serialized === undefined) {\n throw new TypeError('inputSchema must be JSON-serializable');\n }\n return serialized;\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcp-b/webmcp-polyfill",
3
- "version": "4.0.0",
3
+ "version": "5.0.0",
4
4
  "description": "Strict WebMCP core runtime polyfill for document.modelContext (with deprecated navigator.modelContext alias)",
5
5
  "keywords": [
6
6
  "browser",
@@ -24,10 +24,12 @@
24
24
  "dist"
25
25
  ],
26
26
  "type": "module",
27
- "sideEffects": true,
27
+ "sideEffects": [
28
+ "./dist/index.iife.js"
29
+ ],
28
30
  "main": "./dist/index.js",
29
31
  "module": "./dist/index.js",
30
- "browser": "./dist/index.iife.js",
32
+ "browser": "./dist/index.js",
31
33
  "types": "./dist/index.d.ts",
32
34
  "exports": {
33
35
  ".": {
@@ -50,23 +52,20 @@
50
52
  "registry": "https://registry.npmjs.org/"
51
53
  },
52
54
  "dependencies": {
53
- "@cfworker/json-schema": "^4.1.1",
54
55
  "@standard-schema/spec": "^1.1.0",
55
- "@mcp-b/webmcp-types": "4.0.0"
56
+ "@mcp-b/webmcp-types": "5.0.0"
56
57
  },
57
58
  "devDependencies": {
58
- "@vitest/coverage-v8": "^4.1.7",
59
- "happy-dom": "^20.8.9",
60
59
  "playwright": "^1.60.0",
61
60
  "typescript": "^5.8.3",
62
61
  "vite-plus": "^0.1.22",
63
62
  "vitest": "npm:@voidzero-dev/vite-plus-test@latest"
64
63
  },
65
64
  "engines": {
66
- "node": ">=18"
65
+ "node": ">=20"
67
66
  },
68
67
  "scripts": {
69
- "build": "pnpm --filter @mcp-b/webmcp-types build && vp pack",
68
+ "build": "vp pack",
70
69
  "check": "vp check --fix",
71
70
  "clean": "rm -rf dist",
72
71
  "format": "vp fmt --write",
@@ -74,9 +73,7 @@
74
73
  "publish:dry": "pnpm publish --access public --dry-run",
75
74
  "publish:npm": "pnpm publish --access public",
76
75
  "test": "vp test run",
77
- "test:browser": "vp test run --config vitest.browser.config.ts --browser.headless",
78
- "test:browser:ui": "vp test --config vitest.browser.config.ts --browser",
79
- "test:conformance": "vp test run --config vitest.conformance.config.ts --browser.headless",
80
- "typecheck": "pnpm --filter @mcp-b/webmcp-types build && tsc --noEmit && vp test run --typecheck --silent"
76
+ "test:conformance": "vp test run conformance/polyfill-runtime.e2e.test.ts --browser.headless",
77
+ "typecheck": "tsc --noEmit && vp test run --typecheck --silent"
81
78
  }
82
79
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";;;UAkFiB,yBAAA;EAAA;;;;;EAMf,cAAA;EAcA;;;AA0mBF;;;;EA/mBE,kBAAA;EAmsBc;;;EA9rBd,+BAAA;AAAA;AAAA,iBA0mBc,wBAAA,CAAyB,OAAA,GAAU,yBAAA;AAAA,iBAoFnC,qBAAA,CAAA;AAAA,QA+CR,MAAA;EAAA,UACI,MAAA;IACR,uBAAA,GAA0B,yBAAA;EAAA;AAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"schema.d.ts","names":[],"sources":["../src/schema.ts"],"mappings":";;;;KAQY,4BAAA,GAA+B,gBAAA,CACzC,MAAA,mBACA,MAAA;AAAA,KAEU,uBAAA,GAA0B,sBAAA,CACpC,MAAA,mBACA,MAAA;AAAA,KAEU,eAAA,GAAkB,WAAA,GAAc,4BAAA,GAA+B,uBAAA;AAAA,KAC/D,gBAAA,GAAmB,WAAA,GAAc,uBAAA;AAAA,KAEjC,wBAAA,GAA2B,OAAA,CACrC,UAAA,CAAW,4BAAA;AAAA,KAED,uBAAA,GAA0B,WAAA,CAAY,wBAAA;AAAA,UAEjC,qBAAA;EACf,WAAA,EAAa,WAAA;EACb,iBAAA,EAAmB,4BAAA;AAAA;AAAA,iBAGL,aAAA,CAAc,KAAA,YAAiB,KAAA,IAAS,MAAA;AAAA,iBA6CxC,WAAA,CAAY,KAAA,YAAiB,SAAA;AAAA,iBA4E7B,oBAAA,CACd,WAAA,EAAa,eAAA,eACZ,qBAAA;AAAA,iBA2Ia,uBAAA,CACd,KAAA,WACA,MAAA,EAAQ,WAAA,GAAc,sBAAA,GACrB,uBAAA"}