UNPKG

@vqp/core

Version:

Core VQP protocol implementation - adapter-agnostic

217 lines 5.77 kB
/** * Query Builder - Fluent interface for building VQP queries */ import { randomUUID } from 'node:crypto'; export class QueryBuilder { query = {}; constructor() { this.query = { id: randomUUID(), version: '1.1.0', // Updated to support response modes timestamp: new Date().toISOString(), }; } /** * Set the requester DID */ requester(did) { this.query.requester = did; return this; } /** * Set the target DID (optional for broadcast queries) */ target(did) { this.query.target = did; return this; } /** * Set response mode for the query */ responseMode(mode, config) { this.query.responseMode = { type: mode, config, }; return this; } /** * Set strict response mode (default) - only returns boolean result */ strict() { return this.responseMode('strict'); } /** * Set consensual response mode - returns actual value if consent is granted */ consensual(justification, consentRequired = true) { return this.responseMode('consensual', { justification, consentRequired, }); } /** * Set reciprocal response mode - requires mutual verification */ reciprocal(requesterProof, requiredClaims) { return this.responseMode('reciprocal', { mutualVerification: { requesterProof, requiredClaims, }, }); } /** * Set obfuscated response mode - returns obfuscated actual value */ obfuscated(method, options = {}) { return this.responseMode('obfuscated', { obfuscation: { method, ...options, }, }); } /** * Set the vocabulary URI */ vocabulary(vocabUri) { if (!this.query.query) { this.query.query = { lang: 'jsonlogic@1.0.0', vocab: vocabUri, expr: {}, }; } else { this.query.query.vocab = vocabUri; } return this; } /** * Set the query expression */ expression(expr) { if (!this.query.query) { this.query.query = { lang: 'jsonlogic@1.0.0', vocab: '', expr: expr, }; } else { this.query.query.expr = expr; } return this; } /** * Set a custom query ID */ id(queryId) { this.query.id = queryId; return this; } /** * Set a custom timestamp */ timestamp(timestamp) { this.query.timestamp = timestamp; return this; } /** * Set the query language (defaults to jsonlogic@1.0.0) */ language(lang) { if (!this.query.query) { this.query.query = { lang: lang, vocab: '', expr: {}, }; } else { this.query.query.lang = lang; } return this; } /** * Build the complete VQP query */ build() { if (!this.query.id || !this.query.version || !this.query.timestamp || !this.query.requester) { throw new Error('Missing required query fields: id, version, timestamp, requester'); } if (!this.query.query || !this.query.query.vocab || !this.query.query.expr) { throw new Error('Missing required query fields: vocab, expr'); } return this.query; } /** * Create a query with a simple field comparison */ static compare(requester, vocabulary, field, operator, value, target) { const builder = new QueryBuilder() .requester(requester) .vocabulary(vocabulary) .expression({ [operator]: [{ var: field }, value], }); if (target) { builder.target(target); } return builder.build(); } /** * Create a query with an 'and' condition */ static and(requester, vocabulary, conditions, target) { const builder = new QueryBuilder().requester(requester).vocabulary(vocabulary).expression({ and: conditions, }); if (target) { builder.target(target); } return builder.build(); } /** * Create a query with an 'or' condition */ static or(requester, vocabulary, conditions, target) { const builder = new QueryBuilder().requester(requester).vocabulary(vocabulary).expression({ or: conditions, }); if (target) { builder.target(target); } return builder.build(); } /** * Create a query with an 'in' condition (array membership) */ static in(requester, vocabulary, value, arrayField, target) { const builder = new QueryBuilder() .requester(requester) .vocabulary(vocabulary) .expression({ in: [value, { var: arrayField }], }); if (target) { builder.target(target); } return builder.build(); } /** * Create a query from raw JSONLogic expression */ static fromExpression(requester, vocabulary, expression, target) { const builder = new QueryBuilder() .requester(requester) .vocabulary(vocabulary) .expression(expression); if (target) { builder.target(target); } return builder.build(); } } //# sourceMappingURL=query-builder.js.map