canonize 0.1.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.
Files changed (63) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +629 -0
  3. package/dist/coercers/array.d.ts +7 -0
  4. package/dist/coercers/array.d.ts.map +1 -0
  5. package/dist/coercers/bigint.d.ts +5 -0
  6. package/dist/coercers/bigint.d.ts.map +1 -0
  7. package/dist/coercers/boolean.d.ts +5 -0
  8. package/dist/coercers/boolean.d.ts.map +1 -0
  9. package/dist/coercers/date.d.ts +5 -0
  10. package/dist/coercers/date.d.ts.map +1 -0
  11. package/dist/coercers/discriminated-union.d.ts +7 -0
  12. package/dist/coercers/discriminated-union.d.ts.map +1 -0
  13. package/dist/coercers/enum.d.ts +9 -0
  14. package/dist/coercers/enum.d.ts.map +1 -0
  15. package/dist/coercers/intersection.d.ts +8 -0
  16. package/dist/coercers/intersection.d.ts.map +1 -0
  17. package/dist/coercers/literal.d.ts +5 -0
  18. package/dist/coercers/literal.d.ts.map +1 -0
  19. package/dist/coercers/map-set.d.ts +11 -0
  20. package/dist/coercers/map-set.d.ts.map +1 -0
  21. package/dist/coercers/nan.d.ts +5 -0
  22. package/dist/coercers/nan.d.ts.map +1 -0
  23. package/dist/coercers/null.d.ts +5 -0
  24. package/dist/coercers/null.d.ts.map +1 -0
  25. package/dist/coercers/number.d.ts +13 -0
  26. package/dist/coercers/number.d.ts.map +1 -0
  27. package/dist/coercers/object.d.ts +7 -0
  28. package/dist/coercers/object.d.ts.map +1 -0
  29. package/dist/coercers/record.d.ts +7 -0
  30. package/dist/coercers/record.d.ts.map +1 -0
  31. package/dist/coercers/string.d.ts +6 -0
  32. package/dist/coercers/string.d.ts.map +1 -0
  33. package/dist/coercers/tuple.d.ts +7 -0
  34. package/dist/coercers/tuple.d.ts.map +1 -0
  35. package/dist/coercers/union.d.ts +7 -0
  36. package/dist/coercers/union.d.ts.map +1 -0
  37. package/dist/constants.d.ts +36 -0
  38. package/dist/constants.d.ts.map +1 -0
  39. package/dist/create-schema.d.ts +5 -0
  40. package/dist/create-schema.d.ts.map +1 -0
  41. package/dist/index.d.ts +51 -0
  42. package/dist/index.d.ts.map +1 -0
  43. package/dist/index.js +1623 -0
  44. package/dist/index.js.map +33 -0
  45. package/dist/tool-parameters/index.d.ts +206 -0
  46. package/dist/tool-parameters/index.d.ts.map +1 -0
  47. package/dist/tool-parameters/index.js +301 -0
  48. package/dist/tool-parameters/index.js.map +12 -0
  49. package/dist/tool-parameters/link-metadata.d.ts +17 -0
  50. package/dist/tool-parameters/link-metadata.d.ts.map +1 -0
  51. package/dist/utilities/circular.d.ts +27 -0
  52. package/dist/utilities/circular.d.ts.map +1 -0
  53. package/dist/utilities/parsers.d.ts +29 -0
  54. package/dist/utilities/parsers.d.ts.map +1 -0
  55. package/dist/utilities/special-methods.d.ts +14 -0
  56. package/dist/utilities/special-methods.d.ts.map +1 -0
  57. package/dist/utilities/type-coercion.d.ts +11 -0
  58. package/dist/utilities/type-coercion.d.ts.map +1 -0
  59. package/dist/utilities/type-detection.d.ts +26 -0
  60. package/dist/utilities/type-detection.d.ts.map +1 -0
  61. package/dist/utilities/type-guards.d.ts +35 -0
  62. package/dist/utilities/type-guards.d.ts.map +1 -0
  63. package/package.json +123 -0
@@ -0,0 +1,301 @@
1
+ // src/tool-parameters/index.ts
2
+ import { z as z2 } from "zod";
3
+
4
+ // src/utilities/type-coercion.ts
5
+ var COMMON_LIST_DELIMITERS = /[,;|]/;
6
+ var TRUTHY_STRINGS = new Set(["true", "yes", "y", "on", "1", "enable", "enabled"]);
7
+ var FALSY_STRINGS = new Set([
8
+ "false",
9
+ "no",
10
+ "n",
11
+ "off",
12
+ "0",
13
+ "disable",
14
+ "disabled",
15
+ "null",
16
+ "undefined",
17
+ ""
18
+ ]);
19
+ function toString(value, fallbackOrCtx) {
20
+ const fallback = typeof fallbackOrCtx === "string" ? fallbackOrCtx : "";
21
+ if (typeof value === "string")
22
+ return value;
23
+ if (value === null || value === undefined)
24
+ return fallback;
25
+ if (typeof value === "number" || typeof value === "bigint" || typeof value === "boolean") {
26
+ return String(value);
27
+ }
28
+ if (typeof value === "symbol")
29
+ return value.description ?? fallback;
30
+ if (value instanceof Date) {
31
+ const time = value.getTime();
32
+ return Number.isNaN(time) ? fallback : value.toISOString();
33
+ }
34
+ if (Array.isArray(value)) {
35
+ return value.map((entry) => toString(entry, fallback)).join(",");
36
+ }
37
+ if (typeof value === "function")
38
+ return value.name || "function";
39
+ if (typeof value === "object") {
40
+ if (typeof value.toString === "function") {
41
+ const str = value.toString();
42
+ if (str !== "[object Object]")
43
+ return str;
44
+ }
45
+ try {
46
+ return JSON.stringify(value);
47
+ } catch {
48
+ return fallback;
49
+ }
50
+ }
51
+ return fallback;
52
+ }
53
+ function toBoolean(value, defaultValue = false) {
54
+ if (typeof value === "boolean")
55
+ return value;
56
+ if (typeof value === "number")
57
+ return value !== 0 && !Number.isNaN(value);
58
+ if (typeof value === "bigint")
59
+ return value !== 0n;
60
+ if (typeof value === "string") {
61
+ const normalized = value.trim().toLowerCase();
62
+ if (TRUTHY_STRINGS.has(normalized))
63
+ return true;
64
+ if (FALSY_STRINGS.has(normalized))
65
+ return false;
66
+ const parsed = Number.parseFloat(normalized.replace(/,/g, ""));
67
+ if (!Number.isNaN(parsed))
68
+ return parsed !== 0;
69
+ return defaultValue;
70
+ }
71
+ if (Array.isArray(value) || value instanceof Set || value instanceof Map) {
72
+ return value.size ? value.size > 0 : value.length > 0;
73
+ }
74
+ if (value && typeof value === "object")
75
+ return true;
76
+ return defaultValue;
77
+ }
78
+ function toNumber(value, defaultValue = 0, options) {
79
+ const normalize = (n) => {
80
+ let result = Number.isFinite(n) ? n : defaultValue;
81
+ if (options?.min !== undefined && result < options.min)
82
+ result = options.min;
83
+ if (options?.max !== undefined && result > options.max)
84
+ result = options.max;
85
+ if (options?.int)
86
+ result = Math[result >= 0 ? "floor" : "ceil"](result);
87
+ return result;
88
+ };
89
+ if (typeof value === "number")
90
+ return normalize(value);
91
+ if (typeof value === "bigint")
92
+ return normalize(Number(value));
93
+ if (typeof value === "boolean")
94
+ return normalize(value ? 1 : 0);
95
+ if (typeof value === "string") {
96
+ const trimmed = value.trim();
97
+ if (trimmed === "")
98
+ return normalize(defaultValue);
99
+ const normalized = trimmed.replace(/,/g, "");
100
+ const match = normalized.match(/-?\d*\.?\d+(?:e-?\d+)?/i);
101
+ if (match) {
102
+ const num = Number.parseFloat(match[0]);
103
+ return normalize(num);
104
+ }
105
+ return normalize(defaultValue);
106
+ }
107
+ if (Array.isArray(value)) {
108
+ return normalize(toNumber(value[0], defaultValue, options));
109
+ }
110
+ if (value instanceof Date) {
111
+ return normalize(value.getTime());
112
+ }
113
+ if (value && typeof value === "object") {
114
+ const primitive = value.value ?? value.default ?? value[0];
115
+ if (primitive !== undefined) {
116
+ return normalize(toNumber(primitive, defaultValue, options));
117
+ }
118
+ return normalize(Number.parseFloat(toString(value)));
119
+ }
120
+ return normalize(defaultValue);
121
+ }
122
+ function toArray(value) {
123
+ if (value === null || value === undefined)
124
+ return [];
125
+ if (Array.isArray(value))
126
+ return value;
127
+ if (value instanceof Set || value instanceof Map) {
128
+ return Array.from(value.values());
129
+ }
130
+ if (ArrayBuffer.isView(value)) {
131
+ return Array.from(value);
132
+ }
133
+ if (typeof value === "string") {
134
+ const trimmed = value.trim();
135
+ if (!trimmed)
136
+ return [];
137
+ try {
138
+ const parsed = JSON.parse(trimmed);
139
+ if (Array.isArray(parsed))
140
+ return parsed;
141
+ if (typeof parsed === "object" && parsed !== null)
142
+ return Object.values(parsed);
143
+ } catch {}
144
+ if (trimmed.includes(`
145
+ `)) {
146
+ return trimmed.split(`
147
+ `).map((part) => part.trim()).filter(Boolean);
148
+ }
149
+ if (COMMON_LIST_DELIMITERS.test(trimmed)) {
150
+ return trimmed.split(COMMON_LIST_DELIMITERS).map((part) => part.trim()).filter(Boolean);
151
+ }
152
+ return [trimmed];
153
+ }
154
+ if (typeof value === "object" && Symbol.iterator in value) {
155
+ return Array.from(value);
156
+ }
157
+ if (typeof value === "object") {
158
+ return Object.values(value);
159
+ }
160
+ return [value];
161
+ }
162
+ function toNumberArray(value) {
163
+ const arr = toArray(value);
164
+ return arr.map((entry) => toNumber(entry, Number.NaN)).filter((num) => Number.isFinite(num));
165
+ }
166
+ function toEnum(value, values, defaultValue) {
167
+ if (!values.length)
168
+ throw new Error("values must contain at least one option");
169
+ const fallback = defaultValue ?? values[0];
170
+ if (value === null || value === undefined)
171
+ return fallback;
172
+ const raw = toString(value).trim();
173
+ if (!raw)
174
+ return fallback;
175
+ if (values.includes(raw))
176
+ return raw;
177
+ const lowerValues = values.map((v) => v.toLowerCase());
178
+ const normalized = raw.toLowerCase();
179
+ const exactIdx = lowerValues.findIndex((v) => v === normalized);
180
+ if (exactIdx !== -1)
181
+ return values[exactIdx];
182
+ const prefixIdx = lowerValues.findIndex((v) => v.startsWith(normalized));
183
+ if (prefixIdx !== -1)
184
+ return values[prefixIdx];
185
+ const substringIdx = lowerValues.findIndex((v) => normalized.startsWith(v) || normalized.includes(v) || v.includes(normalized));
186
+ if (substringIdx !== -1)
187
+ return values[substringIdx];
188
+ return fallback;
189
+ }
190
+
191
+ // src/tool-parameters/link-metadata.ts
192
+ import { z } from "zod";
193
+ var linkMetadataSchema = z.object({
194
+ title: z.string().nullable().describe("The text or title of the linked page, if available."),
195
+ url: z.string().min(1).describe("The URL of the link. May be absolute, relative, or a fragment depending on extraction context."),
196
+ source: z.enum(["html", "markdown", "element", "link"]).optional().describe("Where the link was extracted from."),
197
+ rel: z.string().nullable().optional(),
198
+ target: z.string().nullable().optional(),
199
+ referrerPolicy: z.string().nullable().optional(),
200
+ text: z.string().nullable().optional().describe("Raw link text prior to normalization.")
201
+ });
202
+
203
+ // src/tool-parameters/index.ts
204
+ var boolean = (defaultValue) => z2.preprocess((val) => toBoolean(val, defaultValue), z2.boolean()).default(defaultValue);
205
+ var number = (defaultValue, options) => z2.preprocess((val) => toNumber(val, defaultValue, options), z2.number()).default(defaultValue);
206
+ var string = () => z2.preprocess(toString, z2.string());
207
+ var selector = () => z2.preprocess(toString, z2.string().min(1));
208
+ var containerSelector = () => z2.preprocess((val) => {
209
+ if (val === null || val === undefined)
210
+ return null;
211
+ const str = toString(val).trim();
212
+ if (str === "")
213
+ return null;
214
+ const normalized = str.toLowerCase();
215
+ const naturalLanguagePatterns = [
216
+ "all",
217
+ "everything",
218
+ "everywhere",
219
+ "entire page",
220
+ "whole page",
221
+ "full page",
222
+ "the page",
223
+ "document",
224
+ "page",
225
+ "website"
226
+ ];
227
+ if (naturalLanguagePatterns.includes(normalized)) {
228
+ return null;
229
+ }
230
+ const literalPatterns = ["null", "undefined", "none", "nil", "false", "0"];
231
+ if (literalPatterns.includes(normalized)) {
232
+ return null;
233
+ }
234
+ if (normalized === "*") {
235
+ return null;
236
+ }
237
+ if (/^a(\[href\])?$|^links?$|^anchors?$/i.test(normalized)) {
238
+ console.warn(`[containerSelector] Invalid selector "${val}" attempts to select link elements. Use null to search entire page or specify a container region like "main" or "#content".`);
239
+ return null;
240
+ }
241
+ const descendantMatch = normalized.match(/^(.+?)\s+a(\[|:|$)/);
242
+ if (descendantMatch && descendantMatch[1]) {
243
+ const container = descendantMatch[1].trim();
244
+ console.warn(`[containerSelector] Detected descendant combinator "${val}". Extracting container "${container}". Links are found automatically.`);
245
+ return container;
246
+ }
247
+ return str;
248
+ }, z2.string().nullable()).optional();
249
+ var collection = (...defaultValues) => z2.preprocess((val) => {
250
+ const arr = toArray(val);
251
+ return arr.map((item) => toString(item));
252
+ }, z2.array(z2.string())).default(defaultValues);
253
+ var numbers = (options) => z2.preprocess((val) => {
254
+ if (val === null || val === undefined)
255
+ return [];
256
+ const arr = toNumberArray(val);
257
+ if (!options)
258
+ return arr;
259
+ return arr.map((n) => {
260
+ let result = n;
261
+ if (options.min !== undefined && result < options.min)
262
+ result = options.min;
263
+ if (options.max !== undefined && result > options.max)
264
+ result = options.max;
265
+ if (options.int)
266
+ result = Math.round(result);
267
+ return result;
268
+ });
269
+ }, z2.array(z2.number())).default([]);
270
+ var choices = (values, defaultValue) => {
271
+ const schema = z2.preprocess((val) => toEnum(val, values, defaultValue), z2.enum(values));
272
+ return defaultValue !== undefined ? schema.default(defaultValue) : schema;
273
+ };
274
+ var count = () => z2.preprocess((val) => toNumber(val, 0), z2.number());
275
+ var url = () => z2.preprocess((val) => {
276
+ const str = toString(val);
277
+ return str.replace(/^["'<[({]+|[\])"'>}]+$/g, "").trim();
278
+ }, z2.string().min(1));
279
+ var exportFormat = (options) => {
280
+ const formats = options?.includeJson === false ? ["markdown", "csv"] : ["markdown", "csv", "json"];
281
+ return choices(formats, options?.defaultValue ?? "markdown");
282
+ };
283
+ var imageFormat = (defaultValue = "png") => choices(["jpeg", "png"], defaultValue);
284
+ var links = () => z2.array(linkMetadataSchema).default([]);
285
+ export {
286
+ url,
287
+ string,
288
+ selector,
289
+ numbers,
290
+ number,
291
+ links,
292
+ imageFormat,
293
+ exportFormat,
294
+ count,
295
+ containerSelector,
296
+ collection,
297
+ choices,
298
+ boolean
299
+ };
300
+
301
+ //# debugId=D22B75972928F1DD64756E2164756E21
@@ -0,0 +1,12 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/tool-parameters/index.ts", "../src/utilities/type-coercion.ts", "../src/tool-parameters/link-metadata.ts"],
4
+ "sourcesContent": [
5
+ "import { z } from 'zod';\n\nimport {\n toArray,\n toBoolean,\n toEnum,\n toNumber,\n toNumberArray,\n toString,\n} from '../utilities/type-coercion';\nimport { linkMetadataSchema } from './link-metadata';\n\n/**\n * Generic Tool Parameter Schema Helpers\n *\n * Reusable, permissive schema builders for tool parameter definitions.\n * These wrap LLM coercion utilities to handle malformed inputs gracefully.\n */\n\n/**\n * Creates a schema for boolean parameters with ultra-robust coercion.\n * Handles: true, false, \"true\", \"false\", \"yes\", \"no\", \"on\", \"off\", 1, 0, etc.\n *\n * @param defaultValue - Default boolean value\n * @example\n * const enabledSchema = boolean(true); // defaults to true\n * enabledSchema.parse(\"yes\"); // true\n * enabledSchema.parse(\"FALSE\"); // false\n * enabledSchema.parse(1); // true\n */\nexport const boolean = (defaultValue: boolean) =>\n z.preprocess((val) => toBoolean(val, defaultValue), z.boolean()).default(defaultValue);\n\n/**\n * Creates a schema for number parameters with ultra-robust coercion.\n * Handles: 42, \"42\", \"42px\", \"1,234\", \"1e5\", objects, arrays, etc.\n *\n * @param defaultValue - Default number value\n * @param options - Optional constraints (min, max, int)\n * @example\n * const countSchema = number(10, { min: 1, max: 100, int: true });\n * countSchema.parse(\"42px\"); // 42\n * countSchema.parse(\"1,234\"); // 1234\n * countSchema.parse({value: 15}); // 15\n */\nexport const number = (\n defaultValue: number,\n options?: {\n min?: number;\n max?: number;\n int?: boolean;\n },\n) =>\n z\n .preprocess((val) => toNumber(val, defaultValue, options), z.number())\n .default(defaultValue);\n\n/**\n * Creates a schema for string parameters with ultra-robust coercion and trimming.\n * Handles: \"hello\", 123, true, objects, arrays, etc.\n *\n * @example\n * const nameSchema = string();\n * nameSchema.parse(\" hello \"); // \"hello\"\n * nameSchema.parse(123); // \"123\"\n * nameSchema.parse({value: \"foo\"}); // \"foo\"\n */\nexport const string = () => z.preprocess(toString, z.string());\n\n/**\n * Creates a schema for CSS selector strings with validation.\n * Trims whitespace and validates non-empty.\n *\n * @example\n * const selectorSchema = selector();\n * selectorSchema.parse(\" .class \"); // \".class\"\n */\nexport const selector = () => z.preprocess(toString, z.string().min(1));\n\n/**\n * Creates a schema for container/region CSS selectors with intelligent coercion.\n * Designed to handle common LLM mistakes when specifying page regions to search within.\n *\n * Coercion strategies:\n * - Natural language (\"all\", \"everything\", \"entire page\") → null (entire document)\n * - Programming literals (\"null\", \"undefined\", \"none\") → null\n * - Wildcards (\"*\") → null (too broad to be useful)\n * - Link selectors (\"a\", \"a[href]\", \"links\") → null (wrong element type)\n * - Descendant combinators (\"body a\", \"main a\") → extracts container (\"body\", \"main\")\n * - Valid CSS → passes through unchanged\n * - Invalid CSS → passes through (will be caught at runtime)\n *\n * @example\n * containerSelector().parse(\"main\"); // \"main\" (valid)\n * containerSelector().parse(\"*\"); // null (wildcard)\n * containerSelector().parse(\"null\"); // null (literal)\n * containerSelector().parse(\"a\"); // null (link selector)\n * containerSelector().parse(\"body a\"); // \"body\" (extracted)\n * containerSelector().parse(\"all\"); // null (natural language)\n */\nexport const containerSelector = () =>\n z\n .preprocess((val) => {\n if (val === null || val === undefined) return null;\n\n const str = toString(val).trim();\n if (str === '') return null;\n\n const normalized = str.toLowerCase();\n\n // Natural language meaning \"entire page\" → null\n const naturalLanguagePatterns = [\n 'all',\n 'everything',\n 'everywhere',\n 'entire page',\n 'whole page',\n 'full page',\n 'the page',\n 'document',\n 'page',\n 'website',\n ];\n if (naturalLanguagePatterns.includes(normalized)) {\n return null;\n }\n\n // Programming construct literals → null\n const literalPatterns = ['null', 'undefined', 'none', 'nil', 'false', '0'];\n if (literalPatterns.includes(normalized)) {\n return null;\n }\n\n // Wildcard selector → null (matches everything, not useful as container)\n if (normalized === '*') {\n return null;\n }\n\n // Link element selectors → null (trying to select links, not containers)\n if (/^a(\\[href\\])?$|^links?$|^anchors?$/i.test(normalized)) {\n console.warn(\n `[containerSelector] Invalid selector \"${val}\" attempts to select link elements. Use null to search entire page or specify a container region like \"main\" or \"#content\".`,\n );\n return null;\n }\n\n // Descendant combinator pattern: \"container a\" → \"container\"\n // Matches: \"body a\", \"main a[href]\", \"div a:not([href=''])\", etc.\n const descendantMatch = normalized.match(/^(.+?)\\s+a(\\[|:|$)/);\n if (descendantMatch && descendantMatch[1]) {\n const container = descendantMatch[1].trim();\n console.warn(\n `[containerSelector] Detected descendant combinator \"${val}\". Extracting container \"${container}\". Links are found automatically.`,\n );\n return container;\n }\n\n // Pass through anything else (assume valid CSS, will be validated at runtime)\n return str;\n }, z.string().nullable())\n .optional();\n\n/**\n * Creates a schema for collection of strings with ultra-flexible input handling.\n *\n * Handles:\n * - Arrays: [\"foo\", \"bar\"]\n * - Comma-separated: \"foo,bar,baz\"\n * - Semicolon-separated: \"foo;bar;baz\"\n * - Pipe-separated: \"foo|bar|baz\"\n * - Newline-separated: \"foo\\nbar\\nbaz\"\n * - Single values: wraps in array\n * - Empty values: filters out\n *\n * @param defaultValues - Default array values (defaults to empty array)\n * @example\n * const tagsSchema = collection('default', 'tags');\n * tagsSchema.parse(\"foo,bar\"); // ['foo', 'bar']\n * tagsSchema.parse(\"foo;bar\"); // ['foo', 'bar']\n * tagsSchema.parse(\"foo\"); // ['foo']\n * tagsSchema.parse(null); // ['default', 'tags']\n */\nexport const collection = (...defaultValues: string[]) =>\n z\n .preprocess((val) => {\n const arr = toArray(val);\n return arr.map((item) => toString(item));\n }, z.array(z.string()))\n .default(defaultValues);\n\n/**\n * Creates a schema for collection of numbers with ultra-flexible input handling.\n *\n * Handles:\n * - Arrays: [1, 2, 3]\n * - Comma-separated: \"1,2,3\"\n * - Semicolon-separated: \"1;2;3\"\n * - Pipe-separated: \"1|2|3\"\n * - Single values: wraps in array\n * - Strings with units: \"42px,100%,5\" → [42, 100, 5]\n *\n * @param options - Optional constraints (min, max, int)\n * @example\n * const idsSchema = numbers({ int: true, min: 0 });\n * idsSchema.parse(\"1,2,3\"); // [1, 2, 3]\n * idsSchema.parse([1, \"2\", 3]); // [1, 2, 3]\n * idsSchema.parse(\"42\"); // [42]\n */\nexport const numbers = (options?: { min?: number; max?: number; int?: boolean }) =>\n z\n .preprocess((val) => {\n if (val === null || val === undefined) return [];\n const arr = toNumberArray(val);\n // Apply constraints to each number if options provided\n if (!options) return arr;\n return arr.map((n) => {\n let result = n;\n if (options.min !== undefined && result < options.min) result = options.min;\n if (options.max !== undefined && result > options.max) result = options.max;\n if (options.int) result = Math.round(result);\n return result;\n });\n }, z.array(z.number()))\n .default([]);\n\n/**\n * Creates a schema for enum/literal string values with fuzzy matching.\n * Handles case-insensitive, partial, and fuzzy matches.\n *\n * @param values - Allowed string literals\n * @param defaultValue - Default value (optional)\n * @example\n * const sortSchema = choices(['date', 'name', 'size'], 'date');\n * sortSchema.parse('Date'); // 'date' (case-insensitive)\n * sortSchema.parse('nam'); // 'name' (prefix match)\n * sortSchema.parse('date_desc'); // 'date' (contains match)\n */\nexport const choices = <T extends string>(\n values: readonly [T, ...T[]],\n defaultValue?: T,\n) => {\n const schema = z.preprocess((val) => toEnum(val, values, defaultValue), z.enum(values));\n return defaultValue !== undefined ? schema.default(defaultValue) : schema;\n};\n\n/**\n * Creates a schema for count/statistic values in tool results.\n * Ultra-robust number coercion with no default value.\n *\n * @example\n * results: z.object({\n * totalFound: count(),\n * filtered: count(),\n * })\n */\nexport const count = () => z.preprocess((val) => toNumber(val, 0), z.number());\n\n/**\n * Creates a schema for URL parameters with ultra-robust string coercion.\n * Validates URL format while remaining permissive.\n *\n * @example\n * const schema = url();\n * schema.parse(\"https://example.com\"); // \"https://example.com\"\n * schema.parse(\" /path \"); // \"/path\"\n */\nexport const url = () =>\n z.preprocess((val) => {\n const str = toString(val);\n // Remove common wrapping characters (quotes, brackets, etc.)\n return str.replace(/^[\"'<[({]+|[\\])\"'>}]+$/g, '').trim();\n }, z.string().min(1));\n\n/**\n * Standard export format parameter (markdown, csv, json).\n * Provides fuzzy matching and defaults to 'markdown'.\n *\n * @param options - Configuration options\n * @param options.defaultValue - Default format (defaults to 'markdown')\n * @param options.includeJson - Whether to include json option (default true)\n * @example\n * exportFormat() // markdown|csv|json, defaults to markdown\n * exportFormat({ includeJson: false }) // markdown|csv only\n * exportFormat({ defaultValue: 'csv' }) // defaults to csv\n */\nexport const exportFormat = (options?: {\n defaultValue?: 'markdown' | 'csv' | 'json';\n includeJson?: boolean;\n}) => {\n const formats =\n options?.includeJson === false\n ? (['markdown', 'csv'] as const)\n : (['markdown', 'csv', 'json'] as const);\n\n return choices(formats, options?.defaultValue ?? 'markdown');\n};\n\n/**\n * Image format parameter for screenshots and image captures.\n * Provides fuzzy matching and defaults to 'png'.\n *\n * @param defaultValue - Default format ('jpeg' or 'png')\n * @example\n * imageFormat() // defaults to 'png'\n * imageFormat('jpeg') // defaults to 'jpeg'\n */\nexport const imageFormat = (defaultValue: 'jpeg' | 'png' = 'png') =>\n choices(['jpeg', 'png'], defaultValue);\n\n/**\n * Creates a schema for link metadata arrays used in tools that work with URLs.\n * Accepts arrays of link objects with title and url properties.\n *\n * @example\n * const schema = links();\n * schema.parse([{ title: 'Example', url: 'https://example.com' }]);\n */\nexport const links = () => z.array(linkMetadataSchema).default([]);\n",
6
+ "const COMMON_LIST_DELIMITERS = /[,;|]/;\n\nconst TRUTHY_STRINGS = new Set(['true', 'yes', 'y', 'on', '1', 'enable', 'enabled']);\nconst FALSY_STRINGS = new Set([\n 'false',\n 'no',\n 'n',\n 'off',\n '0',\n 'disable',\n 'disabled',\n 'null',\n 'undefined',\n '',\n]);\n\nexport function toString(value: unknown, fallbackOrCtx?: string | unknown): string {\n const fallback = typeof fallbackOrCtx === 'string' ? fallbackOrCtx : '';\n if (typeof value === 'string') return value;\n if (value === null || value === undefined) return fallback;\n if (\n typeof value === 'number' ||\n typeof value === 'bigint' ||\n typeof value === 'boolean'\n ) {\n return String(value);\n }\n if (typeof value === 'symbol') return value.description ?? fallback;\n if (value instanceof Date) {\n const time = value.getTime();\n return Number.isNaN(time) ? fallback : value.toISOString();\n }\n if (Array.isArray(value)) {\n return value.map((entry) => toString(entry, fallback)).join(',');\n }\n if (typeof value === 'function') return value.name || 'function';\n if (typeof value === 'object') {\n if (typeof (value as { toString?: () => string }).toString === 'function') {\n const str = (value as { toString: () => string }).toString();\n if (str !== '[object Object]') return str;\n }\n try {\n return JSON.stringify(value);\n } catch {\n return fallback;\n }\n }\n return fallback;\n}\n\nexport function toBoolean(value: unknown, defaultValue = false): boolean {\n if (typeof value === 'boolean') return value;\n if (typeof value === 'number') return value !== 0 && !Number.isNaN(value);\n if (typeof value === 'bigint') return value !== 0n;\n if (typeof value === 'string') {\n const normalized = value.trim().toLowerCase();\n if (TRUTHY_STRINGS.has(normalized)) return true;\n if (FALSY_STRINGS.has(normalized)) return false;\n const parsed = Number.parseFloat(normalized.replace(/,/g, ''));\n if (!Number.isNaN(parsed)) return parsed !== 0;\n return defaultValue;\n }\n if (Array.isArray(value) || value instanceof Set || value instanceof Map) {\n return (value as { size?: number; length?: number }).size\n ? (value as Set<unknown> | Map<unknown, unknown>).size > 0\n : (value as unknown[]).length > 0;\n }\n if (value && typeof value === 'object') return true;\n return defaultValue;\n}\n\nexport function toNumber(\n value: unknown,\n defaultValue = 0,\n options?: { min?: number; max?: number; int?: boolean },\n): number {\n const normalize = (n: number): number => {\n let result = Number.isFinite(n) ? n : defaultValue;\n if (options?.min !== undefined && result < options.min) result = options.min;\n if (options?.max !== undefined && result > options.max) result = options.max;\n if (options?.int) result = Math[result >= 0 ? 'floor' : 'ceil'](result);\n return result;\n };\n\n if (typeof value === 'number') return normalize(value);\n if (typeof value === 'bigint') return normalize(Number(value));\n if (typeof value === 'boolean') return normalize(value ? 1 : 0);\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (trimmed === '') return normalize(defaultValue);\n const normalized = trimmed.replace(/,/g, '');\n const match = normalized.match(/-?\\d*\\.?\\d+(?:e-?\\d+)?/i);\n if (match) {\n const num = Number.parseFloat(match[0]);\n return normalize(num);\n }\n return normalize(defaultValue);\n }\n if (Array.isArray(value)) {\n return normalize(toNumber(value[0], defaultValue, options));\n }\n if (value instanceof Date) {\n return normalize(value.getTime());\n }\n if (value && typeof value === 'object') {\n const primitive =\n (value as { value?: unknown }).value ??\n (value as { default?: unknown }).default ??\n (value as Record<string, unknown>)[0];\n if (primitive !== undefined) {\n return normalize(toNumber(primitive, defaultValue, options));\n }\n return normalize(Number.parseFloat(toString(value)));\n }\n return normalize(defaultValue);\n}\n\nexport function toArray(value: unknown): unknown[] {\n if (value === null || value === undefined) return [];\n if (Array.isArray(value)) return value;\n if (value instanceof Set || value instanceof Map) {\n return Array.from(value.values());\n }\n if (ArrayBuffer.isView(value)) {\n return Array.from(value as unknown as Iterable<unknown>);\n }\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (!trimmed) return [];\n try {\n const parsed = JSON.parse(trimmed);\n if (Array.isArray(parsed)) return parsed;\n if (typeof parsed === 'object' && parsed !== null) return Object.values(parsed);\n } catch {\n // Ignore JSON parse errors and fall back to delimiter-based splitting.\n }\n if (trimmed.includes('\\n')) {\n return trimmed\n .split('\\n')\n .map((part) => part.trim())\n .filter(Boolean);\n }\n if (COMMON_LIST_DELIMITERS.test(trimmed)) {\n return trimmed\n .split(COMMON_LIST_DELIMITERS)\n .map((part) => part.trim())\n .filter(Boolean);\n }\n return [trimmed];\n }\n if (typeof value === 'object' && Symbol.iterator in value) {\n return Array.from(value as Iterable<unknown>);\n }\n if (typeof value === 'object') {\n return Object.values(value as Record<string, unknown>);\n }\n return [value];\n}\n\nexport function toNumberArray(value: unknown): number[] {\n const arr = toArray(value);\n return arr\n .map((entry) => toNumber(entry, Number.NaN))\n .filter((num) => Number.isFinite(num));\n}\n\nexport function toEnum<T extends string>(\n value: unknown,\n values: readonly T[],\n defaultValue?: T,\n): T {\n if (!values.length) throw new Error('values must contain at least one option');\n const fallback = (defaultValue ?? values[0])!;\n if (value === null || value === undefined) return fallback;\n\n const raw = toString(value).trim();\n if (!raw) return fallback;\n\n if (values.includes(raw as T)) return raw as T;\n\n const lowerValues = values.map((v) => v.toLowerCase());\n const normalized = raw.toLowerCase();\n\n const exactIdx = lowerValues.findIndex((v) => v === normalized);\n if (exactIdx !== -1) return values[exactIdx]!;\n\n const prefixIdx = lowerValues.findIndex((v) => v.startsWith(normalized));\n if (prefixIdx !== -1) return values[prefixIdx]!;\n\n const substringIdx = lowerValues.findIndex(\n (v) => normalized.startsWith(v) || normalized.includes(v) || v.includes(normalized),\n );\n if (substringIdx !== -1) return values[substringIdx]!;\n\n return fallback;\n}\n",
7
+ "import { z } from 'zod';\n\n/** Metadata for a link extracted from content */\nexport interface LinkMetadata {\n /** The text or title of the linked page, if available. */\n title: string | null;\n /** The URL of the link. May be absolute, relative, or a fragment depending on extraction context. */\n url: string;\n /** Where the link was extracted from. */\n source?: 'html' | 'markdown' | 'element' | 'link' | undefined;\n rel?: string | null | undefined;\n target?: string | null | undefined;\n referrerPolicy?: string | null | undefined;\n /** Raw link text prior to normalization. */\n text?: string | null | undefined;\n}\n\nexport const linkMetadataSchema: z.ZodType<LinkMetadata> = z.object({\n title: z\n .string()\n .nullable()\n .describe('The text or title of the linked page, if available.'),\n url: z\n .string()\n .min(1)\n .describe(\n 'The URL of the link. May be absolute, relative, or a fragment depending on extraction context.',\n ),\n source: z\n .enum(['html', 'markdown', 'element', 'link'])\n .optional()\n .describe('Where the link was extracted from.'),\n rel: z.string().nullable().optional(),\n target: z.string().nullable().optional(),\n referrerPolicy: z.string().nullable().optional(),\n text: z\n .string()\n .nullable()\n .optional()\n .describe('Raw link text prior to normalization.'),\n});\n"
8
+ ],
9
+ "mappings": "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",
10
+ "debugId": "D22B75972928F1DD64756E2164756E21",
11
+ "names": []
12
+ }
@@ -0,0 +1,17 @@
1
+ import { z } from 'zod';
2
+ /** Metadata for a link extracted from content */
3
+ export interface LinkMetadata {
4
+ /** The text or title of the linked page, if available. */
5
+ title: string | null;
6
+ /** The URL of the link. May be absolute, relative, or a fragment depending on extraction context. */
7
+ url: string;
8
+ /** Where the link was extracted from. */
9
+ source?: 'html' | 'markdown' | 'element' | 'link' | undefined;
10
+ rel?: string | null | undefined;
11
+ target?: string | null | undefined;
12
+ referrerPolicy?: string | null | undefined;
13
+ /** Raw link text prior to normalization. */
14
+ text?: string | null | undefined;
15
+ }
16
+ export declare const linkMetadataSchema: z.ZodType<LinkMetadata>;
17
+ //# sourceMappingURL=link-metadata.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"link-metadata.d.ts","sourceRoot":"","sources":["../../src/tool-parameters/link-metadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,iDAAiD;AACjD,MAAM,WAAW,YAAY;IAC3B,0DAA0D;IAC1D,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,qGAAqG;IACrG,GAAG,EAAE,MAAM,CAAC;IACZ,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAAC;IAC9D,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAChC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACnC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC3C,4CAA4C;IAC5C,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CAClC;AAED,eAAO,MAAM,kBAAkB,EAAE,CAAC,CAAC,OAAO,CAAC,YAAY,CAuBrD,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Circular reference tracker using WeakSet
3
+ */
4
+ export declare class CircularTracker {
5
+ private seen;
6
+ /**
7
+ * Check if object has been seen before
8
+ */
9
+ has(obj: object): boolean;
10
+ /**
11
+ * Mark object as seen
12
+ */
13
+ add(obj: object): void;
14
+ /**
15
+ * Create a child tracker (for nested coercion)
16
+ */
17
+ child(): CircularTracker;
18
+ }
19
+ /**
20
+ * Check if a value can have circular references
21
+ */
22
+ export declare function canBeCircular(value: unknown): value is object;
23
+ /**
24
+ * Throw error for circular reference
25
+ */
26
+ export declare function throwCircular(): never;
27
+ //# sourceMappingURL=circular.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"circular.d.ts","sourceRoot":"","sources":["../../src/utilities/circular.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,IAAI,CAAyB;IAErC;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAItB;;OAEG;IACH,KAAK,IAAI,eAAe;CAKzB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAE7D;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,KAAK,CAErC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Try to parse a JSON string
3
+ */
4
+ export declare function tryParseJSON(value: string): unknown;
5
+ /**
6
+ * Try to parse a delimited string to array (CSV, semicolon, pipe)
7
+ */
8
+ export declare function tryParseCSV(value: string): string[] | null;
9
+ /**
10
+ * Try to parse a hex/octal/binary number string
11
+ */
12
+ export declare function tryParseSpecialNumber(value: string): number | null;
13
+ /**
14
+ * Try to parse a string to number
15
+ */
16
+ export declare function tryParseNumber(value: string): number | null;
17
+ /**
18
+ * Check if a string looks like a boolean
19
+ */
20
+ export declare function isBooleanLikeString(value: string): boolean;
21
+ /**
22
+ * Normalize a string for case-insensitive comparison
23
+ */
24
+ export declare function normalizeString(value: string): string;
25
+ /**
26
+ * Check if value is falsy for null coercion
27
+ */
28
+ export declare function isFalsyForNull(value: unknown): boolean;
29
+ //# sourceMappingURL=parsers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parsers.d.ts","sourceRoot":"","sources":["../../src/utilities/parsers.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAMnD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAc1D;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAmBlE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAa3D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAkB1D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAErD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAyBtD"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Try to extract a primitive value from an object using special methods
3
+ * Priority: Symbol.toPrimitive > toJSON > toString > valueOf
4
+ */
5
+ export declare function extractPrimitiveValue(value: unknown, hint?: 'string' | 'number' | 'default'): unknown;
6
+ /**
7
+ * Check if object has a specific special method
8
+ */
9
+ export declare function hasSpecialMethod(value: unknown, method: string): boolean;
10
+ /**
11
+ * Try to get a Date value from an object using getTime() or toISOString()
12
+ */
13
+ export declare function extractDateValue(value: unknown): Date | null;
14
+ //# sourceMappingURL=special-methods.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"special-methods.d.ts","sourceRoot":"","sources":["../../src/utilities/special-methods.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,OAAO,EACd,IAAI,GAAE,QAAQ,GAAG,QAAQ,GAAG,SAAqB,GAChD,OAAO,CAwET;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAGxE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,GAAG,IAAI,CAgC5D"}
@@ -0,0 +1,11 @@
1
+ export declare function toString(value: unknown, fallbackOrCtx?: string | unknown): string;
2
+ export declare function toBoolean(value: unknown, defaultValue?: boolean): boolean;
3
+ export declare function toNumber(value: unknown, defaultValue?: number, options?: {
4
+ min?: number;
5
+ max?: number;
6
+ int?: boolean;
7
+ }): number;
8
+ export declare function toArray(value: unknown): unknown[];
9
+ export declare function toNumberArray(value: unknown): number[];
10
+ export declare function toEnum<T extends string>(value: unknown, values: readonly T[], defaultValue?: T): T;
11
+ //# sourceMappingURL=type-coercion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type-coercion.d.ts","sourceRoot":"","sources":["../../src/utilities/type-coercion.ts"],"names":[],"mappings":"AAgBA,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAgCjF;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,YAAY,UAAQ,GAAG,OAAO,CAmBvE;AAED,wBAAgB,QAAQ,CACtB,KAAK,EAAE,OAAO,EACd,YAAY,SAAI,EAChB,OAAO,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAA;CAAE,GACtD,MAAM,CAwCR;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,EAAE,CAwCjD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,CAKtD;AAED,wBAAgB,MAAM,CAAC,CAAC,SAAS,MAAM,EACrC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,SAAS,CAAC,EAAE,EACpB,YAAY,CAAC,EAAE,CAAC,GACf,CAAC,CAyBH"}
@@ -0,0 +1,26 @@
1
+ import * as z from 'zod';
2
+ /**
3
+ * Get the Zod type name from a schema (Zod v4 uses _def.type)
4
+ */
5
+ export declare function getZodTypeName(schema: z.ZodTypeAny): string;
6
+ /**
7
+ * Check if a schema is a specific Zod type
8
+ */
9
+ export declare function isZodType(schema: z.ZodTypeAny, typeName: string): boolean;
10
+ /**
11
+ * Unwrap a schema from optional/nullable/default/catch wrappers
12
+ */
13
+ export declare function unwrapSchema(schema: z.ZodTypeAny): z.ZodTypeAny;
14
+ /**
15
+ * Check if value is a plain object (not Date, Array, Map, Set, etc.)
16
+ */
17
+ export declare function isPlainObject(value: unknown): value is Record<string, unknown>;
18
+ /**
19
+ * Check if value is an array-like object
20
+ */
21
+ export declare function isArrayLike(value: unknown): boolean;
22
+ /**
23
+ * Check if value is iterable
24
+ */
25
+ export declare function isIterable(value: unknown): value is Iterable<unknown>;
26
+ //# sourceMappingURL=type-detection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type-detection.d.ts","sourceRoot":"","sources":["../../src/utilities/type-detection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAIzB;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,GAAG,MAAM,CAgB3D;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEzE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAoB/D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAY9E;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAInD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAAC,OAAO,CAAC,CAGrE"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Consolidated type guards used across the codebase.
3
+ */
4
+ export declare function instanceOf(value: unknown, constructor: new (...args: unknown[]) => unknown): boolean;
5
+ export declare function isBuiltIn(value: object): boolean;
6
+ export declare function isError<T extends ErrorConstructor>(value: unknown, errorType?: T): value is InstanceType<T>;
7
+ /** Value is an object and not null. */
8
+ export declare function isObject(value: unknown): value is object;
9
+ /** Object-like (object or function, not null). */
10
+ export declare function isObjectLike(value: unknown): value is object;
11
+ /**
12
+ * Plain object (not array, not built-in like Date/Map, has Object prototype or null).
13
+ */
14
+ export declare function isPlainObject(value: unknown): value is Record<string, unknown>;
15
+ export declare function isPromise(value: unknown): value is Promise<unknown>;
16
+ /**
17
+ * Type guard to filter out undefined/null values and narrow to numbers.
18
+ *
19
+ * Useful for Chrome API calls that require numeric IDs (tabs, groups, windows).
20
+ * Replaces inline `(id): id is number => typeof id === 'number'` patterns.
21
+ *
22
+ * Note: Returns true for NaN (typeof NaN === 'number'). Callers should validate
23
+ * further if NaN is problematic for their use case.
24
+ *
25
+ * @example
26
+ * const tabIds = tabs.map(t => t.id).filter(isDefinedNumber);
27
+ * await chrome.tabs.remove(tabIds);
28
+ * // Type: number[] (not (number | undefined)[])
29
+ *
30
+ * @example
31
+ * const groupIds = groups.map(g => g.id).filter(isDefinedNumber);
32
+ * await Promise.all(groupIds.map(id => TabGroup.get(id)));
33
+ */
34
+ export declare function isDefinedNumber(value: unknown): value is number;
35
+ //# sourceMappingURL=type-guards.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type-guards.d.ts","sourceRoot":"","sources":["../../src/utilities/type-guards.ts"],"names":[],"mappings":"AAAA;;GAEG;AAkBH,wBAAgB,UAAU,CACxB,KAAK,EAAE,OAAO,EACd,WAAW,EAAE,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,GAC/C,OAAO,CAET;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED,wBAAgB,OAAO,CAAC,CAAC,SAAS,gBAAgB,EAChD,KAAK,EAAE,OAAO,EACd,SAAS,GAAY,CAAC,GACrB,KAAK,IAAI,YAAY,CAAC,CAAC,CAAC,CAE1B;AAED,uCAAuC;AACvC,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAExD;AAED,kDAAkD;AAClD,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAE5D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAI9E;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC,CAMnE;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAE/D"}