aura-protocol
Version:
Core TypeScript definitions and JSON Schema for the AURA protocol - making websites machine-readable for AI agents
316 lines (315 loc) • 12.4 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const vitest_1 = require("vitest");
const Ajv = __importStar(require("ajv"));
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
(0, vitest_1.describe)('AURA Protocol JSON Schema Validation', () => {
let ajv;
let schema;
(0, vitest_1.beforeAll)(() => {
// Load the generated JSON schema
const schemaPath = path.join(__dirname, '../dist/aura-v1.0.schema.json');
if (!fs.existsSync(schemaPath)) {
throw new Error(`Schema file not found at ${schemaPath}. Run 'npm run build' first.`);
}
schema = JSON.parse(fs.readFileSync(schemaPath, 'utf-8'));
ajv = new Ajv.default({ allErrors: true, strict: false });
});
(0, vitest_1.it)('should validate a complete valid manifest using JSON schema', () => {
const manifest = {
$schema: 'https://aura.dev/schemas/v1.0.json',
protocol: 'AURA',
version: '1.0',
site: {
name: 'Test Site',
description: 'A test site',
url: 'https://example.com'
},
resources: {
posts: {
uriPattern: '/api/posts/{id}',
description: 'Blog posts',
operations: {
GET: { capabilityId: 'read_post' }
}
}
},
capabilities: {
read_post: {
id: 'read_post',
v: 1,
description: 'Read a post',
parameters: {
type: 'object',
required: ['id'],
properties: {
id: { type: 'string' }
}
},
action: {
type: 'HTTP',
method: 'GET',
urlTemplate: '/api/posts/{id}',
parameterMapping: {
id: '/id'
}
}
}
}
};
const validate = ajv.compile(schema);
const valid = validate(manifest);
(0, vitest_1.expect)(valid).toBe(true);
(0, vitest_1.expect)(validate.errors).toBeNull();
});
(0, vitest_1.it)('should validate a minimal manifest using JSON schema', () => {
const minimalManifest = {
$schema: 'https://aura.dev/schemas/v1.0.json',
protocol: 'AURA',
version: '1.0',
site: {
name: 'Minimal Site',
url: 'https://minimal.com'
},
resources: {},
capabilities: {}
};
const validate = ajv.compile(schema);
const valid = validate(minimalManifest);
(0, vitest_1.expect)(valid).toBe(true);
(0, vitest_1.expect)(validate.errors).toBeNull();
});
(0, vitest_1.it)('should reject invalid manifests missing required fields', () => {
const invalidManifest = {
$schema: 'https://aura.dev/schemas/v1.0.json',
protocol: 'AURA',
// Missing version field
site: {
name: 'Test Site',
url: 'https://example.com'
},
resources: {},
capabilities: {}
};
const validate = ajv.compile(schema);
const valid = validate(invalidManifest);
(0, vitest_1.expect)(valid).toBe(false);
(0, vitest_1.expect)(validate.errors).not.toBeNull();
(0, vitest_1.expect)(validate.errors).toHaveLength(1);
(0, vitest_1.expect)(validate.errors[0].instancePath).toBe('');
(0, vitest_1.expect)(validate.errors[0].message).toContain('version');
});
(0, vitest_1.it)('should reject manifests with invalid protocol value', () => {
const invalidManifest = {
$schema: 'https://aura.dev/schemas/v1.0.json',
protocol: 'INVALID_PROTOCOL',
version: '1.0',
site: {
name: 'Test Site',
url: 'https://example.com'
},
resources: {},
capabilities: {}
};
const validate = ajv.compile(schema);
const valid = validate(invalidManifest);
(0, vitest_1.expect)(valid).toBe(false);
(0, vitest_1.expect)(validate.errors).not.toBeNull();
(0, vitest_1.expect)(validate.errors.length).toBeGreaterThan(0);
// Should have an error about protocol value
const protocolError = validate.errors.find(error => {
var _a;
return error.instancePath === '/protocol' ||
(error.instancePath === '' && ((_a = error.message) === null || _a === void 0 ? void 0 : _a.includes('protocol')));
});
(0, vitest_1.expect)(protocolError).toBeDefined();
});
(0, vitest_1.it)('should reject manifests with invalid site structure', () => {
const invalidManifest = {
$schema: 'https://aura.dev/schemas/v1.0.json',
protocol: 'AURA',
version: '1.0',
site: {
// Missing required name field
url: 'https://example.com'
},
resources: {},
capabilities: {}
};
const validate = ajv.compile(schema);
const valid = validate(invalidManifest);
(0, vitest_1.expect)(valid).toBe(false);
(0, vitest_1.expect)(validate.errors).not.toBeNull();
(0, vitest_1.expect)(validate.errors.length).toBeGreaterThan(0);
// Should have an error about missing name field
const nameError = validate.errors.find(error => { var _a; return error.instancePath === '/site' && ((_a = error.message) === null || _a === void 0 ? void 0 : _a.includes('name')); });
(0, vitest_1.expect)(nameError).toBeDefined();
});
(0, vitest_1.it)('should validate manifests with capability structure (current schema is permissive)', () => {
const manifest = {
$schema: 'https://aura.dev/schemas/v1.0.json',
protocol: 'AURA',
version: '1.0',
site: {
name: 'Test Site',
url: 'https://example.com'
},
resources: {},
capabilities: {
some_capability: {
id: 'some_capability', // Added missing required field
v: 1,
description: 'Test capability',
parameters: {
type: 'object',
properties: {}
},
action: {
type: 'HTTP',
method: 'GET',
urlTemplate: '/api/test',
parameterMapping: {} // Added missing required field
}
}
}
};
const validate = ajv.compile(schema);
const valid = validate(manifest);
// The main schema is currently permissive for capabilities
(0, vitest_1.expect)(valid).toBe(true);
});
(0, vitest_1.it)('should validate capabilities with proper parameter mapping', () => {
const manifest = {
$schema: 'https://aura.dev/schemas/v1.0.json',
protocol: 'AURA',
version: '1.0',
site: {
name: 'Test Site',
url: 'https://example.com'
},
resources: {
users: {
uriPattern: '/api/users/{id}',
description: 'User management',
operations: {
GET: { capabilityId: 'get_user' },
POST: { capabilityId: 'create_user' }
}
}
},
capabilities: {
get_user: {
id: 'get_user',
v: 1,
description: 'Get user by ID',
parameters: {
type: 'object',
required: ['id'],
properties: {
id: { type: 'string' }
}
},
action: {
type: 'HTTP',
method: 'GET',
urlTemplate: '/api/users/{id}',
parameterMapping: {
id: '/id'
}
}
},
create_user: {
id: 'create_user',
v: 1,
description: 'Create a new user',
parameters: {
type: 'object',
required: ['name', 'email'],
properties: {
name: { type: 'string' },
email: { type: 'string', format: 'email' }
}
},
action: {
type: 'HTTP',
method: 'POST',
urlTemplate: '/api/users',
parameterMapping: {
name: '/name',
email: '/email'
}
}
}
}
};
const validate = ajv.compile(schema);
const valid = validate(manifest);
(0, vitest_1.expect)(valid).toBe(true);
(0, vitest_1.expect)(validate.errors).toBeNull();
});
(0, vitest_1.it)('should validate manifests with resources (current schema is permissive for detailed structure)', () => {
const manifest = {
$schema: 'https://aura.dev/schemas/v1.0.json',
protocol: 'AURA',
version: '1.0',
site: {
name: 'Test Site',
url: 'https://example.com'
},
resources: {
posts: {
uriPattern: '/api/posts/{id}', // Added missing required field
description: 'Blog posts',
operations: {
GET: { capabilityId: 'test_capability' } // Fixed reference
}
}
},
capabilities: {
test_capability: {
id: 'test_capability',
v: 1,
description: 'Test capability',
parameters: {
type: 'object',
properties: {}
},
action: {
type: 'HTTP',
method: 'GET',
urlTemplate: '/api/test',
parameterMapping: {} // Added missing required field
}
}
}
};
const validate = ajv.compile(schema);
const valid = validate(manifest);
// The main schema is currently permissive for resources and capabilities
(0, vitest_1.expect)(valid).toBe(true);
});
});