New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

oso

Package Overview
Dependencies
Maintainers
1
Versions
51
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

oso - npm Package Compare versions

Comparing version 0.4.1-rc3 to 0.5.0

bin/repl.js

3

dist/src/errors.d.ts

@@ -0,1 +1,2 @@

/** Base error type. */
export declare class PolarError extends Error {

@@ -18,3 +19,3 @@ constructor(msg: string);

export declare class InvalidCallError extends PolarError {
constructor(attr: string, instance: any);
constructor(instance: any, field: string);
}

@@ -21,0 +22,0 @@ export declare class KwargsConstructorError extends PolarError {

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.UnregisteredInstanceError = exports.UnregisteredClassError = exports.PolarFileNotFoundError = exports.PolarFileExtensionError = exports.PolarFileDuplicateContentError = exports.PolarFileContentsChangedError = exports.PolarFileAlreadyLoadedError = exports.InvalidQueryEventError = exports.KwargsConstructorError = exports.InvalidCallError = exports.InlineQueryFailedError = exports.DuplicateInstanceRegistrationError = exports.DuplicateClassAliasError = exports.PolarError = void 0;
const helpers_1 = require("./helpers");
/** Base error type. */
class PolarError extends Error {

@@ -38,4 +40,4 @@ constructor(msg) {

class InvalidCallError extends PolarError {
constructor(attr, instance) {
super(`Property '${attr}' does not exist on ${JSON.stringify(instance)}`);
constructor(instance, field) {
super(`${helpers_1.repr(instance)}.${field} is not a function`);
Object.setPrototypeOf(this, InvalidCallError.prototype);

@@ -42,0 +44,0 @@ }

import type { obj, QueryEvent } from './types';
/**
* Assemble the prototypal inheritance chain of a class.
*
* @returns The inheritance chain as a list of prototypes in most-to-least
* specific order.
*
* @internal
*/
export declare function ancestors(cls: Function): Function[];
/**
* Stringify a value.
*
* @returns A string representation of the input value.
*
* @internal
*/
export declare function repr(x: any): string;
/**
* Try to parse a JSON payload received from across the WebAssembly boundary
* into a valid [[`QueryEvent`]].
*
* @internal
*/
export declare function parseQueryEvent(event: string | obj): QueryEvent;
/**
* Promisified version of the pre-`fs/promises` asynchronous `fs.readFile`
* function since none of the following work on all Node.js versions we want to
* support (>= 10):
*
* ```ts
* import { readFile } from 'fs/promises';
* import { promises } from 'fs';
* const { readFile } = require('fs/promises');
* ```
*
* @internal
*/
export declare function readFile(file: string): Promise<string>;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseQueryEvent = exports.repr = exports.ancestors = void 0;
exports.readFile = exports.parseQueryEvent = exports.repr = exports.ancestors = void 0;
const util_1 = require("util");
const fs_1 = require("fs");
const errors_1 = require("./errors");
const types_1 = require("./types");
const root = Object.getPrototypeOf(() => { });
/**
* Assemble the prototypal inheritance chain of a class.
*
* @returns The inheritance chain as a list of prototypes in most-to-least
* specific order.
*
* @internal
*/
function ancestors(cls) {

@@ -12,3 +20,3 @@ const ancestors = [cls];

const parent = Object.getPrototypeOf(cls);
if (parent === root)
if (parent === Function.prototype)
return;

@@ -22,2 +30,9 @@ ancestors.push(parent);

exports.ancestors = ancestors;
/**
* Stringify a value.
*
* @returns A string representation of the input value.
*
* @internal
*/
function repr(x) {

@@ -27,2 +42,8 @@ return util_1.inspect(x);

exports.repr = repr;
/**
* Try to parse a JSON payload received from across the WebAssembly boundary
* into a valid [[`QueryEvent`]].
*
* @internal
*/
function parseQueryEvent(event) {

@@ -62,2 +83,8 @@ try {

exports.parseQueryEvent = parseQueryEvent;
/**
* Try to parse a JSON payload received from across the WebAssembly boundary as
* a [[`Result`]].
*
* @hidden
*/
function parseResult({ bindings }) {

@@ -72,2 +99,8 @@ if (typeof bindings !== 'object' ||

}
/**
* Try to parse a JSON payload received from across the WebAssembly boundary as
* a [[`MakeExternal`]].
*
* @hidden
*/
function parseMakeExternal(d) {

@@ -91,2 +124,8 @@ var _a, _b, _c, _d;

}
/**
* Try to parse a JSON payload received from across the WebAssembly boundary as
* an [[`ExternalCall`]].
*
* @hidden
*/
function parseExternalCall({ args, attribute, call_id: callId, instance, }) {

@@ -96,4 +135,4 @@ if (!Number.isSafeInteger(callId) ||

typeof attribute !== 'string' ||
!Array.isArray(args) ||
args.some((a) => !types_1.isPolarTerm(a)))
(args !== undefined &&
(!Array.isArray(args) || args.some((a) => !types_1.isPolarTerm(a)))))
throw new Error();

@@ -105,2 +144,8 @@ return {

}
/**
* Try to parse a JSON payload received from across the WebAssembly boundary as
* an [[`ExternalIsSubspecializer`]].
*
* @hidden
*/
function parseExternalIsSubspecializer({ call_id: callId, instance_id: instanceId, left_class_tag: leftTag, right_class_tag: rightTag, }) {

@@ -117,2 +162,8 @@ if (!Number.isSafeInteger(instanceId) ||

}
/**
* Try to parse a JSON payload received from across the WebAssembly boundary as
* an [[`ExternalIsa`]].
*
* @hidden
*/
function parseExternalIsa({ call_id: callId, instance, class_tag: tag, }) {

@@ -128,2 +179,8 @@ if (!Number.isSafeInteger(callId) ||

}
/**
* Try to parse a JSON payload received from across the WebAssembly boundary as
* an [[`ExternalUnify`]].
*
* @hidden
*/
function parseExternalUnify({ call_id: callId, left_instance_id: leftId, right_instance_id: rightId, }) {

@@ -139,2 +196,8 @@ if (!Number.isSafeInteger(callId) ||

}
/**
* Try to parse a JSON payload received from across the WebAssembly boundary as
* a [[`Debug`]].
*
* @hidden
*/
function parseDebug({ message }) {

@@ -148,2 +211,19 @@ if (typeof message !== 'string')

}
/**
* Promisified version of the pre-`fs/promises` asynchronous `fs.readFile`
* function since none of the following work on all Node.js versions we want to
* support (>= 10):
*
* ```ts
* import { readFile } from 'fs/promises';
* import { promises } from 'fs';
* const { readFile } = require('fs/promises');
* ```
*
* @internal
*/
function readFile(file) {
return new Promise((res, rej) => fs_1.readFile(file, { encoding: 'utf8' }, (err, contents) => err === null ? res(contents) : rej(err)));
}
exports.readFile = readFile;
//# sourceMappingURL=helpers.js.map
import type { Polar as FfiPolar } from './polar_wasm_api';
import type { Class, PolarTerm } from './types';
import type { Class, EqualityFn, PolarTerm } from './types';
/**
* Translator between Polar and JavaScript.
*
* @internal
*/
export declare class Host {
#private;
/**
* Shallow clone a host to extend its state for the duration of a particular
* query without modifying the longer-lived [[`Polar.#host`]] state.
*
* @internal
*/
static clone(host: Host): Host;
constructor(ffiPolar: FfiPolar);
/** @internal */
constructor(ffiPolar: FfiPolar, equalityFn: EqualityFn);
/**
* Fetch a JavaScript class from the [[`#classes`]] cache.
*
* @param name Class name to look up.
*
* @internal
*/
private getClass;
/**
* Store a JavaScript class in the [[`#classes`]] cache.
*
* @param cls Class to cache.
* @param name Optional alias under which to cache the class. Defaults to the
* class's `name` property.
*
* @internal
*/
cacheClass<T>(cls: Class<T>, name?: string): string;
/**
* Check if an instance exists in the [[`instances`]] cache.
*
* @internal
*/
hasInstance(id: number): boolean;
/**
* Fetch a JavaScript instance from the [[`#instances`]] cache.
*
* Public for the test suite.
*
* @internal
*/
getInstance(id: number): any;
/**
* Store a JavaScript instance in the [[`#instances`]] cache, fetching a new
* instance ID from the Polar VM if an ID is not provided.
*
* @internal
*/
private cacheInstance;
makeInstance(name: string, fields: PolarTerm[], id: number): number;
isSubspecializer(id: number, left: string, right: string): boolean;
isa(instance: PolarTerm, name: string): boolean;
unify(left: number, right: number): boolean;
/**
* Construct a JavaScript instance and store it in the [[`#instances`]]
* cache.
*
* @internal
*/
makeInstance(name: string, fields: PolarTerm[], id: number): Promise<void>;
/**
* Check if the left class is more specific than the right class with respect
* to the given instance.
*
* @internal
*/
isSubspecializer(id: number, left: string, right: string): Promise<boolean>;
/**
* Check if the given instance is an instance of a particular class.
*
* @internal
*/
isa(polarInstance: PolarTerm, name: string): Promise<boolean>;
/**
* Check if two instances unify according to the [[`#equalityFn`]].
*
* @internal
*/
unify(leftId: number, rightId: number): Promise<boolean>;
/**
* Turn a JavaScript value into a Polar term that's ready to be sent to the
* Polar VM.
*
* @internal
*/
toPolar(v: any): PolarTerm;
toJs(v: PolarTerm): any;
/**
* Turn a Polar term from the Polar VM into a JavaScript value.
*
* @internal
*/
toJs(v: PolarTerm): Promise<any>;
}

@@ -15,9 +15,5 @@ "use strict";

};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
var _ffiPolar, _classes, _instances;
var _ffiPolar, _classes, _instances, _equalityFn;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Host = void 0;
const isEqual_1 = __importDefault(require("lodash/isEqual"));
const errors_1 = require("./errors");

@@ -28,13 +24,27 @@ const helpers_1 = require("./helpers");

const types_1 = require("./types");
/**
* Translator between Polar and JavaScript.
*
* @internal
*/
class Host {
constructor(ffiPolar) {
/** @internal */
constructor(ffiPolar, equalityFn) {
_ffiPolar.set(this, void 0);
_classes.set(this, void 0);
_instances.set(this, void 0);
_equalityFn.set(this, void 0);
__classPrivateFieldSet(this, _ffiPolar, ffiPolar);
__classPrivateFieldSet(this, _classes, new Map());
__classPrivateFieldSet(this, _instances, new Map());
__classPrivateFieldSet(this, _equalityFn, equalityFn);
}
/**
* Shallow clone a host to extend its state for the duration of a particular
* query without modifying the longer-lived [[`Polar.#host`]] state.
*
* @internal
*/
static clone(host) {
const clone = new Host(__classPrivateFieldGet(host, _ffiPolar));
const clone = new Host(__classPrivateFieldGet(host, _ffiPolar), __classPrivateFieldGet(host, _equalityFn));
__classPrivateFieldSet(clone, _classes, new Map(__classPrivateFieldGet(host, _classes)));

@@ -44,2 +54,9 @@ __classPrivateFieldSet(clone, _instances, new Map(__classPrivateFieldGet(host, _instances)));

}
/**
* Fetch a JavaScript class from the [[`#classes`]] cache.
*
* @param name Class name to look up.
*
* @internal
*/
getClass(name) {

@@ -51,2 +68,11 @@ const cls = __classPrivateFieldGet(this, _classes).get(name);

}
/**
* Store a JavaScript class in the [[`#classes`]] cache.
*
* @param cls Class to cache.
* @param name Optional alias under which to cache the class. Defaults to the
* class's `name` property.
*
* @internal
*/
cacheClass(cls, name) {

@@ -64,6 +90,17 @@ const clsName = name === undefined ? cls.name : name;

}
/**
* Check if an instance exists in the [[`instances`]] cache.
*
* @internal
*/
hasInstance(id) {
return __classPrivateFieldGet(this, _instances).has(id);
}
// Public for the test suite.
/**
* Fetch a JavaScript instance from the [[`#instances`]] cache.
*
* Public for the test suite.
*
* @internal
*/
getInstance(id) {

@@ -74,2 +111,8 @@ if (!this.hasInstance(id))

}
/**
* Store a JavaScript instance in the [[`#instances`]] cache, fetching a new
* instance ID from the Polar VM if an ID is not provided.
*
* @internal
*/
cacheInstance(instance, id) {

@@ -83,10 +126,23 @@ let instanceId = id;

}
makeInstance(name, fields, id) {
/**
* Construct a JavaScript instance and store it in the [[`#instances`]]
* cache.
*
* @internal
*/
async makeInstance(name, fields, id) {
const cls = this.getClass(name);
const args = fields.map(f => this.toJs(f));
const args = await Promise.all(fields.map(async (f) => await this.toJs(f)));
const instance = new cls(...args);
return this.cacheInstance(instance, id);
this.cacheInstance(instance, id);
}
isSubspecializer(id, left, right) {
const instance = this.getInstance(id);
/**
* Check if the left class is more specific than the right class with respect
* to the given instance.
*
* @internal
*/
async isSubspecializer(id, left, right) {
let instance = this.getInstance(id);
instance = instance instanceof Promise ? await instance : instance;
if (!((instance === null || instance === void 0 ? void 0 : instance.constructor) instanceof Function))

@@ -107,10 +163,30 @@ return false;

}
isa(instance, name) {
const jsInstance = this.toJs(instance);
/**
* Check if the given instance is an instance of a particular class.
*
* @internal
*/
async isa(polarInstance, name) {
const instance = await this.toJs(polarInstance);
const cls = this.getClass(name);
return jsInstance instanceof cls || (jsInstance === null || jsInstance === void 0 ? void 0 : jsInstance.constructor) === cls;
return instance instanceof cls || (instance === null || instance === void 0 ? void 0 : instance.constructor) === cls;
}
unify(left, right) {
return isEqual_1.default(this.getInstance(left), this.getInstance(right));
/**
* Check if two instances unify according to the [[`#equalityFn`]].
*
* @internal
*/
async unify(leftId, rightId) {
let left = this.getInstance(leftId);
let right = this.getInstance(rightId);
left = left instanceof Promise ? await left : left;
right = right instanceof Promise ? await right : right;
return __classPrivateFieldGet(this, _equalityFn).call(this, left, right);
}
/**
* Turn a JavaScript value into a Polar term that's ready to be sent to the
* Polar VM.
*
* @internal
*/
toPolar(v) {

@@ -135,6 +211,19 @@ switch (true) {

const instance_id = this.cacheInstance(v);
return { value: { ExternalInstance: { instance_id, repr: helpers_1.repr(v) } } };
return {
value: {
ExternalInstance: {
instance_id,
repr: helpers_1.repr(v),
constructor: undefined,
},
},
};
}
}
toJs(v) {
/**
* Turn a Polar term from the Polar VM into a JavaScript value.
*
* @internal
*/
async toJs(v) {
const t = v.value;

@@ -156,11 +245,12 @@ if (types_1.isPolarStr(t)) {

else if (types_1.isPolarList(t)) {
return t.List.map(this.toJs);
return await Promise.all(t.List.map(async (el) => await this.toJs(el)));
}
else if (types_1.isPolarDict(t)) {
const { fields } = t.Dictionary;
const entries = typeof fields.entries === 'function'
let entries = typeof fields.entries === 'function'
? Array.from(fields.entries())
: Object.entries(fields);
entries = await Promise.all(entries.map(async ([k, v]) => [k, await this.toJs(v)]));
return entries.reduce((obj, [k, v]) => {
obj[k] = this.toJs(v);
obj[k] = v;
return obj;

@@ -170,6 +260,9 @@ }, {});

else if (types_1.isPolarInstance(t)) {
return this.getInstance(t.ExternalInstance.instance_id);
const i = this.getInstance(t.ExternalInstance.instance_id);
return i instanceof Promise ? await i : i;
}
else if (types_1.isPolarPredicate(t)) {
return new Predicate_1.Predicate(t.Call.name, t.Call.args.map(a => this.toJs(a)));
let { name, args } = t.Call;
args = await Promise.all(args.map(async (a) => await this.toJs(a)));
return new Predicate_1.Predicate(name, args);
}

@@ -182,3 +275,3 @@ else if (types_1.isPolarVariable(t)) {

exports.Host = Host;
_ffiPolar = new WeakMap(), _classes = new WeakMap(), _instances = new WeakMap();
_ffiPolar = new WeakMap(), _classes = new WeakMap(), _instances = new WeakMap(), _equalityFn = new WeakMap();
//# sourceMappingURL=Host.js.map

@@ -0,1 +1,2 @@

/** An HTTP resource. */
export declare class Http {

@@ -2,0 +3,0 @@ readonly hostname: string;

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Http = void 0;
/** An HTTP resource. */
class Http {

@@ -5,0 +6,0 @@ constructor(hostname, path, query) {

import { Polar } from './Polar';
import type { Options } from './types';
/** The oso authorization API. */
export declare class Oso extends Polar {
constructor();
isAllowed(actor: unknown, action: unknown, resource: unknown): boolean;
constructor(opts?: Options);
/**
* Query the knowledge base to determine whether an actor is allowed to
* perform an action upon a resource.
*
* @param actor Subject.
* @param action Verb.
* @param resource Object.
* @returns An access control decision.
*/
isAllowed(actor: unknown, action: unknown, resource: unknown): Promise<boolean>;
}

@@ -7,11 +7,21 @@ "use strict";

const PathMapper_1 = require("./PathMapper");
/** The oso authorization API. */
class Oso extends Polar_1.Polar {
constructor() {
super();
constructor(opts = {}) {
super(opts);
this.registerClass(Http_1.Http);
this.registerClass(PathMapper_1.PathMapper);
}
isAllowed(actor, action, resource) {
/**
* Query the knowledge base to determine whether an actor is allowed to
* perform an action upon a resource.
*
* @param actor Subject.
* @param action Verb.
* @param resource Object.
* @returns An access control decision.
*/
async isAllowed(actor, action, resource) {
const results = this.queryRule('allow', actor, action, resource);
const { done } = results.next();
const { done } = await results.next();
results.return();

@@ -18,0 +28,0 @@ return !done;

import type { obj } from './types';
/**
* Utility class to map from a forward-slash-delimited path to a dictionary
* of matched path segments.
*/
export declare class PathMapper {
#private;
constructor(template: string);
/**
* Apply the templated pattern to a provided string, returning an object of
* matching capture groups.
*/
map(str: string): obj;
}

@@ -18,2 +18,6 @@ "use strict";

exports.PathMapper = void 0;
/**
* Utility class to map from a forward-slash-delimited path to a dictionary
* of matched path segments.
*/
class PathMapper {

@@ -38,2 +42,6 @@ constructor(template) {

}
/**
* Apply the templated pattern to a provided string, returning an object of
* matching capture groups.
*/
map(str) {

@@ -40,0 +48,0 @@ var _a;

@@ -10,2 +10,3 @@ /* tslint:disable */

export function query_appError(a: number, b: number, c: number): void;
export function query_nextMessage(a: number): number;
export function __wbg_polar_free(a: number): void;

@@ -19,4 +20,5 @@ export function polar_wasm_new(): number;

export function polar_newId(a: number): number;
export function polar_nextMessage(a: number): number;
export function __wbindgen_malloc(a: number): number;
export function __wbindgen_realloc(a: number, b: number, c: number): number;
export function __wbindgen_free(a: number, b: number): void;

@@ -38,2 +38,6 @@ /* tslint:disable */

newId(): number;
/**
* @returns {any}
*/
nextMessage(): any;
}

@@ -66,2 +70,6 @@ /**

appError(msg: string): void;
/**
* @returns {any}
*/
nextMessage(): any;
}

@@ -160,2 +160,9 @@ let imports = {};

}
/**
* @returns {any}
*/
nextMessage() {
var ret = wasm.polar_nextMessage(this.ptr);
return takeObject(ret);
}
}

@@ -219,2 +226,9 @@ module.exports.Polar = Polar;

}
/**
* @returns {any}
*/
nextMessage() {
var ret = wasm.query_nextMessage(this.ptr);
return takeObject(ret);
}
}

@@ -221,0 +235,0 @@ module.exports.Query = Query;

import { Host } from './Host';
import { Predicate } from './Predicate';
import type { Class, QueryResult } from './types';
import type { Class, Options, QueryResult } from './types';
/** Create and manage an instance of the Polar runtime. */
export declare class Polar {
#private;
constructor();
constructor(opts?: Options);
/**
* For tests only.
*
* @hidden
*/
__host(): Host;
/**
* Process messages received from the Polar VM.
*
* @internal
*/
private processMessages;
/**
* Replace the current Polar VM instance, clearing out all loaded policy but
* retaining all registered classes and constants.
*/
clear(): void;
loadFile(name: string): void;
loadStr(contents: string, name?: string): void;
/**
* Load a Polar policy file.
*/
loadFile(file: string): Promise<void>;
/**
* Load a Polar policy string.
*/
loadStr(contents: string, name?: string): Promise<void>;
/**
* Query for a Polar predicate or string.
*/
query(q: Predicate | string): QueryResult;
/**
* Query for a Polar rule.
*/
queryRule(name: string, ...args: unknown[]): QueryResult;
repl(load: boolean): void;
/**
* Start a REPL session.
*/
repl(files?: string[]): Promise<void>;
/**
* Register a JavaScript class for use in Polar policies.
*/
registerClass<T>(cls: Class<T>, alias?: string): void;
/**
* Register a JavaScript value for use in Polar policies.
*/
registerConstant(name: string, value: any): void;
}

@@ -18,6 +18,6 @@ "use strict";

exports.Polar = void 0;
const fs_1 = require("fs");
const crypto_1 = require("crypto");
const path_1 = require("path");
const readline_1 = require("readline");
const process_1 = require("process");
const errors_1 = require("./errors");

@@ -28,12 +28,51 @@ const Query_1 = require("./Query");

const Predicate_1 = require("./Predicate");
const messages_1 = require("./messages");
const helpers_1 = require("./helpers");
// Optional ANSI escape sequences for the REPL.
let RESET = '';
let FG_BLUE = '';
let FG_RED = '';
if (typeof process_1.stdout.hasColors === 'function' &&
process_1.stdout.hasColors() &&
typeof process_1.stderr.hasColors === 'function' &&
process_1.stderr.hasColors()) {
RESET = '\x1b[0m';
FG_BLUE = '\x1b[34m';
FG_RED = '\x1b[31m';
}
/** Create and manage an instance of the Polar runtime. */
class Polar {
constructor() {
constructor(opts = {}) {
/**
* Internal WebAssembly module.
*
* @internal
*/
_ffiPolar.set(this, void 0);
/**
* Manages registration and comparison of JavaScript classes and instances
* as well as translations between Polar and JavaScript values.
*
* @internal
*/
_host.set(this, void 0);
/**
* Tracking Polar files loaded into the knowledge base by a hash of their
* contents.
*
* @internal
*/
_loadedContents.set(this, void 0);
/**
* Tracking Polar files loaded into the knowledge base by file name.
*
* @internal
*/
_loadedFiles.set(this, void 0);
__classPrivateFieldSet(this, _ffiPolar, new polar_wasm_api_1.Polar());
__classPrivateFieldSet(this, _host, new Host_1.Host(__classPrivateFieldGet(this, _ffiPolar)));
const equalityFn = opts.equalityFn || ((x, y) => x == y);
__classPrivateFieldSet(this, _host, new Host_1.Host(__classPrivateFieldGet(this, _ffiPolar), equalityFn));
__classPrivateFieldSet(this, _loadedContents, new Map());
__classPrivateFieldSet(this, _loadedFiles, new Map());
// Register built-in classes.
this.registerClass(Boolean);

@@ -46,6 +85,27 @@ this.registerClass(Number, 'Integer');

}
// For tests only.
/**
* For tests only.
*
* @hidden
*/
__host() {
return __classPrivateFieldGet(this, _host);
}
/**
* Process messages received from the Polar VM.
*
* @internal
*/
processMessages() {
while (true) {
let msg = __classPrivateFieldGet(this, _ffiPolar).nextMessage();
if (msg === undefined)
break;
messages_1.processMessage(msg);
}
}
/**
* Replace the current Polar VM instance, clearing out all loaded policy but
* retaining all registered classes and constants.
*/
clear() {

@@ -58,9 +118,11 @@ __classPrivateFieldGet(this, _loadedContents).clear();

}
loadFile(name) {
if (path_1.extname(name) !== '.polar')
throw new errors_1.PolarFileExtensionError(name);
let file = path_1.isAbsolute(name) ? name : path_1.resolve(__dirname, name);
/**
* Load a Polar policy file.
*/
async loadFile(file) {
if (path_1.extname(file) !== '.polar')
throw new errors_1.PolarFileExtensionError(file);
let contents;
try {
contents = fs_1.readFileSync(file, { encoding: 'utf8' });
contents = await helpers_1.readFile(file);
}

@@ -82,14 +144,19 @@ catch (e) {

throw new errors_1.PolarFileDuplicateContentError(file, existingFile);
this.loadStr(contents, file);
await this.loadStr(contents, file);
__classPrivateFieldGet(this, _loadedContents).set(hash, file);
__classPrivateFieldGet(this, _loadedFiles).set(file, hash);
}
loadStr(contents, name) {
/**
* Load a Polar policy string.
*/
async loadStr(contents, name) {
__classPrivateFieldGet(this, _ffiPolar).loadFile(contents, name);
this.processMessages();
while (true) {
const query = __classPrivateFieldGet(this, _ffiPolar).nextInlineQuery();
this.processMessages();
if (query === undefined)
break;
const { results } = new Query_1.Query(query, __classPrivateFieldGet(this, _host));
const { done } = results.next();
const { done } = await results.next();
results.return();

@@ -100,2 +167,5 @@ if (done)

}
/**
* Query for a Polar predicate or string.
*/
query(q) {

@@ -111,20 +181,45 @@ const host = Host_1.Host.clone(__classPrivateFieldGet(this, _host));

}
this.processMessages();
return new Query_1.Query(ffiQuery, host).results;
}
/**
* Query for a Polar rule.
*/
queryRule(name, ...args) {
return this.query(new Predicate_1.Predicate(name, args));
}
repl(load) {
if (load)
process.argv.slice(2).forEach(this.loadFile);
readline_1.createInterface({
/**
* Start a REPL session.
*/
async repl(files) {
const rl = readline_1.createInterface({
input: process.stdin,
output: process.stdout,
prompt: 'query> ',
prompt: FG_BLUE + 'query> ' + RESET,
tabSize: 4,
}).on('line', line => {
});
let loadError;
try {
if (files === null || files === void 0 ? void 0 : files.length)
await Promise.all(files.map(f => this.loadFile(f)));
}
catch (e) {
loadError = e;
}
if (loadError !== undefined) {
console.error(FG_RED + 'One or more files failed to load.' + RESET);
console.error(loadError.message);
}
rl.prompt();
rl.on('line', async (line) => {
const input = line.trim().replace(/;+$/, '');
try {
if (input === '')
return;
const ffiQuery = __classPrivateFieldGet(this, _ffiPolar).newQueryFromStr(input);
const results = Array.from(new Query_1.Query(ffiQuery, __classPrivateFieldGet(this, _host)).results);
const query = new Query_1.Query(ffiQuery, __classPrivateFieldGet(this, _host));
const results = [];
for await (const result of query.results) {
results.push(result);
}
if (results.length === 0) {

@@ -139,3 +234,5 @@ console.log(false);

else {
console.log(JSON.stringify(result, null, 4));
for (const [variable, value] of result) {
console.log(variable + ' => ' + helpers_1.repr(value));
}
}

@@ -146,14 +243,16 @@ }

catch (e) {
if (e.kind.split('::')[0] === 'ParseError') {
console.log(`Parse error: ${e}`);
}
else if (e instanceof errors_1.PolarError) {
console.log(e);
}
else {
throw e;
}
console.error(FG_RED + e.name + RESET);
console.error(e.message);
}
finally {
rl.prompt();
}
});
return new Promise((resolve, _) => {
rl.on('close', () => resolve());
});
}
/**
* Register a JavaScript class for use in Polar policies.
*/
registerClass(cls, alias) {

@@ -163,2 +262,5 @@ const name = __classPrivateFieldGet(this, _host).cacheClass(cls, alias);

}
/**
* Register a JavaScript value for use in Polar policies.
*/
registerConstant(name, value) {

@@ -165,0 +267,0 @@ const term = __classPrivateFieldGet(this, _host).toPolar(value);

@@ -0,1 +1,2 @@

/** Polar predicate. */
export declare class Predicate {

@@ -2,0 +3,0 @@ readonly name: string;

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Predicate = void 0;
/** Polar predicate. */
class Predicate {

@@ -5,0 +6,0 @@ constructor(name, args) {

import type { Query as FfiQuery } from './polar_wasm_api';
import { Host } from './Host';
import type { QueryResult } from './types';
/**
* A single Polar query.
*
* @internal
*/
export declare class Query {

@@ -8,9 +13,60 @@ #private;

constructor(ffiQuery: FfiQuery, host: Host);
/**
* Process messages received from the Polar VM.
*
* @internal
*/
private processMessages;
/**
* Send result of predicate check back to the Polar VM.
*
* @internal
*/
private questionResult;
/**
* Register a JavaScript method call or property lookup, wrapping the call
* result in an `AsyncGenerator` if it isn't already one.
*
* @param field The field to look up.
* @param callId The Polar VM-assigned ID of the call.
* @param instance The instance on which to perform the field lookup.
* @param args If it's a method call (as opposed to a field lookup), the
* method will be called with these arguments.
*
* @internal
*/
private registerCall;
/**
* Send next result of JavaScript method call or property lookup to the Polar
* VM.
*
* @internal
*/
private callResult;
/**
* Retrieve the next result from a registered call and prepare it for
* transmission back to the Polar VM.
*
* @internal
*/
private nextCallResult;
/**
* Send application error back to the Polar VM.
*
* @internal
*/
private applicationError;
/**
* Coordinate between [[`registerCall`]], [[`nextCallResult`]], and
* [[`callResult`]] to handle an application call.
*
* @internal
*/
private handleCall;
/**
* Create an `AsyncGenerator` that can be polled to advance the query loop.
*
* @internal
*/
private start;
}

@@ -21,3 +21,9 @@ "use strict";

const errors_1 = require("./errors");
const messages_1 = require("./messages");
const types_1 = require("./types");
/**
* A single Polar query.
*
* @internal
*/
class Query {

@@ -33,53 +39,86 @@ constructor(ffiQuery, host) {

}
/**
* Process messages received from the Polar VM.
*
* @internal
*/
processMessages() {
while (true) {
let msg = __classPrivateFieldGet(this, _ffiQuery).nextMessage();
if (msg === undefined)
break;
messages_1.processMessage(msg);
}
}
/**
* Send result of predicate check back to the Polar VM.
*
* @internal
*/
questionResult(result, callId) {
__classPrivateFieldGet(this, _ffiQuery).questionResult(callId, result);
}
registerCall(attr, callId, instance, args) {
/**
* Register a JavaScript method call or property lookup, wrapping the call
* result in an `AsyncGenerator` if it isn't already one.
*
* @param field The field to look up.
* @param callId The Polar VM-assigned ID of the call.
* @param instance The instance on which to perform the field lookup.
* @param args If it's a method call (as opposed to a field lookup), the
* method will be called with these arguments.
*
* @internal
*/
async registerCall(field, callId, instance, args) {
if (__classPrivateFieldGet(this, _calls).has(callId))
return;
const jsArgs = args.map(a => __classPrivateFieldGet(this, _host).toJs(a));
const jsInstance = __classPrivateFieldGet(this, _host).toJs(instance);
const jsAttr = jsInstance[attr];
if (jsAttr === undefined)
throw new errors_1.InvalidCallError(attr, jsInstance);
let result;
if (types_1.isGenerator(jsAttr)) {
// The Generator#next method only takes 0 or 1 args.
if (jsArgs.length > 1)
throw new errors_1.InvalidCallError(attr, jsInstance);
result = (function* () {
while (true) {
const { done, value } = jsArgs.length
? jsAttr.next(jsArgs[0])
: jsAttr.next();
if (done)
return;
yield value;
const receiver = await __classPrivateFieldGet(this, _host).toJs(instance);
let value = receiver[field];
if (args !== undefined) {
if (typeof value === 'function') {
// If value is a function, call it with the provided args.
const jsArgs = args.map(async (a) => await __classPrivateFieldGet(this, _host).toJs(a));
value = receiver[field](...(await Promise.all(jsArgs)));
}
else {
// Error on attempt to call non-function.
throw new errors_1.InvalidCallError(receiver, field);
}
}
const generator = (async function* () {
if (types_1.isIterableIterator(value)) {
// If the call result is an iterable iterator, yield from it.
yield* value;
}
else if (types_1.isAsyncIterator(value)) {
// Same for async iterators.
for await (const result of value) {
yield result;
}
})();
}
else if (types_1.isGeneratorFunction(jsAttr)) {
result = jsInstance[attr](...jsArgs);
}
else if (typeof jsAttr === 'function') {
result = (function* () {
yield jsInstance[attr](...jsArgs);
})();
}
else {
// Blow up if jsArgs is not [] since the user is attempting to invoke +
// pass args to something that isn't callable.
if (jsArgs.length > 0)
throw new errors_1.InvalidCallError(attr, jsInstance);
result = (function* () {
yield jsAttr;
})();
}
__classPrivateFieldGet(this, _calls).set(callId, result);
}
else {
// Otherwise, yield it.
yield value;
}
})();
__classPrivateFieldGet(this, _calls).set(callId, generator);
}
/**
* Send next result of JavaScript method call or property lookup to the Polar
* VM.
*
* @internal
*/
callResult(callId, result) {
__classPrivateFieldGet(this, _ffiQuery).callResult(callId, result);
}
nextCallResult(callId) {
const { done, value } = __classPrivateFieldGet(this, _calls).get(callId).next();
/**
* Retrieve the next result from a registered call and prepare it for
* transmission back to the Polar VM.
*
* @internal
*/
async nextCallResult(callId) {
const { done, value } = await __classPrivateFieldGet(this, _calls).get(callId).next();
if (done)

@@ -89,13 +128,24 @@ return undefined;

}
/**
* Send application error back to the Polar VM.
*
* @internal
*/
applicationError(message) {
__classPrivateFieldGet(this, _ffiQuery).appError(message);
}
handleCall(attr, callId, instance, args) {
/**
* Coordinate between [[`registerCall`]], [[`nextCallResult`]], and
* [[`callResult`]] to handle an application call.
*
* @internal
*/
async handleCall(attr, callId, instance, args) {
let result;
try {
this.registerCall(attr, callId, instance, args);
result = this.nextCallResult(callId);
await this.registerCall(attr, callId, instance, args);
result = await this.nextCallResult(callId);
}
catch (e) {
if (e instanceof errors_1.InvalidCallError) {
if (e instanceof TypeError || e instanceof errors_1.InvalidCallError) {
this.applicationError(e.message);

@@ -111,6 +161,12 @@ }

}
*start() {
/**
* Create an `AsyncGenerator` that can be polled to advance the query loop.
*
* @internal
*/
async *start() {
try {
while (true) {
const nextEvent = __classPrivateFieldGet(this, _ffiQuery).nextEvent();
this.processMessages();
const event = helpers_1.parseQueryEvent(nextEvent);

@@ -124,3 +180,3 @@ switch (event.kind) {

for (const [k, v] of bindings.entries()) {
transformed.set(k, __classPrivateFieldGet(this, _host).toJs(v));
transformed.set(k, await __classPrivateFieldGet(this, _host).toJs(v));
}

@@ -133,3 +189,3 @@ yield transformed;

throw new errors_1.DuplicateInstanceRegistrationError(instanceId);
__classPrivateFieldGet(this, _host).makeInstance(tag, fields, instanceId);
await __classPrivateFieldGet(this, _host).makeInstance(tag, fields, instanceId);
break;

@@ -139,3 +195,3 @@ }

const { attribute, callId, instance, args, } = event.data;
this.handleCall(attribute, callId, instance, args);
await this.handleCall(attribute, callId, instance, args);
break;

@@ -145,3 +201,3 @@ }

const { instanceId, leftTag, rightTag, callId, } = event.data;
const answer = __classPrivateFieldGet(this, _host).isSubspecializer(instanceId, leftTag, rightTag);
const answer = await __classPrivateFieldGet(this, _host).isSubspecializer(instanceId, leftTag, rightTag);
this.questionResult(answer, callId);

@@ -152,3 +208,3 @@ break;

const { instance, tag, callId } = event.data;
const answer = __classPrivateFieldGet(this, _host).isa(instance, tag);
const answer = await __classPrivateFieldGet(this, _host).isa(instance, tag);
this.questionResult(answer, callId);

@@ -159,3 +215,3 @@ break;

const { leftId, rightId, callId } = event.data;
const answer = __classPrivateFieldGet(this, _host).unify(leftId, rightId);
const answer = await __classPrivateFieldGet(this, _host).unify(leftId, rightId);
this.questionResult(answer, callId);

@@ -177,2 +233,3 @@ break;

__classPrivateFieldGet(this, _ffiQuery).debugCommand(JSON.stringify(command));
this.processMessages();
});

@@ -179,0 +236,0 @@ break;

@@ -0,23 +1,82 @@

/**
* Polar string type.
*
* @internal
*/
interface PolarStr {
String: string;
}
export declare function isPolarStr(v: PolarType): v is PolarStr;
/**
* Type guard to test if a Polar value received from across the WebAssembly
* boundary is a Polar string.
*
* @internal
*/
export declare function isPolarStr(v: PolarValue): v is PolarStr;
/**
* Polar numeric type.
*
* @internal
*/
interface PolarNum {
Number: PolarFloat | PolarInt;
}
export declare function isPolarNum(v: PolarType): v is PolarNum;
/**
* Type guard to test if a Polar value received from across the WebAssembly
* boundary is a Polar numeric.
*
* @internal
*/
export declare function isPolarNum(v: PolarValue): v is PolarNum;
/**
* Polar floating point type.
*
* @internal
*/
interface PolarFloat {
Float: number;
}
/**
* Polar integer type.
*
* @internal
*/
interface PolarInt {
Integer: number;
}
/**
* Polar boolean type.
*
* @internal
*/
interface PolarBool {
Boolean: boolean;
}
export declare function isPolarBool(v: PolarType): v is PolarBool;
/**
* Type guard to test if a Polar value received from across the WebAssembly
* boundary is a Polar boolean.
*
* @internal
*/
export declare function isPolarBool(v: PolarValue): v is PolarBool;
/**
* Polar list type.
*
* @internal
*/
interface PolarList {
List: PolarTerm[];
}
export declare function isPolarList(v: PolarType): v is PolarList;
/**
* Type guard to test if a Polar value received from across the WebAssembly
* boundary is a Polar list.
*
* @internal
*/
export declare function isPolarList(v: PolarValue): v is PolarList;
/**
* Polar dictionary type.
*
* @internal
*/
interface PolarDict {

@@ -30,3 +89,14 @@ Dictionary: {

}
export declare function isPolarDict(v: PolarType): v is PolarDict;
/**
* Type guard to test if a Polar value received from across the WebAssembly
* boundary is a Polar dictionary.
*
* @internal
*/
export declare function isPolarDict(v: PolarValue): v is PolarDict;
/**
* Polar predicate type.
*
* @internal
*/
interface PolarPredicate {

@@ -38,5 +108,29 @@ Call: {

}
/**
* Type guard to test if a Polar value received from across the WebAssembly
* boundary is a Polar predicate.
*
* @internal
*/
export declare function isPolarPredicate(v: PolarValue): v is PolarPredicate;
/**
* Polar variable type.
*
* @internal
*/
interface PolarVariable {
Variable: string;
}
/**
* Type guard to test if a Polar value received from across the WebAssembly
* boundary is a Polar variable.
*
* @internal
*/
export declare function isPolarVariable(v: PolarValue): v is PolarVariable;
/**
* Polar application instance type.
*
* @internal
*/
interface PolarInstance {

@@ -46,18 +140,54 @@ ExternalInstance: {

repr: string;
constructor?: PolarTerm;
};
}
export declare function isPolarInstance(v: PolarType): v is PolarInstance;
export declare function isPolarPredicate(v: PolarType): v is PolarPredicate;
export declare function isPolarVariable(v: PolarType): v is PolarVariable;
declare type PolarType = PolarStr | PolarNum | PolarBool | PolarList | PolarDict | PolarPredicate | PolarVariable | PolarInstance;
/**
* Type guard to test if a Polar value received from across the WebAssembly
* boundary is a Polar application instance.
*
* @internal
*/
export declare function isPolarInstance(v: PolarValue): v is PolarInstance;
/**
* Union of Polar value types.
*
* @internal
*/
declare type PolarValue = PolarStr | PolarNum | PolarBool | PolarList | PolarDict | PolarPredicate | PolarVariable | PolarInstance;
/**
* Union of Polar value types.
*
* @internal
*/
export interface PolarTerm {
value: PolarType;
value: PolarValue;
}
/**
* Type guard to test if a JSON payload received from across the WebAssembly
* boundary contains a valid Polar term.
*
* @internal
*/
export declare function isPolarTerm(v: any): v is PolarTerm;
/**
* A constructable (via the `new` keyword) application class.
*
* @internal
*/
export declare type Class<T extends {} = {}> = new (...args: any[]) => T;
export declare function isGenerator(x: any): x is Generator;
export declare function isGeneratorFunction(x: any): x is GeneratorFunction;
/**
* The `Result` [[`QueryEvent`]] represents a single result from a query
* containing any variables bound during the evaluation of the query.
*
* @internal
*/
export interface Result {
bindings: Map<string, PolarTerm>;
}
/**
* The `MakeExternal` [[`QueryEvent`]] is how Polar constructs application
* instances during the evaluation of a query.
*
* @internal
*/
export interface MakeExternal {

@@ -68,2 +198,9 @@ instanceId: number;

}
/**
* The `ExternalCall` [[`QueryEvent`]] is how Polar invokes JavaScript
* functions registered as constants, methods on built-in types, and methods on
* registered application classes during the evaluation of a query.
*
* @internal
*/
export interface ExternalCall {

@@ -73,4 +210,10 @@ callId: number;

attribute: string;
args: PolarTerm[];
args?: PolarTerm[];
}
/**
* The `ExternalIsSubspecializer` [[`QueryEvent`]] is how Polar determines
* which of two classes is more specific with respect to a given instance.
*
* @internal
*/
export interface ExternalIsSubspecializer {

@@ -82,2 +225,8 @@ instanceId: number;

}
/**
* The `ExternalIsa` [[`QueryEvent`]] is how Polar determines whether a given
* value is an instance of a particular class.
*
* @internal
*/
export interface ExternalIsa {

@@ -88,2 +237,9 @@ instance: PolarTerm;

}
/**
* The `ExternalUnify` [[`QueryEvent`]] is how Polar determines whether a pair
* of values unify where at least one of the values is an application instance
* (and, as such, Polar cannot determine unification internally).
*
* @internal
*/
export interface ExternalUnify {

@@ -94,5 +250,16 @@ leftId: number;

}
/**
* The `Debug` [[`QueryEvent`]] is how Polar relays debugging messages to
* JavaScript from the internal debugger attached to the Polar VM.
*
* @internal
*/
export interface Debug {
message: string;
}
/**
* Union of all [[`QueryEvent`]] types.
*
* @internal
*/
export declare enum QueryEventKind {

@@ -108,2 +275,7 @@ Debug = 0,

}
/**
* An event from the Polar VM.
*
* @internal
*/
export interface QueryEvent {

@@ -113,6 +285,52 @@ kind: QueryEventKind;

}
export declare type QueryResult = Generator<Map<string, any>, void, never>;
/**
* An `AsyncGenerator` over query results.
*
* Each result is a `Map` of variables bound during the computation of that
* result.
*
* If you don't need access to the bindings and only wish to know whether a
* query succeeded or failed, you may check the `done` property of the yielded
* value (and then optionally "complete" the generator by calling its
* `return()` method). If `done` is `true`, the query failed. If `done` is
* `false`, the query yielded at least one result and therefore succeeded.
*/
export declare type QueryResult = AsyncGenerator<Map<string, any>, void, undefined | void>;
/**
* An object with string keys.
*
* @hidden
*/
export declare type obj = {
[key: string]: any;
};
/**
* A function that compares two values and returns `true` if they are equal and
* `false` otherwise.
*
* A custom `EqualityFn` may be passed in the [[`Options`]] provided to the
* [[`Oso.constructor`]] in order to override the default equality function,
* which uses `==` (loose equality).
*/
export declare type EqualityFn = (x: any, y: any) => boolean;
/**
* Optional configuration for the [[`Oso.constructor`]].
*/
export interface Options {
equalityFn?: EqualityFn;
}
/**
* Type guard to test if a value conforms to both the iterable and iterator
* protocols. This is basically a slightly relaxed check for whether the value
* is a `Generator`.
*
* @internal
*/
export declare function isIterableIterator(x: any): boolean;
/**
* Type guard to test if a value is an `AsyncIterator`.
*
* @internal
*/
export declare function isAsyncIterator(x: any): boolean;
export {};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.QueryEventKind = exports.isGeneratorFunction = exports.isGenerator = exports.isPolarTerm = exports.isPolarVariable = exports.isPolarPredicate = exports.isPolarInstance = exports.isPolarDict = exports.isPolarList = exports.isPolarBool = exports.isPolarNum = exports.isPolarStr = void 0;
exports.isAsyncIterator = exports.isIterableIterator = exports.QueryEventKind = exports.isPolarTerm = exports.isPolarInstance = exports.isPolarVariable = exports.isPolarPredicate = exports.isPolarDict = exports.isPolarList = exports.isPolarBool = exports.isPolarNum = exports.isPolarStr = void 0;
/**
* Type guard to test if a Polar value received from across the WebAssembly
* boundary is a Polar string.
*
* @internal
*/
function isPolarStr(v) {

@@ -8,2 +14,8 @@ return v.String !== undefined;

exports.isPolarStr = isPolarStr;
/**
* Type guard to test if a Polar value received from across the WebAssembly
* boundary is a Polar numeric.
*
* @internal
*/
function isPolarNum(v) {

@@ -13,2 +25,8 @@ return v.Number !== undefined;

exports.isPolarNum = isPolarNum;
/**
* Type guard to test if a Polar value received from across the WebAssembly
* boundary is a Polar boolean.
*
* @internal
*/
function isPolarBool(v) {

@@ -18,2 +36,8 @@ return v.Boolean !== undefined;

exports.isPolarBool = isPolarBool;
/**
* Type guard to test if a Polar value received from across the WebAssembly
* boundary is a Polar list.
*
* @internal
*/
function isPolarList(v) {

@@ -23,2 +47,8 @@ return v.List !== undefined;

exports.isPolarList = isPolarList;
/**
* Type guard to test if a Polar value received from across the WebAssembly
* boundary is a Polar dictionary.
*
* @internal
*/
function isPolarDict(v) {

@@ -28,6 +58,8 @@ return v.Dictionary !== undefined;

exports.isPolarDict = isPolarDict;
function isPolarInstance(v) {
return v.ExternalInstance !== undefined;
}
exports.isPolarInstance = isPolarInstance;
/**
* Type guard to test if a Polar value received from across the WebAssembly
* boundary is a Polar predicate.
*
* @internal
*/
function isPolarPredicate(v) {

@@ -37,2 +69,8 @@ return v.Call !== undefined;

exports.isPolarPredicate = isPolarPredicate;
/**
* Type guard to test if a Polar value received from across the WebAssembly
* boundary is a Polar variable.
*
* @internal
*/
function isPolarVariable(v) {

@@ -42,3 +80,21 @@ return v.Variable !== undefined;

exports.isPolarVariable = isPolarVariable;
function isPolarType(v) {
/**
* Type guard to test if a Polar value received from across the WebAssembly
* boundary is a Polar application instance.
*
* @internal
*/
function isPolarInstance(v) {
return v.ExternalInstance !== undefined;
}
exports.isPolarInstance = isPolarInstance;
/**
* Type guard to test if a JSON payload received from across the WebAssembly
* boundary contains a valid Polar value.
*
* @internal
*/
function isPolarValue(v) {
if (typeof v !== 'object' || v === null)
return false;
return (isPolarStr(v) ||

@@ -53,17 +109,17 @@ isPolarNum(v) ||

}
/**
* Type guard to test if a JSON payload received from across the WebAssembly
* boundary contains a valid Polar term.
*
* @internal
*/
function isPolarTerm(v) {
return isPolarType(v === null || v === void 0 ? void 0 : v.value);
return isPolarValue(v === null || v === void 0 ? void 0 : v.value);
}
exports.isPolarTerm = isPolarTerm;
function isGenerator(x) {
return [x.next, x.return, x.throw].every(f => typeof f === 'function');
}
exports.isGenerator = isGenerator;
function isGeneratorFunction(x) {
if (!x.constructor)
return false;
return (x.constructor.name === 'GeneratorFunction' ||
isGenerator(x.constructor.prototype));
}
exports.isGeneratorFunction = isGeneratorFunction;
/**
* Union of all [[`QueryEvent`]] types.
*
* @internal
*/
var QueryEventKind;

@@ -80,2 +136,22 @@ (function (QueryEventKind) {

})(QueryEventKind = exports.QueryEventKind || (exports.QueryEventKind = {}));
/**
* Type guard to test if a value conforms to both the iterable and iterator
* protocols. This is basically a slightly relaxed check for whether the value
* is a `Generator`.
*
* @internal
*/
function isIterableIterator(x) {
return typeof (x === null || x === void 0 ? void 0 : x.next) === 'function' && Symbol.iterator in Object(x);
}
exports.isIterableIterator = isIterableIterator;
/**
* Type guard to test if a value is an `AsyncIterator`.
*
* @internal
*/
function isAsyncIterator(x) {
return Symbol.asyncIterator in Object(x);
}
exports.isAsyncIterator = isAsyncIterator;
//# sourceMappingURL=types.js.map

@@ -0,1 +1,2 @@

/** Polar variable. */
export declare class Variable {

@@ -2,0 +3,0 @@ readonly name: string;

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Variable = void 0;
/** Polar variable. */
class Variable {

@@ -5,0 +6,0 @@ constructor(name) {

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const path_1 = __importDefault(require("path"));
const Oso_1 = require("../src/Oso");

@@ -33,66 +29,89 @@ const oso = new Oso_1.Oso();

oso.registerClass(B.C, 'C');
// This path has the same nesting for development and the parity test jobs by sheer coincidence.
// In tests it's `languages/js/test/parity.ts`
// In parity tests it's `js_package/dist/test/parity.js`
// In both these cases the relative path to the test.polar file is the same.
oso.loadFile(path_1.default.resolve(__dirname, '../../../test/test.polar'));
if (!oso.isAllowed('a', 'b', 'c'))
throw new Error();
// Test that a built in string method can be called.
oso.loadStr('?= x = "hello world!" and x.endsWith("world!");');
// Test that a custom error type is thrown.
let exceptionThrown = false;
try {
oso.loadStr('missingSemicolon()');
class E {
static sum(args) {
return args.reduce((a, b) => {
return a + b;
}, 0);
}
}
catch (e) {
const expectedName = 'ParseError::UnrecognizedEOF';
const expectedMessage = 'hit the end of the file unexpectedly. Did you forget a semi-colon at line 1, column 19';
if (e.name === expectedName && e.message === expectedMessage)
exceptionThrown = true;
}
finally {
if (!exceptionThrown)
oso.registerClass(E);
(async function () {
// This path has the same nesting for development and the parity test jobs by sheer coincidence.
// In tests it's `languages/js/test/parity.ts`
// In parity tests it's `js_package/dist/test/parity.js`
// In both these cases the relative path to the test.polar file is the same.
await oso.loadFile('../../../test/test.polar');
if (!(await oso.isAllowed('a', 'b', 'c')))
throw new Error();
}
if ([
oso.queryRule('specializers', new D('hello'), new B.C('hello')).next().done,
oso.queryRule('floatLists').next().done,
oso.queryRule('intDicts').next().done,
oso.queryRule('comparisons').next().done,
oso.queryRule('testForall').next().done,
oso.queryRule('testRest').next().done,
oso.queryRule('testMatches', new A('hello')).next().done,
oso.queryRule('testMethodCalls', new A('hello'), new B.C('hello')).next()
.done,
oso.queryRule('testOr').next().done,
].some(v => v))
throw new Error();
// Test that cut doesn't return anything.
if (!oso.queryRule('testCut').next().done)
throw new Error();
// Test that a constant can be called.
oso.registerConstant('Math', Math);
oso.loadStr('?= Math.acos(1.0) = 0;');
// Test built-in type specializers.
if ([
oso.query('builtinSpecializers(true, "Boolean")').next().done,
!oso.query('builtinSpecializers(false, "Boolean")').next().done,
oso.query('builtinSpecializers(2, "Integer")').next().done,
oso.query('builtinSpecializers(1, "Integer")').next().done,
!oso.query('builtinSpecializers(0, "Integer")').next().done,
!oso.query('builtinSpecializers(-1, "Integer")').next().done,
oso.query('builtinSpecializers(1.0, "Float")').next().done,
!oso.query('builtinSpecializers(0.0, "Float")').next().done,
!oso.query('builtinSpecializers(-1.0, "Float")').next().done,
oso.query('builtinSpecializers(["foo", "bar", "baz"], "List")').next().done,
!oso.query('builtinSpecializers(["bar", "foo", "baz"], "List")').next()
.done,
oso.query('builtinSpecializers({foo: "foo"}, "Dictionary")').next().done,
!oso.query('builtinSpecializers({foo: "bar"}, "Dictionary")').next().done,
oso.query('builtinSpecializers("foo", "String")').next().done,
!oso.query('builtinSpecializers("bar", "String")').next().done,
].some(v => v))
throw new Error();
console.log('tests pass');
// Test that a built in string method can be called.
await oso.loadStr('?= x = "hello world!" and x.endsWith("world!");');
// Test that a custom error type is thrown.
let exceptionThrown = false;
try {
await oso.loadStr('missingSemicolon()');
}
catch (e) {
const expectedName = 'ParseError::UnrecognizedEOF';
const expectedMessage = 'hit the end of the file unexpectedly. Did you forget a semi-colon at line 1, column 19';
if (e.name === expectedName && e.message === expectedMessage)
exceptionThrown = true;
}
finally {
if (!exceptionThrown)
throw new Error();
}
if ([
(await oso
.queryRule('specializers', new D('hello'), new B.C('hello'))
.next()).done,
(await oso.queryRule('floatLists').next()).done,
(await oso.queryRule('intDicts').next()).done,
(await oso.queryRule('comparisons').next()).done,
(await oso.queryRule('testForall').next()).done,
(await oso.queryRule('testRest').next()).done,
(await oso.queryRule('testMatches', new A('hello')).next()).done,
(await oso
.queryRule('testMethodCalls', new A('hello'), new B.C('hello'))
.next()).done,
(await oso.queryRule('testOr').next()).done,
(await oso.queryRule('testUnifyClass', E).next()).done,
].some(v => v))
throw new Error();
// Test that cut doesn't return anything.
if (!(await oso.queryRule('testCut').next()).done)
throw new Error();
// Test that a constant can be called.
oso.registerConstant('Math', Math);
await oso.loadStr('?= Math.acos(1.0) = 0;');
// Test built-in type specializers.
if ([
(await oso.query('builtinSpecializers(true, "Boolean")').next()).done,
!(await oso.query('builtinSpecializers(false, "Boolean")').next()).done,
(await oso.query('builtinSpecializers(2, "Integer")').next()).done,
(await oso.query('builtinSpecializers(1, "Integer")').next()).done,
!(await oso.query('builtinSpecializers(0, "Integer")').next()).done,
!(await oso.query('builtinSpecializers(-1, "Integer")').next()).done,
(await oso.query('builtinSpecializers(1.0, "Float")').next()).done,
!(await oso.query('builtinSpecializers(0.0, "Float")').next()).done,
!(await oso.query('builtinSpecializers(-1.0, "Float")').next()).done,
(await oso
.query('builtinSpecializers(["foo", "bar", "baz"], "List")')
.next()).done,
!(await oso
.query('builtinSpecializers(["bar", "foo", "baz"], "List")')
.next()).done,
(await oso
.query('builtinSpecializers({foo: "foo"}, "Dictionary")')
.next()).done,
!(await oso
.query('builtinSpecializers({foo: "bar"}, "Dictionary")')
.next()).done,
(await oso.query('builtinSpecializers("foo", "String")').next()).done,
!(await oso.query('builtinSpecializers("bar", "String")').next()).done,
].some(v => v))
throw new Error();
// Test deref behaviour
await oso.loadStr('?= x = 1 and E.sum([x, 2, x]) = 4 and [3, 2, x].indexOf(1) = 2;');
console.log('tests pass');
})();
//# sourceMappingURL=parity.js.map
{
"name": "oso",
"version": "0.4.1-rc3",
"description": "Oso authorization library.",
"version": "0.5.0",
"description": "oso authorization library.",
"main": "dist/src/index.js",
"bin": "bin/repl.js",
"repository": "https://github.com/osohq/oso",

@@ -13,6 +14,7 @@ "collaborators": [

"files": [
"dist"
"dist",
"bin"
],
"engines": {
"node": ">=10.13.0",
"node": ">=10",
"npm": ">=6.4.1"

@@ -24,4 +26,8 @@ },

"fix": "gts fix",
"fmt": "prettier --write 'src/**/*.ts' 'test/**/*.ts'",
"fmtcheck": "prettier --check 'src/**/*.[jt]s'",
"test": "jest"
"test": "jest",
"docs-build": "typedoc --options typedoc.js",
"docs-watch": "chokidar 'src/**/*.ts' -c 'yarn docs-build'",
"docs-serve": "live-server docs"
},

@@ -32,13 +38,15 @@ "devDependencies": {

"@types/node": "^14.0.14",
"chokidar-cli": "^2.1.0",
"gts": "^2.0.2",
"jest": "^26.3.0",
"live-server": "^1.2.1",
"prettier": "^2.0.5",
"rimraf": "^3.0.2",
"temp-write": "^4.0.0",
"ts-jest": "^26.2.0",
"ts-node": "^8.10.2",
"typedoc": "^0.17.0-3",
"typescript": "^3.9.5"
},
"dependencies": {
"lodash": "^4.17.19"
}
"dependencies": {}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc