UNPKG

oso-cloud

Version:

Oso Cloud Node.js Client SDK

177 lines 8.88 kB
import { Fact, IntoFact, IntoValue, Oso, Value } from "."; import { DefaultPolarTypes } from "./helpers"; import { QueryCall as ApiQueryCall, QueryConstraint, ConcreteFact } from "./api"; type AbstractType = "Actor" | "Resource"; type ConcreteType<T extends string> = T extends AbstractType ? never : T; export type TypedVar<T extends string> = QueryVariable<ConcreteType<T>>; /** * Construct a new query variable of a specific type. * * @param type The actor/resource type of the variable to be created. * Note: This must NOT be the "Actor" or "Resource" abstract types. * To query for many types of results, make one request for each concrete * type. * @returns A new variable that can be used with `oso.buildQuery` APIs */ export declare function typedVar<T extends string>(type: ConcreteType<T>): QueryVariable<T>; declare class QueryVariable<T extends string> { private type; private id; constructor(type: T); getId(): string; getType(): string; toString(): string; } type QueryValue<V extends Value> = IntoValue<V> | TypedVar<V["type"]>; type QueryValues<A extends Value[]> = A extends [ infer HD extends Value, ...infer TL extends Value[] ] ? [QueryValue<HD>, ...QueryValues<TL>] : []; export type QueryArgs<FQ extends Fact> = FQ extends [ infer P extends string, ...infer A extends Value[] ] ? [P, ...QueryValues<A>] : never; type EvaluateArgItem = TypedVar<string> | [] | [EvaluateArgItem] | [EvaluateArgItem, EvaluateArgItem] | [EvaluateArgItem, EvaluateArgItem, EvaluateArgItem] | [EvaluateArgItem, EvaluateArgItem, EvaluateArgItem, EvaluateArgItem]; type EvaluateArg = undefined | EvaluateArgItem | Map<TypedVar<string>, EvaluateArg>; type EvaluateTupleResult<A extends EvaluateArgItem[], Depth extends unknown[]> = 10 extends Depth["length"] ? never : A extends [ infer HD extends EvaluateArgItem, ...infer TL extends EvaluateArgItem[] ] ? [ EvaluateResultItem<HD, [unknown, ...Depth]>, ...EvaluateTupleResult<TL, [unknown, ...Depth]> ] : []; type EvaluateResultItem<A extends EvaluateArgItem, Depth extends unknown[] = []> = A extends TypedVar<string> ? string : A extends EvaluateArgItem[] ? EvaluateTupleResult<A, Depth> : never; type EvaluateResult<A extends EvaluateArg> = A extends undefined ? boolean : A extends EvaluateArgItem ? EvaluateResultItem<A>[] : A extends Map<TypedVar<string>, infer B extends EvaluateArg> ? Map<string, EvaluateResult<B>> : never; /** * Helper class to support building a custom Oso query. * * Initialize this with `oso.buildQuery` and chain calls to `and` and `in` to add additional constraints. * * After building your query, run it and get the results by calling `evaluate`. */ export declare class QueryBuilder<PT extends DefaultPolarTypes> { private oso; private predicate; private calls; private constraints; private contextFacts; constructor(oso: Oso<PT>, predicate: ApiQueryCall, calls?: ApiQueryCall[], constraints?: Map<string, QueryConstraint>, contextFacts?: ConcreteFact[]); static init<PT extends DefaultPolarTypes>(oso: Oso<PT>, [predicate, ...args]: QueryArgs<PT["fact"] | PT["query"]>): QueryBuilder<PT>; /** * Add another condition that must be true of the query results. * For example: * ```typescript * // Query for all the repos on which the given actor can perform the given action, * // and require the repos to belong to the given folder * const repo = typedVar("Repo"); * const authorizedReposInFolder = await oso * .buildQuery(["allow", actor, action, repo]) * .and(["has_relation", repo, "folder", folder]) * .evaluate(repo); * ``` * @param args The rule or fact constraint to add to the query * @returns {QueryBuilder} */ and([predicate, ...args]: QueryArgs<PT["fact"] | PT["query"]>): QueryBuilder<PT>; /** * Constrain a query variable to be one of a set of values. * For example: * ```typescript * const repos = ["acme", "anvil"]; * const repo = typedVar("Repo"); * const action = typedVar("String"); * // Get all the actions the actor can perform on the repos that are in the given set * const authorizedActions = await oso * .buildQuery(["allow", actor, action, repo]) * .in(repo, repos) * .evaluate(action); * ``` * @param {TypedVar} v The variable to constrain * @param {string[]} values The set of allowed values for the constrained variable * @returns {QueryBuilder} */ in<T extends string>(v: QueryVariable<T>, values: string[]): QueryBuilder<PT>; /** * Add context facts to the query. * @param {IntoFact[]} contextFacts * @returns {QueryBuilder} */ withContextFacts(contextFacts: IntoFact<PT["fact"]>[]): QueryBuilder<PT>; /** * Evaluate the query. The shape of the return value is determined by what you pass in: * - If you pass no arguments, returns a boolean. For example: * ```typescript * // true if the given actor can perform the given action on the given resource * let allowed = await oso.buildQuery(["allow", actor, action, resource]).evaluate(); * ``` * - If you pass a variable, returns a list of values for that variable. For example: * ```typescript * let action = typedVar("String"); * // all the actions the actor can perform on the given resource- eg. ["read", "write"] * let actions = await oso.buildQuery(["allow", actor, action, resource]).evaluate(action); * ``` * - If you pass a tuple of variables, returns a list of tuples of values for those variables. For example: * ```typescript * let action = typedVar("String"); * let repo = typedVar("Repo"); * // an array of pairs of allowed actions and repo IDs- eg. [["read", "acme"], ["read", "anvil"], ["write", "anvil"]] * let pairs = await oso.buildQuery(["allow", actor, action, repo]).evaluate([action, repo]); * ``` * - If you pass a Map mapping one input variable (call it K) to another * (call it V), returns a Map of unique values of K to the unique values of * V for each value of K. For example: * ```typescript * let action = typedVar("String"); * let repo = typedVar("Repo"); * let map = await oso.buildQuery(["allow", actor, action, repo]).evaluate(new Map([[repo, action]])); * // a map of repo IDs to allowed actions- eg. new Map(Object.entries({ "acme": ["read"], "anvil": ["read", "write"]})) * ``` * * @param arg See above * @returns See above */ evaluate<Arg extends EvaluateArg = undefined>(arg?: Arg): Promise<EvaluateResult<Arg>>; /** * Fetches a complete SQL query that can be run against your database, selecting * a row for each authorized combination of the query variables in `columnNamesToQueryVars` * (ie. combinations of variables that satisfy the Oso query). * * See https://www.osohq.com/docs/app-integration/client-apis/node for examples and limitations. * * @param {Record<string, TypedVar<string>>?} columnNamesToQueryVars * A mapping of the desired column names to the query variables whose values * will be selected into those columns in the returned SQL query. * * If you pass an empty object or omit this parameter entirely, the returned SQL query * will select a single row with a boolean column called `result`. * * @returns {Promise<string>} SQL query containing the desired columns * @throws {TypeError} when columnNamesToQueryVars is empty or contains duplicate values * @throws {Error} */ evaluateLocalSelect(columnNamesToQueryVars?: Record<string, TypedVar<string>>): Promise<string>; /** * Fetches a SQL fragment, which you can embed into the `WHERE` clause of a * SQL query against your database to filter out unauthorized rows (ie. rows * that don't satisfy the Oso query). * * See https://www.osohq.com/docs/app-integration/client-apis/node for examples and limitations. * * @param {string} columnName the name of the SQL column to filter * @param {TypedVar<string>} queryVar the variable corresponding to the column to filter * @returns {Promise<string>} SQL fragment, suitable for embedding in a `WHERE` clause * @throws {Error} */ evaluateLocalFilter(columnName: string, queryVar: TypedVar<string>): Promise<string>; private asQuery; /** * The query API expects all call args to be variable names. This method helps * in this process by converting concrete arguments to temporary variables and * returning the variable names. */ private pushArg; private clone; } export {}; //# sourceMappingURL=query.d.ts.map