minions-sdk 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.
@@ -0,0 +1,173 @@
1
+ /**
2
+ * @module minions-sdk/validation
3
+ * Field validation engine for the Minions system.
4
+ * Validates minion field values against their MinionType schema.
5
+ */
6
+ const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
7
+ const ISO8601_RE = /^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2}))?$/;
8
+ /**
9
+ * Validate a single field value against its definition.
10
+ * @param value - The value to validate
11
+ * @param field - The field definition to validate against
12
+ * @returns Array of validation errors (empty if valid)
13
+ */
14
+ export function validateField(value, field) {
15
+ const errors = [];
16
+ const isAbsent = value === undefined || value === null || value === '';
17
+ // Required check
18
+ if (field.required && isAbsent) {
19
+ errors.push({ field: field.name, message: `Field "${field.name}" is required`, value });
20
+ return errors;
21
+ }
22
+ // If not present and not required, skip further validation
23
+ if (isAbsent)
24
+ return errors;
25
+ // Type-specific validation
26
+ const typeErrors = validateFieldType(value, field);
27
+ errors.push(...typeErrors);
28
+ return errors;
29
+ }
30
+ /**
31
+ * Validate a value matches the expected field type and constraints.
32
+ */
33
+ function validateFieldType(value, field) {
34
+ const errors = [];
35
+ const { name, type, options, validation } = field;
36
+ const typeValidators = {
37
+ string: () => {
38
+ if (typeof value !== 'string') {
39
+ errors.push({ field: name, message: `Expected string, got ${typeof value}`, value });
40
+ return;
41
+ }
42
+ applyStringConstraints(value, name, validation, errors);
43
+ },
44
+ textarea: () => {
45
+ if (typeof value !== 'string') {
46
+ errors.push({ field: name, message: `Expected string, got ${typeof value}`, value });
47
+ return;
48
+ }
49
+ applyStringConstraints(value, name, validation, errors);
50
+ },
51
+ number: () => {
52
+ if (typeof value !== 'number' || Number.isNaN(value)) {
53
+ errors.push({ field: name, message: `Expected number, got ${typeof value}`, value });
54
+ return;
55
+ }
56
+ if (validation?.min !== undefined && value < validation.min) {
57
+ errors.push({ field: name, message: `Value must be >= ${validation.min}`, value });
58
+ }
59
+ if (validation?.max !== undefined && value > validation.max) {
60
+ errors.push({ field: name, message: `Value must be <= ${validation.max}`, value });
61
+ }
62
+ },
63
+ boolean: () => {
64
+ if (typeof value !== 'boolean') {
65
+ errors.push({ field: name, message: `Expected boolean, got ${typeof value}`, value });
66
+ }
67
+ },
68
+ date: () => {
69
+ if (typeof value !== 'string' || !ISO8601_RE.test(value)) {
70
+ errors.push({ field: name, message: `Expected valid ISO 8601 date string`, value });
71
+ }
72
+ },
73
+ select: () => {
74
+ if (typeof value !== 'string') {
75
+ errors.push({ field: name, message: `Expected string for select, got ${typeof value}`, value });
76
+ return;
77
+ }
78
+ if (options && !options.includes(value)) {
79
+ errors.push({ field: name, message: `Value must be one of: ${options.join(', ')}`, value });
80
+ }
81
+ },
82
+ 'multi-select': () => {
83
+ if (!Array.isArray(value)) {
84
+ errors.push({ field: name, message: `Expected array for multi-select, got ${typeof value}`, value });
85
+ return;
86
+ }
87
+ if (options) {
88
+ for (const item of value) {
89
+ if (!options.includes(item)) {
90
+ errors.push({ field: name, message: `Invalid option: ${item}. Must be one of: ${options.join(', ')}`, value: item });
91
+ }
92
+ }
93
+ }
94
+ },
95
+ url: () => {
96
+ if (typeof value !== 'string') {
97
+ errors.push({ field: name, message: `Expected valid URL (http/https)`, value });
98
+ return;
99
+ }
100
+ try {
101
+ const parsed = new URL(value);
102
+ if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
103
+ errors.push({ field: name, message: `Expected valid URL (http/https)`, value });
104
+ }
105
+ }
106
+ catch {
107
+ errors.push({ field: name, message: `Expected valid URL (http/https)`, value });
108
+ }
109
+ },
110
+ email: () => {
111
+ if (typeof value !== 'string' || !EMAIL_RE.test(value)) {
112
+ errors.push({ field: name, message: `Expected valid email address`, value });
113
+ }
114
+ },
115
+ tags: () => {
116
+ if (!Array.isArray(value)) {
117
+ errors.push({ field: name, message: `Expected array for tags, got ${typeof value}`, value });
118
+ return;
119
+ }
120
+ for (const tag of value) {
121
+ if (typeof tag !== 'string') {
122
+ errors.push({ field: name, message: `Tag values must be strings`, value: tag });
123
+ }
124
+ }
125
+ },
126
+ json: () => {
127
+ if (typeof value !== 'object' && typeof value !== 'string' && typeof value !== 'number' && typeof value !== 'boolean') {
128
+ errors.push({ field: name, message: `Expected valid JSON value`, value });
129
+ }
130
+ },
131
+ array: () => {
132
+ if (!Array.isArray(value)) {
133
+ errors.push({ field: name, message: `Expected array, got ${typeof value}`, value });
134
+ }
135
+ },
136
+ };
137
+ const validator = typeValidators[type];
138
+ if (validator) {
139
+ validator();
140
+ }
141
+ else {
142
+ errors.push({ field: name, message: `Unknown field type: ${type}`, value });
143
+ }
144
+ return errors;
145
+ }
146
+ function applyStringConstraints(value, fieldName, validation, errors) {
147
+ if (!validation)
148
+ return;
149
+ if (validation.minLength !== undefined && value.length < validation.minLength) {
150
+ errors.push({ field: fieldName, message: `Must be at least ${validation.minLength} characters`, value });
151
+ }
152
+ if (validation.maxLength !== undefined && value.length > validation.maxLength) {
153
+ errors.push({ field: fieldName, message: `Must be at most ${validation.maxLength} characters`, value });
154
+ }
155
+ if (validation.pattern !== undefined && !new RegExp(validation.pattern).test(value)) {
156
+ errors.push({ field: fieldName, message: `Must match pattern: ${validation.pattern}`, value });
157
+ }
158
+ }
159
+ /**
160
+ * Validate all fields of a minion against a MinionType schema.
161
+ * @param fields - The minion's field values
162
+ * @param schema - The field definitions from the MinionType
163
+ * @returns Validation result with any errors
164
+ */
165
+ export function validateFields(fields, schema) {
166
+ const errors = [];
167
+ for (const fieldDef of schema) {
168
+ const value = fields[fieldDef.name];
169
+ errors.push(...validateField(value, fieldDef));
170
+ }
171
+ return { valid: errors.length === 0, errors };
172
+ }
173
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/validation/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "minions-sdk",
3
+ "version": "0.1.0",
4
+ "description": "Framework-agnostic core library for the Minions structured object system",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/mxn2020/minions"
9
+ },
10
+ "homepage": "https://github.com/mxn2020/minions",
11
+ "keywords": [
12
+ "ai",
13
+ "agents",
14
+ "structured-objects",
15
+ "schema",
16
+ "minions"
17
+ ],
18
+ "type": "module",
19
+ "main": "./dist/index.js",
20
+ "types": "./dist/index.d.ts",
21
+ "exports": {
22
+ ".": {
23
+ "import": "./dist/index.js",
24
+ "types": "./dist/index.d.ts"
25
+ }
26
+ },
27
+ "files": [
28
+ "dist"
29
+ ],
30
+ "devDependencies": {
31
+ "typescript": "^5.3.3",
32
+ "vitest": "^1.6.1",
33
+ "typedoc": "^0.28.0",
34
+ "typedoc-plugin-markdown": "^4.4.0"
35
+ },
36
+ "scripts": {
37
+ "build": "tsc",
38
+ "test": "vitest run",
39
+ "test:watch": "vitest",
40
+ "lint": "tsc --noEmit",
41
+ "docs": "typedoc"
42
+ }
43
+ }