@maximai/maxim-js
Version:
Maxim AI JS SDK. Visit https://getmaxim.ai for more info.
223 lines • 7.74 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.QueryBuilder = exports.QueryRuleType = void 0;
var QueryRuleType;
(function (QueryRuleType) {
QueryRuleType["DeploymentVar"] = "deploymentVar";
QueryRuleType["Tag"] = "tag";
})(QueryRuleType || (exports.QueryRuleType = QueryRuleType = {}));
/**
* Builder class for constructing queries to filter prompts and prompt chains.
*
* Provides an interface for building complex query rules that determine
* which version of a prompt or prompt chain should be retrieved based on
* deployment variables, tags, and other criteria. Essential for implementing
* deployment strategies and A/B testing with prompts.
*
* @class QueryBuilder
* @example
* import { QueryBuilder } from '@maximai/maxim-js';
*
* // Basic deployment query
* const rule = new QueryBuilder()
* .deploymentVar('environment', 'production')
* .deploymentVar('region', 'us-east-1')
* .build();
*
* const prompt = await maxim.getPrompt('prompt-id', rule);
*
* @example
* // Complex query with tags and exact matching
* const rule = new QueryBuilder()
* .exactMatch()
* .and()
* .deploymentVar('stage', 'prod', true) // enforced
* .tag('version', 'v2.0')
* .folder('marketing-prompts')
* .build();
*/
class QueryBuilder {
/**
* Creates a new QueryBuilder instance with default settings.
*
* Initializes with AND operator and exact matching disabled.
* Use the class methods to configure the query before calling build().
*/
constructor() {
this.scopes = {};
this.isExactMatch = false;
this.query = "";
this.operator = "AND";
}
/**
* Sets the logical operator to AND for combining query criteria.
*
* With AND logic, all specified criteria must match for a prompt version
* to be selected. This is the default behavior.
*
* @returns This QueryBuilder instance for method chaining
* @example
* const rule = new QueryBuilder()
* .and() // All conditions must match
* .deploymentVar('env', 'prod')
* .deploymentVar('region', 'us-east')
* .build();
*/
and() {
this.operator = "AND";
return this;
}
/**
* Sets the logical operator to OR for combining query criteria.
*
* With OR logic, any of the specified criteria can match for a prompt version
* to be selected. Useful for fallback scenarios and flexible matching.
*
* @returns This QueryBuilder instance for method chaining
* @example
* const rule = new QueryBuilder()
* .or() // Any condition can match
* .deploymentVar('feature_beta', true)
* .deploymentVar('user_type', 'premium')
* .build();
*/
or() {
this.operator = "OR";
return this;
}
/**
* Restricts the query to a specific folder.
*
* Only prompts and prompt chains within the specified folder will be
* considered when evaluating the query criteria.
*
* @param folderId - The ID of the folder to restrict the query to
* @returns This QueryBuilder instance for method chaining
* @example
* const rule = new QueryBuilder()
* .folder('marketing-folder-123')
* .deploymentVar('campaign', 'summer-2024')
* .build();
*/
folder(folderId) {
this.scopes["folder"] = folderId;
return this;
}
/**
* Enables exact matching mode for the query.
*
* When exact matching is enabled, prompt versions must have deployment
* configurations that exactly match the query criteria. No partial or
* fuzzy matching is performed.
*
* @returns This QueryBuilder instance for method chaining
* @example
* const rule = new QueryBuilder()
* .exactMatch() // Require exact match
* .deploymentVar('environment', 'production')
* .build();
*/
exactMatch() {
this.isExactMatch = true;
return this;
}
/**
* Adds a deployment variable constraint to the query.
*
* Deployment variables are used to control which version of a prompt is
* served based on runtime conditions like environment, user segments,
* feature flags, etc.
*
* @param key - The deployment variable name
* @param value - The required value for the variable
* @param enforce - Whether this variable must be present (defaults to true)
* @returns This QueryBuilder instance for method chaining
* @example
* const rule = new QueryBuilder()
* .deploymentVar('environment', 'production') // Must match
* .deploymentVar('feature_flag', true, false) // Optional match
* .build();
*
* @example
* // Different data types
* new QueryBuilder()
* .deploymentVar('region', 'us-west-2') // string
* .deploymentVar('max_users', 1000) // number
* .deploymentVar('beta_enabled', true) // boolean
* .build();
*/
deploymentVar(key, value, enforce = true) {
if (this.query.length > 0)
this.query += ",";
this.query += `${enforce ? "!!" : ""}${key}=${Array.isArray(value) ? JSON.stringify(value) : value}`;
return this;
}
/**
* Adds a tag constraint to the query.
*
* Tags provide additional metadata for organizing and filtering prompts.
* Unlike deployment variables, tags are typically used for categorization
* and organization rather than runtime deployment logic.
*
* @param key - The tag name
* @param value - The required value for the tag
* @param enforce - Whether this tag must be present (defaults to false)
* @returns This QueryBuilder instance for method chaining
* @example
* const rule = new QueryBuilder()
* .tag('category', 'customer-service')
* .tag('version', 'v2.1', true) // Enforced tag
* .build();
*
* @example
* // Organizing by team and purpose
* new QueryBuilder()
* .tag('team', 'marketing')
* .tag('purpose', 'email-generation')
* .tag('priority', 'high')
* .build();
*/
tag(key, value, enforce = false) {
if (this.query.length > 0)
this.query += ",";
this.query += `${enforce ? "!!" : ""}${key}=${value}`;
return this;
}
promptVersionNumber(number) {
if (this.query.length > 0)
this.query += ",";
this.query += `promptVersionNumber=${number}`;
return this;
}
/**
* Builds and returns the final QueryRule object.
*
* Validates that at least one constraint has been added and constructs
* the final QueryRule with all specified criteria, operators, and scopes.
*
* @returns The constructed query rule ready for use with Maxim API methods
* @throws {Error} When no constraints have been added to the query
* @example
* const rule = new QueryBuilder()
* .deploymentVar('env', 'prod')
* .tag('version', 'stable')
* .build();
*
* // Use with Maxim methods
* const prompt = await maxim.getPrompt('prompt-id', rule);
* const prompts = await maxim.getPrompts(rule);
*/
build() {
if (this.query.trim().length === 0) {
throw new Error("Cannot build an empty query. Please add at least one rule (deploymentVar or tag).");
}
return {
query: this.query,
operator: this.operator,
exactMatch: this.isExactMatch,
scopes: this.scopes,
};
}
}
exports.QueryBuilder = QueryBuilder;
//# sourceMappingURL=queryBuilder.js.map