@fairspec/agent 0.9.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 (90) hide show
  1. package/LICENSE.md +9 -0
  2. package/README.md +3 -0
  3. package/build/actions/tableSchema/asHtml.d.ts +4 -0
  4. package/build/actions/tableSchema/asHtml.js +82 -0
  5. package/build/actions/tableSchema/asHtml.spec.d.ts +1 -0
  6. package/build/actions/tableSchema/asHtml.spec.js +356 -0
  7. package/build/actions/tableSchema/asMarkdown.d.ts +4 -0
  8. package/build/actions/tableSchema/asMarkdown.js +65 -0
  9. package/build/actions/tableSchema/asMarkdown.spec.d.ts +1 -0
  10. package/build/actions/tableSchema/asMarkdown.spec.js +133 -0
  11. package/build/document/Document.d.ts +2 -0
  12. package/build/document/Document.js +2 -0
  13. package/build/document/index.d.ts +3 -0
  14. package/build/document/index.js +3 -0
  15. package/build/document/types/Base.d.ts +3 -0
  16. package/build/document/types/Base.js +2 -0
  17. package/build/document/types/Json.d.ts +5 -0
  18. package/build/document/types/Json.js +2 -0
  19. package/build/document/validate.d.ts +5 -0
  20. package/build/document/validate.js +23 -0
  21. package/build/document/validate.spec.d.ts +1 -0
  22. package/build/document/validate.spec.js +71 -0
  23. package/build/index.d.ts +1 -0
  24. package/build/index.js +2 -0
  25. package/build/package.json +39 -0
  26. package/build/plugin.d.ts +6 -0
  27. package/build/plugin.js +15 -0
  28. package/build/schema/convert/toHtml.d.ts +4 -0
  29. package/build/schema/convert/toHtml.js +107 -0
  30. package/build/schema/convert/toHtml.spec.d.ts +1 -0
  31. package/build/schema/convert/toHtml.spec.js +432 -0
  32. package/build/schema/convert/toMarkdown.d.ts +4 -0
  33. package/build/schema/convert/toMarkdown.js +75 -0
  34. package/build/schema/convert/toMarkdown.spec.d.ts +1 -0
  35. package/build/schema/convert/toMarkdown.spec.js +137 -0
  36. package/build/schema/index.d.ts +2 -0
  37. package/build/schema/index.js +3 -0
  38. package/build/server.d.ts +2 -0
  39. package/build/server.js +29 -0
  40. package/build/tableSchema/convert/toHtml.d.ts +4 -0
  41. package/build/tableSchema/convert/toHtml.js +80 -0
  42. package/build/tableSchema/convert/toHtml.spec.d.ts +1 -0
  43. package/build/tableSchema/convert/toHtml.spec.js +375 -0
  44. package/build/tableSchema/convert/toMarkdown.d.ts +4 -0
  45. package/build/tableSchema/convert/toMarkdown.js +57 -0
  46. package/build/tableSchema/convert/toMarkdown.spec.d.ts +1 -0
  47. package/build/tableSchema/convert/toMarkdown.spec.js +141 -0
  48. package/build/tableSchema/index.d.ts +2 -0
  49. package/build/tableSchema/index.js +3 -0
  50. package/build/tools/data/validate.d.ts +971 -0
  51. package/build/tools/data/validate.js +15 -0
  52. package/build/tools/data/validate.spec.d.ts +1 -0
  53. package/build/tools/data/validate.spec.js +228 -0
  54. package/build/tools/dataSchema/infer.d.ts +797 -0
  55. package/build/tools/dataSchema/infer.js +15 -0
  56. package/build/tools/dataSchema/infer.spec.d.ts +1 -0
  57. package/build/tools/dataSchema/infer.spec.js +215 -0
  58. package/build/tools/dataSchema/validate.d.ts +177 -0
  59. package/build/tools/dataSchema/validate.js +17 -0
  60. package/build/tools/dataSchema/validate.spec.d.ts +1 -0
  61. package/build/tools/dataSchema/validate.spec.js +148 -0
  62. package/build/tools/dataset/infer.d.ts +1985 -0
  63. package/build/tools/dataset/infer.js +15 -0
  64. package/build/tools/dataset/infer.spec.d.ts +1 -0
  65. package/build/tools/dataset/infer.spec.js +181 -0
  66. package/build/tools/dataset/validate.d.ts +1168 -0
  67. package/build/tools/dataset/validate.js +17 -0
  68. package/build/tools/dataset/validate.spec.d.ts +1 -0
  69. package/build/tools/dataset/validate.spec.js +212 -0
  70. package/build/tools/dialect/infer.d.ts +889 -0
  71. package/build/tools/dialect/infer.js +16 -0
  72. package/build/tools/dialect/infer.spec.d.ts +1 -0
  73. package/build/tools/dialect/infer.spec.js +138 -0
  74. package/build/tools/table/query.d.ts +798 -0
  75. package/build/tools/table/query.js +24 -0
  76. package/build/tools/table/query.spec.d.ts +1 -0
  77. package/build/tools/table/query.spec.js +138 -0
  78. package/build/tools/table/validate.d.ts +999 -0
  79. package/build/tools/table/validate.js +16 -0
  80. package/build/tools/table/validate.spec.d.ts +1 -0
  81. package/build/tools/table/validate.spec.js +106 -0
  82. package/build/tools/tableSchema/infer.d.ts +1316 -0
  83. package/build/tools/tableSchema/infer.js +16 -0
  84. package/build/tools/tableSchema/infer.spec.d.ts +1 -0
  85. package/build/tools/tableSchema/infer.spec.js +152 -0
  86. package/build/tools/tableSchema/validate.d.ts +177 -0
  87. package/build/tools/tableSchema/validate.js +17 -0
  88. package/build/tools/tableSchema/validate.spec.d.ts +1 -0
  89. package/build/tools/tableSchema/validate.spec.js +121 -0
  90. package/package.json +39 -0
@@ -0,0 +1,16 @@
1
+ import { InferTableSchemaOptions, inferTableSchema, Resource, TableSchema, } from "@fairspec/library";
2
+ import { createTool } from "@mastra/core/tools";
3
+ import { z } from "zod";
4
+ export const inferTableSchemaTool = createTool({
5
+ id: "infer-table-schema",
6
+ description: "Infer a table schema from table resource data. Analyzes the data to determine column types and constraints.",
7
+ inputSchema: z.object({
8
+ resource: Resource.describe("The table resource to infer schema from"),
9
+ options: InferTableSchemaOptions.optional().describe("Schema inference options"),
10
+ }),
11
+ outputSchema: TableSchema.optional(),
12
+ execute: async (input) => {
13
+ return await inferTableSchema(input.resource, input.options);
14
+ },
15
+ });
16
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5mZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90b29scy90YWJsZVNjaGVtYS9pbmZlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLGdCQUFnQixFQUNoQixRQUFRLEVBQ1IsV0FBVyxHQUNaLE1BQU0sbUJBQW1CLENBQUE7QUFDMUIsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLG9CQUFvQixDQUFBO0FBQy9DLE9BQU8sRUFBRSxDQUFDLEVBQUUsTUFBTSxLQUFLLENBQUE7QUFFdkIsTUFBTSxDQUFDLE1BQU0sb0JBQW9CLEdBQUcsVUFBVSxDQUFDO0lBQzdDLEVBQUUsRUFBRSxvQkFBb0I7SUFDeEIsV0FBVyxFQUNULDZHQUE2RztJQUMvRyxXQUFXLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQztRQUNwQixRQUFRLEVBQUUsUUFBUSxDQUFDLFFBQVEsQ0FBQyx5Q0FBeUMsQ0FBQztRQUN0RSxPQUFPLEVBQUUsdUJBQXVCLENBQUMsUUFBUSxFQUFFLENBQUMsUUFBUSxDQUNsRCwwQkFBMEIsQ0FDM0I7S0FDRixDQUFDO0lBQ0YsWUFBWSxFQUFFLFdBQVcsQ0FBQyxRQUFRLEVBQUU7SUFDcEMsT0FBTyxFQUFFLEtBQUssRUFBQyxLQUFLLEVBQUMsRUFBRTtRQUNyQixPQUFPLE1BQU0sZ0JBQWdCLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUE7SUFDOUQsQ0FBQztDQUNGLENBQUMsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEluZmVyVGFibGVTY2hlbWFPcHRpb25zLFxuICBpbmZlclRhYmxlU2NoZW1hLFxuICBSZXNvdXJjZSxcbiAgVGFibGVTY2hlbWEsXG59IGZyb20gXCJAZmFpcnNwZWMvbGlicmFyeVwiXG5pbXBvcnQgeyBjcmVhdGVUb29sIH0gZnJvbSBcIkBtYXN0cmEvY29yZS90b29sc1wiXG5pbXBvcnQgeyB6IH0gZnJvbSBcInpvZFwiXG5cbmV4cG9ydCBjb25zdCBpbmZlclRhYmxlU2NoZW1hVG9vbCA9IGNyZWF0ZVRvb2woe1xuICBpZDogXCJpbmZlci10YWJsZS1zY2hlbWFcIixcbiAgZGVzY3JpcHRpb246XG4gICAgXCJJbmZlciBhIHRhYmxlIHNjaGVtYSBmcm9tIHRhYmxlIHJlc291cmNlIGRhdGEuIEFuYWx5emVzIHRoZSBkYXRhIHRvIGRldGVybWluZSBjb2x1bW4gdHlwZXMgYW5kIGNvbnN0cmFpbnRzLlwiLFxuICBpbnB1dFNjaGVtYTogei5vYmplY3Qoe1xuICAgIHJlc291cmNlOiBSZXNvdXJjZS5kZXNjcmliZShcIlRoZSB0YWJsZSByZXNvdXJjZSB0byBpbmZlciBzY2hlbWEgZnJvbVwiKSxcbiAgICBvcHRpb25zOiBJbmZlclRhYmxlU2NoZW1hT3B0aW9ucy5vcHRpb25hbCgpLmRlc2NyaWJlKFxuICAgICAgXCJTY2hlbWEgaW5mZXJlbmNlIG9wdGlvbnNcIixcbiAgICApLFxuICB9KSxcbiAgb3V0cHV0U2NoZW1hOiBUYWJsZVNjaGVtYS5vcHRpb25hbCgpLFxuICBleGVjdXRlOiBhc3luYyBpbnB1dCA9PiB7XG4gICAgcmV0dXJuIGF3YWl0IGluZmVyVGFibGVTY2hlbWEoaW5wdXQucmVzb3VyY2UsIGlucHV0Lm9wdGlvbnMpXG4gIH0sXG59KVxuIl19
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,152 @@
1
+ import { writeTempFile } from "@fairspec/library";
2
+ import { describe, expect, it } from "vitest";
3
+ import { inferTableSchemaTool } from "./infer.js";
4
+ describe("inferTableSchemaTool", () => {
5
+ it("validates tool structure", () => {
6
+ expect(inferTableSchemaTool.id).toBe("infer-table-schema");
7
+ expect(inferTableSchemaTool.description).toBeTruthy();
8
+ expect(inferTableSchemaTool.inputSchema).toBeTruthy();
9
+ expect(inferTableSchemaTool.outputSchema).toBeTruthy();
10
+ expect(inferTableSchemaTool.execute).toBeTypeOf("function");
11
+ });
12
+ it("infers schema from CSV file", async () => {
13
+ const path = await writeTempFile("id,name,age\n1,alice,30\n2,bob,25");
14
+ const resource = { data: path, dialect: { format: "csv" } };
15
+ const result = await inferTableSchemaTool.execute?.({
16
+ resource,
17
+ }, {});
18
+ expect.assert(result);
19
+ expect.assert(!("error" in result));
20
+ expect(result.properties).toBeDefined();
21
+ expect(result.properties?.id?.type).toBe("integer");
22
+ expect(result.properties?.name?.type).toBe("string");
23
+ expect(result.properties?.age?.type).toBe("integer");
24
+ });
25
+ it("infers schema from inline object data", async () => {
26
+ const resource = {
27
+ data: [
28
+ { id: 1, name: "alice", age: 30 },
29
+ { id: 2, name: "bob", age: 25 },
30
+ ],
31
+ };
32
+ const result = await inferTableSchemaTool.execute?.({
33
+ resource,
34
+ }, {});
35
+ expect.assert(result);
36
+ expect.assert(!("error" in result));
37
+ expect(result.properties).toBeDefined();
38
+ expect(result.properties?.id?.type).toBe("integer");
39
+ expect(result.properties?.name?.type).toBe("string");
40
+ expect(result.properties?.age?.type).toBe("integer");
41
+ });
42
+ it("infers different field types correctly", async () => {
43
+ const resource = {
44
+ data: [
45
+ { id: 1, name: "alice", score: 95.5, active: true },
46
+ { id: 2, name: "bob", score: 87.3, active: false },
47
+ ],
48
+ };
49
+ const result = await inferTableSchemaTool.execute?.({
50
+ resource,
51
+ }, {});
52
+ expect.assert(result);
53
+ expect.assert(!("error" in result));
54
+ expect(result.properties).toBeDefined();
55
+ expect(result.properties?.id?.type).toBe("integer");
56
+ expect(result.properties?.name?.type).toBe("string");
57
+ expect(result.properties?.score?.type).toBe("number");
58
+ expect(result.properties?.active?.type).toBe("boolean");
59
+ });
60
+ it("infers date fields from strings", async () => {
61
+ const resource = {
62
+ data: [
63
+ { id: 1, name: "alice", created: "2024-01-01" },
64
+ { id: 2, name: "bob", created: "2024-01-02" },
65
+ ],
66
+ };
67
+ const result = await inferTableSchemaTool.execute?.({
68
+ resource,
69
+ }, {});
70
+ expect.assert(result);
71
+ expect.assert(!("error" in result));
72
+ expect(result.properties).toBeDefined();
73
+ expect(result.properties?.id?.type).toBe("integer");
74
+ expect(result.properties?.name?.type).toBe("string");
75
+ expect(result.properties?.created?.type).toBe("string");
76
+ expect(result.properties?.created?.format).toBe("date");
77
+ });
78
+ it("respects sampleRows option", async () => {
79
+ const resource = {
80
+ data: Array.from({ length: 1000 }, (_, i) => ({
81
+ id: i,
82
+ name: `user${i}`,
83
+ })),
84
+ };
85
+ const result = await inferTableSchemaTool.execute?.({
86
+ resource,
87
+ options: { sampleRows: 10 },
88
+ }, {});
89
+ expect.assert(result);
90
+ expect.assert(!("error" in result));
91
+ expect(result.properties).toBeDefined();
92
+ expect(result.properties?.id?.type).toBe("integer");
93
+ expect(result.properties?.name?.type).toBe("string");
94
+ });
95
+ it("handles empty data", async () => {
96
+ const resource = {
97
+ data: [],
98
+ };
99
+ const result = await inferTableSchemaTool.execute?.({
100
+ resource,
101
+ }, {});
102
+ expect(result).toBeUndefined();
103
+ });
104
+ it("handles single row data", async () => {
105
+ const resource = {
106
+ data: [{ id: 1, name: "alice" }],
107
+ };
108
+ const result = await inferTableSchemaTool.execute?.({
109
+ resource,
110
+ }, {});
111
+ expect.assert(result);
112
+ expect.assert(!("error" in result));
113
+ expect(result.properties).toBeDefined();
114
+ expect(result.properties?.id?.type).toBe("integer");
115
+ expect(result.properties?.name?.type).toBe("string");
116
+ });
117
+ it("respects columnTypes option", async () => {
118
+ const resource = {
119
+ data: [
120
+ { id: "123", value: "456" },
121
+ { id: "789", value: "012" },
122
+ ],
123
+ };
124
+ const result = await inferTableSchemaTool.execute?.({
125
+ resource,
126
+ options: { columnTypes: { id: "integer", value: "integer" } },
127
+ }, {});
128
+ expect.assert(result);
129
+ expect.assert(!("error" in result));
130
+ expect(result.properties).toBeDefined();
131
+ expect(result.properties?.id?.type).toBe("integer");
132
+ expect(result.properties?.value?.type).toBe("integer");
133
+ });
134
+ it("handles time fields", async () => {
135
+ const resource = {
136
+ data: [
137
+ { id: 1, time: "14:30:00" },
138
+ { id: 2, time: "09:15:30" },
139
+ ],
140
+ };
141
+ const result = await inferTableSchemaTool.execute?.({
142
+ resource,
143
+ }, {});
144
+ expect.assert(result);
145
+ expect.assert(!("error" in result));
146
+ expect(result.properties).toBeDefined();
147
+ expect(result.properties?.id?.type).toBe("integer");
148
+ expect(result.properties?.time?.type).toBe("string");
149
+ expect(result.properties?.time?.format).toBe("time");
150
+ });
151
+ });
152
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5mZXIuc3BlYy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Rvb2xzL3RhYmxlU2NoZW1hL2luZmVyLnNwZWMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLG1CQUFtQixDQUFBO0FBQ2pELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLEVBQUUsRUFBRSxNQUFNLFFBQVEsQ0FBQTtBQUM3QyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxZQUFZLENBQUE7QUFFakQsUUFBUSxDQUFDLHNCQUFzQixFQUFFLEdBQUcsRUFBRTtJQUNwQyxFQUFFLENBQUMsMEJBQTBCLEVBQUUsR0FBRyxFQUFFO1FBQ2xDLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsb0JBQW9CLENBQUMsQ0FBQTtRQUMxRCxNQUFNLENBQUMsb0JBQW9CLENBQUMsV0FBVyxDQUFDLENBQUMsVUFBVSxFQUFFLENBQUE7UUFDckQsTUFBTSxDQUFDLG9CQUFvQixDQUFDLFdBQVcsQ0FBQyxDQUFDLFVBQVUsRUFBRSxDQUFBO1FBQ3JELE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxZQUFZLENBQUMsQ0FBQyxVQUFVLEVBQUUsQ0FBQTtRQUN0RCxNQUFNLENBQUMsb0JBQW9CLENBQUMsT0FBTyxDQUFDLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFBO0lBQzdELENBQUMsQ0FBQyxDQUFBO0lBRUYsRUFBRSxDQUFDLDZCQUE2QixFQUFFLEtBQUssSUFBSSxFQUFFO1FBQzNDLE1BQU0sSUFBSSxHQUFHLE1BQU0sYUFBYSxDQUFDLG1DQUFtQyxDQUFDLENBQUE7UUFDckUsTUFBTSxRQUFRLEdBQWEsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFBO1FBRXJFLE1BQU0sTUFBTSxHQUFHLE1BQU0sb0JB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QUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFO2dCQUMzQixFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRTthQUM1QjtTQUNGLENBQUE7UUFFRCxNQUFNLE1BQU0sR0FBRyxNQUFNLG9CQUFvQixDQUFDLE9BQU8sRUFBRSxDQUNqRDtZQUNFLFFBQVE7U0FDVCxFQUNELEVBQUUsQ0FDSCxDQUFBO1FBRUQsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQTtRQUNyQixNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxPQUFPLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQTtRQUVuQyxNQUFNLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFBO1FBQ3ZDLE1BQU0sQ0FBQyxNQUFNLENBQUMsVUFBVSxFQUFFLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUE7UUFDbkQsTUFBTSxDQUFDLE1BQU0sQ0FBQyxVQUFVLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQTtRQUNwRCxNQUFNLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRSxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFBO0lBQ3RELENBQUMsQ0FBQyxDQUFBO0FBQ0osQ0FBQyxDQUFDLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IFJlc291cmNlIH0gZnJvbSBcIkBmYWlyc3BlYy9saWJyYXJ5XCJcbmltcG9ydCB7IHdyaXRlVGVtcEZpbGUgfSBmcm9tIFwiQGZhaXJzcGVjL2xpYnJhcnlcIlxuaW1wb3J0IHsgZGVzY3JpYmUsIGV4cGVjdCwgaXQgfSBmcm9tIFwidml0ZXN0XCJcbmltcG9ydCB7IGluZmVyVGFibGVTY2hlbWFUb29sIH0gZnJvbSBcIi4vaW5mZXIudHNcIlxuXG5kZXNjcmliZShcImluZmVyVGFibGVTY2hlbWFUb29sXCIsICgpID0+IHtcbiAgaXQoXCJ2YWxpZGF0ZXMgdG9vbCBzdHJ1Y3R1cmVcIiwgKCkgPT4ge1xuICAgIGV4cGVjdChpbmZlclRhYmxlU2NoZW1hVG9vbC5pZCkudG9CZShcImluZmVyLXRhYmxlLXNjaGVtYVwiKVxuICAgIGV4cGVjdChpbmZlclRhYmxlU2NoZW1hVG9vbC5kZXNjcmlwdGlvbikudG9CZVRydXRoeSgpXG4gICAgZXhwZWN0KGluZmVyVGFibGVTY2hlbWFUb29sLmlucHV0U2NoZW1hKS50b0JlVHJ1dGh5KClcbiAgICBleHBlY3QoaW5mZXJUYWJsZVNjaGVtYVRvb2wub3V0cHV0U2NoZW1hKS50b0JlVHJ1dGh5KClcbiAgICBleHBlY3QoaW5mZXJUYWJsZVNjaGVtYVRvb2wuZXhlY3V0ZSkudG9CZVR5cGVPZihcImZ1bmN0aW9uXCIpXG4gIH0pXG5cbiAgaXQoXCJpbmZlcnMgc2NoZW1hIGZyb20gQ1NWIGZpbGVcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHBhdGggPSBhd2FpdCB3cml0ZVRlbXBGaWxlKFwiaWQsbmFtZSxhZ2VcXG4xLGFsaWNlLDMwXFxuMixib2IsMjVcIilcbiAgICBjb25zdCByZXNvdXJjZTogUmVzb3VyY2UgPSB7IGRhdGE6IHBhdGgsIGRpYWxlY3Q6IHsgZm9ybWF0OiBcImNzdlwiIH0gfVxuXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgaW5mZXJUYWJsZVNjaGVtYVRvb2wuZXhlY3V0ZT8uKFxuICAgICAge1xuICAgICAgICByZXNvdXJjZSxcbiAgICAgIH0sXG4gICAgICB7fSxcbiAgICApXG5cbiAgICBleHBlY3QuYXNzZXJ0KHJlc3VsdClcbiAgICBleHBlY3QuYXNzZXJ0KCEoXCJlcnJvclwiIGluIHJlc3VsdCkpXG5cbiAgICBleHBlY3QocmVzdWx0LnByb3BlcnRpZXMpLnRvQmVEZWZpbmVkKClcbiAgICBleHBlY3QocmVzdWx0LnByb3BlcnRpZXM/LmlkPy50eXBlKS50b0JlKFwiaW50ZWdlclwiKVxuICAgIGV4cGVjdChyZXN1bHQucHJvcGVydGllcz8ubmFtZT8udHlwZSkudG9CZShcInN0cmluZ1wiKVxuICAgIGV4cGVjdChyZXN1bHQucHJvcGVydGllcz8uYWdlPy50eXBlKS50b0JlKFwiaW50ZWdlclwiKVxuICB9KVxuXG4gIGl0KFwiaW5mZXJzIHNjaGVtYSBmcm9tIGlubGluZSBvYmplY3QgZGF0YVwiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcmVzb3VyY2U6IFJlc291cmNlID0ge1xuICAgICAgZGF0YTogW1xuICAgICAgICB7IGlkOiAxLCBuYW1lOiBcImFsaWNlXCIsIGFnZTogMzAgfSxcbiAgICAgICAgeyBpZDogMiwgbmFtZTogXCJib2JcIiwgYWdlOiAyNSB9LFxuICAgICAgXSxcbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBpbmZlclRhYmxlU2NoZW1hVG9vbC5leGVjdXRlPy4oXG4gICAgICB7XG4gICAgICAgIHJlc291cmNlLFxuICAgICAgfSxcbiAgICAgIHt9LFxuICAgIClcblxuICAgIGV4cGVjdC5hc3NlcnQocmVzdWx0KVxuICAgIGV4cGVjdC5hc3NlcnQoIShcImVycm9yXCIgaW4gcmVzdWx0KSlcblxuICAgIGV4cGVjdChyZXN1bHQucHJvcGVydGllcykudG9CZURlZmluZWQoKVxuICAgIGV4cGVjdChyZXN1bHQucHJvcGVydGllcz8uaWQ/LnR5cGUpLnRvQmUoXCJpbnRlZ2VyXCIpXG4gICAgZXhwZWN0KHJlc3VsdC5wcm9wZXJ0aWVzPy5uYW1lPy50eXBlKS50b0JlKFwic3RyaW5nXCIpXG4gICAgZXhwZWN0KHJlc3VsdC5wcm9wZXJ0aWVzPy5hZ2U/LnR5cGUpLnRvQmUoXCJpbnRlZ2VyXCIpXG4gIH0pXG5cbiAgaXQoXCJpbmZlcnMgZGlmZmVyZW50IGZpZWxkIHR5cGVzIGNvcnJlY3RseVwiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcmVzb3VyY2U6IFJlc291cmNlID0ge1xuICAgICAgZGF0YTogW1xuICAgICAgICB7IGlkOiAxLCBuYW1lOiBcImFsaWNlXCIsIHNjb3JlOiA5NS41LCBhY3RpdmU6IHRydWUgfSxcbiAgICAgICAgeyBpZDogMiwgbmFtZTogXCJib2JcIiwgc2NvcmU6IDg3LjMsIGFjdGl2ZTogZmFsc2UgfSxcbiAgICAgIF0sXG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgaW5mZXJUYWJsZVNjaGVtYVRvb2wuZXhlY3V0ZT8uKFxuICAgICAge1xuICAgICAgICByZXNvdXJjZSxcbiAgICAgIH0sXG4gICAgICB7fSxcbiAgICApXG5cbiAgICBleHBlY3QuYXNzZXJ0KHJlc3VsdClcbiAgICBleHBlY3QuYXNzZXJ0KCEoXCJlcnJvclwiIGluIHJlc3VsdCkpXG5cbiAgICBleHBlY3QocmVzdWx0LnByb3BlcnRpZXMpLnRvQmVEZWZpbmVkKClcbiAgICBleHBlY3QocmVzdWx0LnByb3BlcnRpZXM/LmlkPy50eXBlKS50b0JlKFwiaW50ZWdlclwiKVxuICAgIGV4cGVjdChyZXN1bHQucHJvcGVydGllcz8ubmFtZT8udHlwZSkudG9CZShcInN0cmluZ1wiKVxuICAgIGV4cGVjdChyZXN1bHQucHJvcGVydGllcz8uc2NvcmU/LnR5cGUpLnRvQmUoXCJudW1iZXJcIilcbiAgICBleHBlY3QocmVzdWx0LnByb3BlcnRpZXM/LmFjdGl2ZT8udHlwZSkudG9CZShcImJvb2xlYW5cIilcbiAgfSlcblxuICBpdChcImluZmVycyBkYXRlIGZpZWxkcyBmcm9tIHN0cmluZ3NcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHJlc291cmNlOiBSZXNvdXJjZSA9IHtcbiAgICAgIGRhdGE6IFtcbiAgICAgICAgeyBpZDogMSwgbmFtZTogXCJhbGljZVwiLCBjcmVhdGVkOiBcIjIwMjQtMDEtMDFcIiB9LFxuICAgICAgICB7IGlkOiAyLCBuYW1lOiBcImJvYlwiLCBjcmVhdGVkOiBcIjIwMjQtMDEtMDJcIiB9LFxuICAgICAgXSxcbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBpbmZlclRhYmxlU2NoZW1hVG9vbC5leGVjdXRlPy4oXG4gICAgICB7XG4gICAgICAgIHJlc291cmNlLFxuICAgICAgfSxcbiAgICAgIHt9LFxuICAgIClcblxuICAgIGV4cGVjdC5hc3NlcnQocmVzdWx0KVxuICAgIGV4cGVjdC5hc3NlcnQoIShcImVycm9yXCIgaW4gcmVzdWx0KSlcblxuICAgIGV4cGVjdChyZXN1bHQucHJvcGVydGllcykudG9CZURlZmluZWQoKVxuICAgIGV4cGVjdChyZXN1bHQucHJvcGVydGllcz8uaWQ/LnR5cGUpLnRvQmUoXCJpbnRlZ2VyXCIpXG4gICAgZXhwZWN0KHJlc3VsdC5wcm9wZXJ0aWVzPy5uYW1lPy50eXBlKS50b0JlKFwic3RyaW5nXCIpXG4gICAgZXhwZWN0KHJlc3VsdC5wcm9wZXJ0aWVzPy5jcmVhdGVkPy50eXBlKS50b0JlKFwic3RyaW5nXCIpXG4gICAgZXhwZWN0KHJlc3VsdC5wcm9wZXJ0aWVzPy5jcmVhdGVkPy5mb3JtYXQpLnRvQmUoXCJkYXRlXCIpXG4gIH0pXG5cbiAgaXQoXCJyZXNwZWN0cyBzYW1wbGVSb3dzIG9wdGlvblwiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcmVzb3VyY2U6IFJlc291cmNlID0ge1xuICAgICAgZGF0YTogQXJyYXkuZnJvbSh7IGxlbmd0aDogMTAwMCB9LCAoXywgaSkgPT4gKHtcbiAgICAgICAgaWQ6IGksXG4gICAgICAgIG5hbWU6IGB1c2VyJHtpfWAsXG4gICAgICB9KSksXG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgaW5mZXJUYWJsZVNjaGVtYVRvb2wuZXhlY3V0ZT8uKFxuICAgICAge1xuICAgICAgICByZXNvdXJjZSxcbiAgICAgICAgb3B0aW9uczogeyBzYW1wbGVSb3dzOiAxMCB9LFxuICAgICAgfSxcbiAgICAgIHt9LFxuICAgIClcblxuICAgIGV4cGVjdC5hc3NlcnQocmVzdWx0KVxuICAgIGV4cGVjdC5hc3NlcnQoIShcImVycm9yXCIgaW4gcmVzdWx0KSlcblxuICAgIGV4cGVjdChyZXN1bHQucHJvcGVydGllcykudG9CZURlZmluZWQoKVxuICAgIGV4cGVjdChyZXN1bHQucHJvcGVydGllcz8uaWQ/LnR5cGUpLnRvQmUoXCJpbnRlZ2VyXCIpXG4gICAgZXhwZWN0KHJlc3VsdC5wcm9wZXJ0aWVzPy5uYW1lPy50eXBlKS50b0JlKFwic3RyaW5nXCIpXG4gIH0pXG5cbiAgaXQoXCJoYW5kbGVzIGVtcHR5IGRhdGFcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHJlc291cmNlOiBSZXNvdXJjZSA9IHtcbiAgICAgIGRhdGE6IFtdLFxuICAgIH1cblxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGluZmVyVGFibGVTY2hlbWFUb29sLmV4ZWN1dGU/LihcbiAgICAgIHtcbiAgICAgICAgcmVzb3VyY2UsXG4gICAgICB9LFxuICAgICAge30sXG4gICAgKVxuXG4gICAgZXhwZWN0KHJlc3VsdCkudG9CZVVuZGVmaW5lZCgpXG4gIH0pXG5cbiAgaXQoXCJoYW5kbGVzIHNpbmdsZSByb3cgZGF0YVwiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcmVzb3VyY2U6IFJlc291cmNlID0ge1xuICAgICAgZGF0YTogW3sgaWQ6IDEsIG5hbWU6IFwiYWxpY2VcIiB9XSxcbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBpbmZlclRhYmxlU2NoZW1hVG9vbC5leGVjdXRlPy4oXG4gICAgICB7XG4gICAgICAgIHJlc291cmNlLFxuICAgICAgfSxcbiAgICAgIHt9LFxuICAgIClcblxuICAgIGV4cGVjdC5hc3NlcnQocmVzdWx0KVxuICAgIGV4cGVjdC5hc3NlcnQoIShcImVycm9yXCIgaW4gcmVzdWx0KSlcblxuICAgIGV4cGVjdChyZXN1bHQucHJvcGVydGllcykudG9CZURlZmluZWQoKVxuICAgIGV4cGVjdChyZXN1bHQucHJvcGVydGllcz8uaWQ/LnR5cGUpLnRvQmUoXCJpbnRlZ2VyXCIpXG4gICAgZXhwZWN0KHJlc3VsdC5wcm9wZXJ0aWVzPy5uYW1lPy50eXBlKS50b0JlKFwic3RyaW5nXCIpXG4gIH0pXG5cbiAgaXQoXCJyZXNwZWN0cyBjb2x1bW5UeXBlcyBvcHRpb25cIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHJlc291cmNlOiBSZXNvdXJjZSA9IHtcbiAgICAgIGRhdGE6IFtcbiAgICAgICAgeyBpZDogXCIxMjNcIiwgdmFsdWU6IFwiNDU2XCIgfSxcbiAgICAgICAgeyBpZDogXCI3ODlcIiwgdmFsdWU6IFwiMDEyXCIgfSxcbiAgICAgIF0sXG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgaW5mZXJUYWJsZVNjaGVtYVRvb2wuZXhlY3V0ZT8uKFxuICAgICAge1xuICAgICAgICByZXNvdXJjZSxcbiAgICAgICAgb3B0aW9uczogeyBjb2x1bW5UeXBlczogeyBpZDogXCJpbnRlZ2VyXCIsIHZhbHVlOiBcImludGVnZXJcIiB9IH0sXG4gICAgICB9LFxuICAgICAge30sXG4gICAgKVxuXG4gICAgZXhwZWN0LmFzc2VydChyZXN1bHQpXG4gICAgZXhwZWN0LmFzc2VydCghKFwiZXJyb3JcIiBpbiByZXN1bHQpKVxuXG4gICAgZXhwZWN0KHJlc3VsdC5wcm9wZXJ0aWVzKS50b0JlRGVmaW5lZCgpXG4gICAgZXhwZWN0KHJlc3VsdC5wcm9wZXJ0aWVzPy5pZD8udHlwZSkudG9CZShcImludGVnZXJcIilcbiAgICBleHBlY3QocmVzdWx0LnByb3BlcnRpZXM/LnZhbHVlPy50eXBlKS50b0JlKFwiaW50ZWdlclwiKVxuICB9KVxuXG4gIGl0KFwiaGFuZGxlcyB0aW1lIGZpZWxkc1wiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcmVzb3VyY2U6IFJlc291cmNlID0ge1xuICAgICAgZGF0YTogW1xuICAgICAgICB7IGlkOiAxLCB0aW1lOiBcIjE0OjMwOjAwXCIgfSxcbiAgICAgICAgeyBpZDogMiwgdGltZTogXCIwOToxNTozMFwiIH0sXG4gICAgICBdLFxuICAgIH1cblxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGluZmVyVGFibGVTY2hlbWFUb29sLmV4ZWN1dGU/LihcbiAgICAgIHtcbiAgICAgICAgcmVzb3VyY2UsXG4gICAgICB9LFxuICAgICAge30sXG4gICAgKVxuXG4gICAgZXhwZWN0LmFzc2VydChyZXN1bHQpXG4gICAgZXhwZWN0LmFzc2VydCghKFwiZXJyb3JcIiBpbiByZXN1bHQpKVxuXG4gICAgZXhwZWN0KHJlc3VsdC5wcm9wZXJ0aWVzKS50b0JlRGVmaW5lZCgpXG4gICAgZXhwZWN0KHJlc3VsdC5wcm9wZXJ0aWVzPy5pZD8udHlwZSkudG9CZShcImludGVnZXJcIilcbiAgICBleHBlY3QocmVzdWx0LnByb3BlcnRpZXM/LnRpbWU/LnR5cGUpLnRvQmUoXCJzdHJpbmdcIilcbiAgICBleHBlY3QocmVzdWx0LnByb3BlcnRpZXM/LnRpbWU/LmZvcm1hdCkudG9CZShcInRpbWVcIilcbiAgfSlcbn0pXG4iXX0=
@@ -0,0 +1,177 @@
1
+ export declare const validateTableSchemaTool: import("@mastra/core/tools").Tool<{
2
+ source: string | Record<string, unknown>;
3
+ }, {
4
+ valid: boolean;
5
+ errors: ({
6
+ type: "metadata";
7
+ message: string;
8
+ jsonPointer: string;
9
+ resourceName?: string | undefined;
10
+ } | {
11
+ type: "resource/missing";
12
+ referencingResourceName: string;
13
+ resourceName?: string | undefined;
14
+ } | {
15
+ type: "resource/type";
16
+ expectedResourceType: "data" | "table";
17
+ resourceName?: string | undefined;
18
+ referencingResourceName?: string | undefined;
19
+ } | {
20
+ type: "column/missing";
21
+ columnName: string;
22
+ resourceName?: string | undefined;
23
+ } | {
24
+ type: "column/type";
25
+ columnName: string;
26
+ expectedColumnType: "string" | "number" | "boolean" | "object" | "unknown" | "date" | "array" | "url" | "integer" | "categorical" | "list" | "date-time" | "time" | "base64" | "hex" | "email" | "duration" | "wkt" | "wkb" | "decimal" | "geojson" | "topojson";
27
+ actualColumnType: "string" | "number" | "boolean" | "object" | "unknown" | "date" | "array" | "url" | "integer" | "categorical" | "list" | "date-time" | "time" | "base64" | "hex" | "email" | "duration" | "wkt" | "wkb" | "decimal" | "geojson" | "topojson";
28
+ resourceName?: string | undefined;
29
+ } | {
30
+ type: "row/primaryKey";
31
+ rowNumber: number;
32
+ columnNames: string[];
33
+ resourceName?: string | undefined;
34
+ } | {
35
+ type: "row/uniqueKey";
36
+ rowNumber: number;
37
+ columnNames: string[];
38
+ resourceName?: string | undefined;
39
+ } | {
40
+ columnName: string;
41
+ rowNumber: number;
42
+ cell: string;
43
+ type: "cell/type";
44
+ columnType: "string" | "number" | "boolean" | "object" | "unknown" | "date" | "array" | "url" | "integer" | "categorical" | "list" | "date-time" | "time" | "base64" | "hex" | "email" | "duration" | "wkt" | "wkb" | "decimal" | "geojson" | "topojson";
45
+ resourceName?: string | undefined;
46
+ } | {
47
+ columnName: string;
48
+ rowNumber: number;
49
+ cell: string;
50
+ type: "cell/required";
51
+ resourceName?: string | undefined;
52
+ } | {
53
+ columnName: string;
54
+ rowNumber: number;
55
+ cell: string;
56
+ type: "cell/minimum";
57
+ minimum: string;
58
+ resourceName?: string | undefined;
59
+ } | {
60
+ columnName: string;
61
+ rowNumber: number;
62
+ cell: string;
63
+ type: "cell/maximum";
64
+ maximum: string;
65
+ resourceName?: string | undefined;
66
+ } | {
67
+ columnName: string;
68
+ rowNumber: number;
69
+ cell: string;
70
+ type: "cell/exclusiveMinimum";
71
+ minimum: string;
72
+ resourceName?: string | undefined;
73
+ } | {
74
+ columnName: string;
75
+ rowNumber: number;
76
+ cell: string;
77
+ type: "cell/exclusiveMaximum";
78
+ maximum: string;
79
+ resourceName?: string | undefined;
80
+ } | {
81
+ columnName: string;
82
+ rowNumber: number;
83
+ cell: string;
84
+ type: "cell/multipleOf";
85
+ multipleOf: number;
86
+ resourceName?: string | undefined;
87
+ } | {
88
+ columnName: string;
89
+ rowNumber: number;
90
+ cell: string;
91
+ type: "cell/minLength";
92
+ minLength: number;
93
+ resourceName?: string | undefined;
94
+ } | {
95
+ columnName: string;
96
+ rowNumber: number;
97
+ cell: string;
98
+ type: "cell/maxLength";
99
+ maxLength: number;
100
+ resourceName?: string | undefined;
101
+ } | {
102
+ columnName: string;
103
+ rowNumber: number;
104
+ cell: string;
105
+ type: "cell/minItems";
106
+ minItems: number;
107
+ resourceName?: string | undefined;
108
+ } | {
109
+ columnName: string;
110
+ rowNumber: number;
111
+ cell: string;
112
+ type: "cell/maxItems";
113
+ maxItems: number;
114
+ resourceName?: string | undefined;
115
+ } | {
116
+ columnName: string;
117
+ rowNumber: number;
118
+ cell: string;
119
+ type: "cell/pattern";
120
+ pattern: string;
121
+ resourceName?: string | undefined;
122
+ } | {
123
+ columnName: string;
124
+ rowNumber: number;
125
+ cell: string;
126
+ type: "cell/unique";
127
+ resourceName?: string | undefined;
128
+ } | {
129
+ columnName: string;
130
+ rowNumber: number;
131
+ cell: string;
132
+ type: "cell/const";
133
+ const: string;
134
+ resourceName?: string | undefined;
135
+ } | {
136
+ columnName: string;
137
+ rowNumber: number;
138
+ cell: string;
139
+ type: "cell/enum";
140
+ enum: string[];
141
+ resourceName?: string | undefined;
142
+ } | {
143
+ columnName: string;
144
+ rowNumber: number;
145
+ cell: string;
146
+ type: "cell/json";
147
+ message: string;
148
+ jsonPointer: string;
149
+ resourceName?: string | undefined;
150
+ } | {
151
+ type: "foreignKey";
152
+ foreignKey: {
153
+ columns: string[];
154
+ reference: {
155
+ columns: string[];
156
+ resource?: string | undefined;
157
+ };
158
+ };
159
+ cells: string[];
160
+ resourceName?: string | undefined;
161
+ } | {
162
+ type: "data";
163
+ message: string;
164
+ jsonPointer: string;
165
+ resourceName?: string | undefined;
166
+ } | {
167
+ type: "file/textual";
168
+ resourceName?: string | undefined;
169
+ actualEncoding?: string | undefined;
170
+ } | {
171
+ type: "file/integrity";
172
+ hashType: string;
173
+ expectedHash: string;
174
+ actualHash: string;
175
+ resourceName?: string | undefined;
176
+ })[];
177
+ }, unknown, unknown, import("@mastra/core/tools").ToolExecutionContext<unknown, unknown, unknown>, "validate-table-schema", unknown>;
@@ -0,0 +1,17 @@
1
+ import { Descriptor, Report, validateTableSchema } from "@fairspec/library";
2
+ import { createTool } from "@mastra/core/tools";
3
+ import { z } from "zod";
4
+ export const validateTableSchemaTool = createTool({
5
+ id: "validate-table-schema",
6
+ description: "Validate a table schema against the Fairspec Table Schema specification. Returns validation report with errors if any.",
7
+ inputSchema: z.object({
8
+ source: z
9
+ .union([Descriptor, z.string()])
10
+ .describe("The table schema to validate (descriptor object or file path)"),
11
+ }),
12
+ outputSchema: Report,
13
+ execute: async (input) => {
14
+ return await validateTableSchema(input.source);
15
+ },
16
+ });
17
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90b29scy90YWJsZVNjaGVtYS92YWxpZGF0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLG1CQUFtQixDQUFBO0FBQzNFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQTtBQUMvQyxPQUFPLEVBQUUsQ0FBQyxFQUFFLE1BQU0sS0FBSyxDQUFBO0FBRXZCLE1BQU0sQ0FBQyxNQUFNLHVCQUF1QixHQUFHLFVBQVUsQ0FBQztJQUNoRCxFQUFFLEVBQUUsdUJBQXVCO0lBQzNCLFdBQVcsRUFDVCx3SEFBd0g7SUFDMUgsV0FBVyxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUM7UUFDcEIsTUFBTSxFQUFFLENBQUM7YUFDTixLQUFLLENBQUMsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7YUFDL0IsUUFBUSxDQUNQLCtEQUErRCxDQUNoRTtLQUNKLENBQUM7SUFDRixZQUFZLEVBQUUsTUFBTTtJQUNwQixPQUFPLEVBQUUsS0FBSyxFQUFDLEtBQUssRUFBQyxFQUFFO1FBQ3JCLE9BQU8sTUFBTSxtQkFBbUIsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUE7SUFDaEQsQ0FBQztDQUNGLENBQUMsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERlc2NyaXB0b3IsIFJlcG9ydCwgdmFsaWRhdGVUYWJsZVNjaGVtYSB9IGZyb20gXCJAZmFpcnNwZWMvbGlicmFyeVwiXG5pbXBvcnQgeyBjcmVhdGVUb29sIH0gZnJvbSBcIkBtYXN0cmEvY29yZS90b29sc1wiXG5pbXBvcnQgeyB6IH0gZnJvbSBcInpvZFwiXG5cbmV4cG9ydCBjb25zdCB2YWxpZGF0ZVRhYmxlU2NoZW1hVG9vbCA9IGNyZWF0ZVRvb2woe1xuICBpZDogXCJ2YWxpZGF0ZS10YWJsZS1zY2hlbWFcIixcbiAgZGVzY3JpcHRpb246XG4gICAgXCJWYWxpZGF0ZSBhIHRhYmxlIHNjaGVtYSBhZ2FpbnN0IHRoZSBGYWlyc3BlYyBUYWJsZSBTY2hlbWEgc3BlY2lmaWNhdGlvbi4gUmV0dXJucyB2YWxpZGF0aW9uIHJlcG9ydCB3aXRoIGVycm9ycyBpZiBhbnkuXCIsXG4gIGlucHV0U2NoZW1hOiB6Lm9iamVjdCh7XG4gICAgc291cmNlOiB6XG4gICAgICAudW5pb24oW0Rlc2NyaXB0b3IsIHouc3RyaW5nKCldKVxuICAgICAgLmRlc2NyaWJlKFxuICAgICAgICBcIlRoZSB0YWJsZSBzY2hlbWEgdG8gdmFsaWRhdGUgKGRlc2NyaXB0b3Igb2JqZWN0IG9yIGZpbGUgcGF0aClcIixcbiAgICAgICksXG4gIH0pLFxuICBvdXRwdXRTY2hlbWE6IFJlcG9ydCxcbiAgZXhlY3V0ZTogYXN5bmMgaW5wdXQgPT4ge1xuICAgIHJldHVybiBhd2FpdCB2YWxpZGF0ZVRhYmxlU2NoZW1hKGlucHV0LnNvdXJjZSlcbiAgfSxcbn0pXG4iXX0=
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,121 @@
1
+ import { writeTempFile } from "@fairspec/library";
2
+ import { describe, expect, it } from "vitest";
3
+ import { validateTableSchemaTool } from "./validate.js";
4
+ describe("validateTableSchemaTool", () => {
5
+ it("validates tool structure", () => {
6
+ expect(validateTableSchemaTool.id).toBe("validate-table-schema");
7
+ expect(validateTableSchemaTool.description).toBeTruthy();
8
+ expect(validateTableSchemaTool.inputSchema).toBeTruthy();
9
+ expect(validateTableSchemaTool.outputSchema).toBeTruthy();
10
+ expect(validateTableSchemaTool.execute).toBeTypeOf("function");
11
+ });
12
+ it("validates a valid table schema descriptor", async () => {
13
+ const descriptor = {
14
+ properties: {
15
+ id: { type: "integer" },
16
+ name: { type: "string" },
17
+ },
18
+ };
19
+ const result = await validateTableSchemaTool.execute?.({
20
+ source: descriptor,
21
+ }, {});
22
+ expect.assert(result);
23
+ expect.assert(!("error" in result));
24
+ expect(result.valid).toBe(true);
25
+ expect(result.errors).toHaveLength(0);
26
+ });
27
+ it("detects invalid table schema", async () => {
28
+ const descriptor = {
29
+ properties: {
30
+ id: {
31
+ type: 123,
32
+ },
33
+ },
34
+ };
35
+ const result = await validateTableSchemaTool.execute?.({
36
+ source: descriptor,
37
+ }, {});
38
+ expect.assert(result);
39
+ expect.assert(!("error" in result));
40
+ expect(result.valid).toBe(false);
41
+ expect(result.errors.length).toBeGreaterThan(0);
42
+ });
43
+ it("validates table schema from file path", async () => {
44
+ const descriptor = {
45
+ properties: {
46
+ id: { type: "integer" },
47
+ name: { type: "string" },
48
+ age: { type: "integer" },
49
+ },
50
+ };
51
+ const path = await writeTempFile(JSON.stringify(descriptor), {
52
+ format: "json",
53
+ });
54
+ const result = await validateTableSchemaTool.execute?.({
55
+ source: path,
56
+ }, {});
57
+ expect.assert(result);
58
+ expect.assert(!("error" in result));
59
+ expect(result.valid).toBe(true);
60
+ expect(result.errors).toHaveLength(0);
61
+ });
62
+ it("detects invalid table schema from file path", async () => {
63
+ const descriptor = {
64
+ properties: {
65
+ id: {
66
+ type: "not-a-valid-type",
67
+ },
68
+ },
69
+ };
70
+ const path = await writeTempFile(JSON.stringify(descriptor), {
71
+ format: "json",
72
+ });
73
+ const result = await validateTableSchemaTool.execute?.({
74
+ source: path,
75
+ }, {});
76
+ expect.assert(result);
77
+ expect.assert(!("error" in result));
78
+ expect(result.valid).toBe(false);
79
+ expect(result.errors.length).toBeGreaterThan(0);
80
+ });
81
+ it("validates minimal valid descriptor", async () => {
82
+ const descriptor = {
83
+ properties: {},
84
+ };
85
+ const result = await validateTableSchemaTool.execute?.({
86
+ source: descriptor,
87
+ }, {});
88
+ expect.assert(result);
89
+ expect.assert(!("error" in result));
90
+ expect(result.valid).toBe(true);
91
+ expect(result.errors).toHaveLength(0);
92
+ });
93
+ it("validates schema with field constraints", async () => {
94
+ const descriptor = {
95
+ properties: {
96
+ id: {
97
+ type: "integer",
98
+ constraints: {
99
+ required: true,
100
+ minimum: 1,
101
+ },
102
+ },
103
+ email: {
104
+ type: "string",
105
+ format: "email",
106
+ constraints: {
107
+ required: true,
108
+ },
109
+ },
110
+ },
111
+ };
112
+ const result = await validateTableSchemaTool.execute?.({
113
+ source: descriptor,
114
+ }, {});
115
+ expect.assert(result);
116
+ expect.assert(!("error" in result));
117
+ expect(result.valid).toBe(true);
118
+ expect(result.errors).toHaveLength(0);
119
+ });
120
+ });
121
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGUuc3BlYy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Rvb2xzL3RhYmxlU2NoZW1hL3ZhbGlkYXRlLnNwZWMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLG1CQUFtQixDQUFBO0FBQ2pELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLEVBQUUsRUFBRSxNQUFNLFFBQVEsQ0FBQTtBQUM3QyxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxlQUFlLENBQUE7QUFFdkQsUUFBUSxDQUFDLHlCQUF5QixFQUFFLEdBQUcsRUFBRTtJQUN2QyxFQUFFLENBQUMsMEJBQTBCLEVBQUUsR0FBRyxFQUFFO1FBQ2xDLE1BQU0sQ0FBQyx1QkFBdUIsQ0FBQyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsdUJBQXVCLENBQUMsQ0FBQTtRQUNoRSxNQUFNLENBQUMsdUJBQXVCLENBQUMsV0FBVyxDQUFDLENBQUMsVUFBVSxFQUFFLENBQUE7UUFDeEQsTUFBTSxDQUFDLHVCQUF1QixDQUFDLFdBQVcsQ0FBQyxDQUFDLFVBQVUsRUFBRSxDQUFBO1FBQ3hELE1BQU0sQ0FBQyx1QkFBdUIsQ0FBQyxZQUFZLENBQUMsQ0FBQyxVQUFVLEVBQUUsQ0FBQTtRQUN6RCxNQUFNLENBQUMsdUJBQXVCLENBQUMsT0FBTyxDQUFDLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFBO0lBQ2hFLENBQUMsQ0FBQyxDQUFBO0lBRUYsRUFBRSxDQUFDLDJDQUEyQyxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ3pELE1BQU0sVUFBVSxHQUFlO1lBQzdCLFVBQVUsRUFBRTtnQkFDVixFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsU0FBa0IsRUFBRTtnQkFDaEMsSUFBSSxFQUFFLEVBQUUsSUFBSSxFQUFFLFFBQWlCLEVBQUU7YUFDbEM7U0FDRixDQUFBO1FBRUQsTUFBTSxNQUFNLEdBQUcsTUFBTSx1QkFB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O29CQUN4QixXQUFXLEVBQUU7d0JBQ1gsUUFBUSxFQUFFLElBQUk7d0JBQ2QsT0FBTyxFQUFFLENBQUM7cUJBQ1g7aUJBQ0Y7Z0JBQ0QsS0FBSyxFQUFFO29CQUNMLElBQUksRUFBRSxRQUFpQjtvQkFDdkIsTUFBTSxFQUFFLE9BQWdCO29CQUN4QixXQUFXLEVBQUU7d0JBQ1gsUUFBUSxFQUFFLElBQUk7cUJBQ2Y7aUJBQ0Y7YUFDRjtTQUNGLENBQUE7UUFFRCxNQUFNLE1BQU0sR0FBRyxNQUFNLHVCQUF1QixDQUFDLE9BQU8sRUFBRSxDQUNwRDtZQUNFLE1BQU0sRUFBRSxVQUFVO1NBQ25CLEVBQ0QsRUFBRSxDQUNILENBQUE7UUFFRCxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFBO1FBQ3JCLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLE9BQU8sSUFBSSxNQUFNLENBQUMsQ0FBQyxDQUFBO1FBRW5DLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO1FBQy9CLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFBO0lBQ3ZDLENBQUMsQ0FBQyxDQUFBO0FBQ0osQ0FBQyxDQUFDLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IERlc2NyaXB0b3IgfSBmcm9tIFwiQGZhaXJzcGVjL2xpYnJhcnlcIlxuaW1wb3J0IHsgd3JpdGVUZW1wRmlsZSB9IGZyb20gXCJAZmFpcnNwZWMvbGlicmFyeVwiXG5pbXBvcnQgeyBkZXNjcmliZSwgZXhwZWN0LCBpdCB9IGZyb20gXCJ2aXRlc3RcIlxuaW1wb3J0IHsgdmFsaWRhdGVUYWJsZVNjaGVtYVRvb2wgfSBmcm9tIFwiLi92YWxpZGF0ZS50c1wiXG5cbmRlc2NyaWJlKFwidmFsaWRhdGVUYWJsZVNjaGVtYVRvb2xcIiwgKCkgPT4ge1xuICBpdChcInZhbGlkYXRlcyB0b29sIHN0cnVjdHVyZVwiLCAoKSA9PiB7XG4gICAgZXhwZWN0KHZhbGlkYXRlVGFibGVTY2hlbWFUb29sLmlkKS50b0JlKFwidmFsaWRhdGUtdGFibGUtc2NoZW1hXCIpXG4gICAgZXhwZWN0KHZhbGlkYXRlVGFibGVTY2hlbWFUb29sLmRlc2NyaXB0aW9uKS50b0JlVHJ1dGh5KClcbiAgICBleHBlY3QodmFsaWRhdGVUYWJsZVNjaGVtYVRvb2wuaW5wdXRTY2hlbWEpLnRvQmVUcnV0aHkoKVxuICAgIGV4cGVjdCh2YWxpZGF0ZVRhYmxlU2NoZW1hVG9vbC5vdXRwdXRTY2hlbWEpLnRvQmVUcnV0aHkoKVxuICAgIGV4cGVjdCh2YWxpZGF0ZVRhYmxlU2NoZW1hVG9vbC5leGVjdXRlKS50b0JlVHlwZU9mKFwiZnVuY3Rpb25cIilcbiAgfSlcblxuICBpdChcInZhbGlkYXRlcyBhIHZhbGlkIHRhYmxlIHNjaGVtYSBkZXNjcmlwdG9yXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBkZXNjcmlwdG9yOiBEZXNjcmlwdG9yID0ge1xuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBpZDogeyB0eXBlOiBcImludGVnZXJcIiBhcyBjb25zdCB9LFxuICAgICAgICBuYW1lOiB7IHR5cGU6IFwic3RyaW5nXCIgYXMgY29uc3QgfSxcbiAgICAgIH0sXG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdmFsaWRhdGVUYWJsZVNjaGVtYVRvb2wuZXhlY3V0ZT8uKFxuICAgICAge1xuICAgICAgICBzb3VyY2U6IGRlc2NyaXB0b3IsXG4gICAgICB9LFxuICAgICAge30sXG4gICAgKVxuXG4gICAgZXhwZWN0LmFzc2VydChyZXN1bHQpXG4gICAgZXhwZWN0LmFzc2VydCghKFwiZXJyb3JcIiBpbiByZXN1bHQpKVxuXG4gICAgZXhwZWN0KHJlc3VsdC52YWxpZCkudG9CZSh0cnVlKVxuICAgIGV4cGVjdChyZXN1bHQuZXJyb3JzKS50b0hhdmVMZW5ndGgoMClcbiAgfSlcblxuICBpdChcImRldGVjdHMgaW52YWxpZCB0YWJsZSBzY2hlbWFcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGRlc2NyaXB0b3I6IERlc2NyaXB0b3IgPSB7XG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIGlkOiB7XG4gICAgICAgICAgdHlwZTogMTIzIGFzIHVua25vd24gYXMgXCJpbnRlZ2VyXCIsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH1cblxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHZhbGlkYXRlVGFibGVTY2hlbWFUb29sLmV4ZWN1dGU/LihcbiAgICAgIHtcbiAgICAgICAgc291cmNlOiBkZXNjcmlwdG9yLFxuICAgICAgfSxcbiAgICAgIHt9LFxuICAgIClcblxuICAgIGV4cGVjdC5hc3NlcnQocmVzdWx0KVxuICAgIGV4cGVjdC5hc3NlcnQoIShcImVycm9yXCIgaW4gcmVzdWx0KSlcblxuICAgIGV4cGVjdChyZXN1bHQudmFsaWQpLnRvQmUoZmFsc2UpXG4gICAgZXhwZWN0KHJlc3VsdC5lcnJvcnMubGVuZ3RoKS50b0JlR3JlYXRlclRoYW4oMClcbiAgfSlcblxuICBpdChcInZhbGlkYXRlcyB0YWJsZSBzY2hlbWEgZnJvbSBmaWxlIHBhdGhcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGRlc2NyaXB0b3IgPSB7XG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIGlkOiB7IHR5cGU6IFwiaW50ZWdlclwiIH0sXG4gICAgICAgIG5hbWU6IHsgdHlwZTogXCJzdHJpbmdcIiB9LFxuICAgICAgICBhZ2U6IHsgdHlwZTogXCJpbnRlZ2VyXCIgfSxcbiAgICAgIH0sXG4gICAgfVxuICAgIGNvbnN0IHBhdGggPSBhd2FpdCB3cml0ZVRlbXBGaWxlKEpTT04uc3RyaW5naWZ5KGRlc2NyaXB0b3IpLCB7XG4gICAgICBmb3JtYXQ6IFwianNvblwiLFxuICAgIH0pXG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB2YWxpZGF0ZVRhYmxlU2NoZW1hVG9vbC5leGVjdXRlPy4oXG4gICAgICB7XG4gICAgICAgIHNvdXJjZTogcGF0aCxcbiAgICAgIH0sXG4gICAgICB7fSxcbiAgICApXG5cbiAgICBleHBlY3QuYXNzZXJ0KHJlc3VsdClcbiAgICBleHBlY3QuYXNzZXJ0KCEoXCJlcnJvclwiIGluIHJlc3VsdCkpXG5cbiAgICBleHBlY3QocmVzdWx0LnZhbGlkKS50b0JlKHRydWUpXG4gICAgZXhwZWN0KHJlc3VsdC5lcnJvcnMpLnRvSGF2ZUxlbmd0aCgwKVxuICB9KVxuXG4gIGl0KFwiZGV0ZWN0cyBpbnZhbGlkIHRhYmxlIHNjaGVtYSBmcm9tIGZpbGUgcGF0aFwiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgZGVzY3JpcHRvciA9IHtcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgaWQ6IHtcbiAgICAgICAgICB0eXBlOiBcIm5vdC1hLXZhbGlkLXR5cGVcIixcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfVxuICAgIGNvbnN0IHBhdGggPSBhd2FpdCB3cml0ZVRlbXBGaWxlKEpTT04uc3RyaW5naWZ5KGRlc2NyaXB0b3IpLCB7XG4gICAgICBmb3JtYXQ6IFwianNvblwiLFxuICAgIH0pXG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB2YWxpZGF0ZVRhYmxlU2NoZW1hVG9vbC5leGVjdXRlPy4oXG4gICAgICB7XG4gICAgICAgIHNvdXJjZTogcGF0aCxcbiAgICAgIH0sXG4gICAgICB7fSxcbiAgICApXG5cbiAgICBleHBlY3QuYXNzZXJ0KHJlc3VsdClcbiAgICBleHBlY3QuYXNzZXJ0KCEoXCJlcnJvclwiIGluIHJlc3VsdCkpXG5cbiAgICBleHBlY3QocmVzdWx0LnZhbGlkKS50b0JlKGZhbHNlKVxuICAgIGV4cGVjdChyZXN1bHQuZXJyb3JzLmxlbmd0aCkudG9CZUdyZWF0ZXJUaGFuKDApXG4gIH0pXG5cbiAgaXQoXCJ2YWxpZGF0ZXMgbWluaW1hbCB2YWxpZCBkZXNjcmlwdG9yXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBkZXNjcmlwdG9yOiBEZXNjcmlwdG9yID0ge1xuICAgICAgcHJvcGVydGllczoge30sXG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdmFsaWRhdGVUYWJsZVNjaGVtYVRvb2wuZXhlY3V0ZT8uKFxuICAgICAge1xuICAgICAgICBzb3VyY2U6IGRlc2NyaXB0b3IsXG4gICAgICB9LFxuICAgICAge30sXG4gICAgKVxuXG4gICAgZXhwZWN0LmFzc2VydChyZXN1bHQpXG4gICAgZXhwZWN0LmFzc2VydCghKFwiZXJyb3JcIiBpbiByZXN1bHQpKVxuXG4gICAgZXhwZWN0KHJlc3VsdC52YWxpZCkudG9CZSh0cnVlKVxuICAgIGV4cGVjdChyZXN1bHQuZXJyb3JzKS50b0hhdmVMZW5ndGgoMClcbiAgfSlcblxuICBpdChcInZhbGlkYXRlcyBzY2hlbWEgd2l0aCBmaWVsZCBjb25zdHJhaW50c1wiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgZGVzY3JpcHRvcjogRGVzY3JpcHRvciA9IHtcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgaWQ6IHtcbiAgICAgICAgICB0eXBlOiBcImludGVnZXJcIiBhcyBjb25zdCxcbiAgICAgICAgICBjb25zdHJhaW50czoge1xuICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICBtaW5pbXVtOiAxLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIGVtYWlsOiB7XG4gICAgICAgICAgdHlwZTogXCJzdHJpbmdcIiBhcyBjb25zdCxcbiAgICAgICAgICBmb3JtYXQ6IFwiZW1haWxcIiBhcyBjb25zdCxcbiAgICAgICAgICBjb25zdHJhaW50czoge1xuICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdmFsaWRhdGVUYWJsZVNjaGVtYVRvb2wuZXhlY3V0ZT8uKFxuICAgICAge1xuICAgICAgICBzb3VyY2U6IGRlc2NyaXB0b3IsXG4gICAgICB9LFxuICAgICAge30sXG4gICAgKVxuXG4gICAgZXhwZWN0LmFzc2VydChyZXN1bHQpXG4gICAgZXhwZWN0LmFzc2VydCghKFwiZXJyb3JcIiBpbiByZXN1bHQpKVxuXG4gICAgZXhwZWN0KHJlc3VsdC52YWxpZCkudG9CZSh0cnVlKVxuICAgIGV4cGVjdChyZXN1bHQuZXJyb3JzKS50b0hhdmVMZW5ndGgoMClcbiAgfSlcbn0pXG4iXX0=
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@fairspec/agent",
3
+ "type": "module",
4
+ "version": "0.9.0",
5
+ "exports": "./build/index.js",
6
+ "sideEffects": false,
7
+ "files": [
8
+ "build"
9
+ ],
10
+ "license": "MIT",
11
+ "author": "Evgeny Karev",
12
+ "repository": "https://github.com/fairspec/fairspec-typescript",
13
+ "description": "Fairspec TypeScript is a fast data management framework built on top of the Fairspec standard and Polars DataFrames",
14
+ "keywords": [
15
+ "fairspec",
16
+ "data",
17
+ "polars",
18
+ "dataframe",
19
+ "jsonschema",
20
+ "tableschema",
21
+ "typescript",
22
+ "validation",
23
+ "quality",
24
+ "fair",
25
+ "mcp",
26
+ "llm",
27
+ "ai"
28
+ ],
29
+ "dependencies": {
30
+ "@mastra/core": "^1.2.0",
31
+ "@mastra/mcp": "^1.0.0",
32
+ "zod": "^4.2.1",
33
+ "@fairspec/library": "0.0.0-dev"
34
+ },
35
+ "scripts": {
36
+ "build": "tsc",
37
+ "type": "tsc --noEmit"
38
+ }
39
+ }