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

@journeyapps/db

Package Overview
Dependencies
Maintainers
2
Versions
308
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@journeyapps/db - npm Package Compare versions

Comparing version 0.0.0-dev.61472d2.0a3ef77 to 0.0.0-dev.62eaa55.99ffd7e

dist/@types/src/browser.d.ts

1

dist/@types/src/Attachment.d.ts
/// <reference types="node" />
import 'isomorphic-fetch';
export declare class Attachment {
static isAttachment(attachment: unknown): attachment is Attachment;
id: string;

@@ -5,0 +6,0 @@ state: string;

39

dist/@types/src/BaseAdapter.d.ts

@@ -1,13 +0,3 @@

import { Schema } from '@journeyapps/parser-schema';
import { Query } from './Query';
export interface ObjectData {
id: string;
type: string;
attributes: {
[index: string]: any;
};
belongs_to: {
[index: string]: string;
};
}
import { ObjectData } from './ObjectData';
export declare abstract class BaseAdapter {

@@ -43,2 +33,3 @@ static logQuery(...args: any[]): any;

getAll(type: string, ids: string[]): Promise<ObjectData[]>;
count(query: Query): Promise<number>;
/**

@@ -52,29 +43,3 @@ * Destroy an object.

ensureOpen(): void;
updateSchemaIndexes(schema: Schema): Promise<void>;
dataChanged(): void;
getCrudBatch(limit?: number): Promise<{
crud: any[];
transaction: any;
}>;
crudComplete(transaction: any): Promise<any>;
calculateHash(start: string, end: string): Promise<any>;
clearRange(start: string, end: string, skip: any[]): Promise<any>;
clearLocal(): Promise<any>;
getLastUpdateId(): Promise<string>;
/**
* Range start and end must be defined (no open-ended ranges).
*
* Returns a list of start update id's for the ranges. Each range is closed by the next range's start UID,
* and the last range is closed by the end parameter (not included in the results).
*
* This first number in the returned list will be the provided start value.
*
* The return list will have a minimum length of 1, and a maximum length of `split`.
*
* This function will attempt to split the range into `split` subranges, but with no subrange having
* less than `minimum` objects, and each subrange having approximately the same number of objects.
*/
splitRange(start: string, end: string, split: number, minimum: number): Promise<string[]>;
explain(query: Query): Promise<any>;
uidAtOffsets(start: string, end: string, offsets: number[]): Promise<string[]>;
abstract getData(type: string, id: string): Promise<ObjectData>;

@@ -81,0 +46,0 @@ abstract applyBatch(ops: any[]): Promise<any[]>;

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

import { DatabaseObject, DatabaseAdapter, Database } from './database';
import { DatabaseObject } from './DatabaseObject';
import { DatabaseAdapter } from './DatabaseAdapter';
import { Database } from './Database';
export interface BatchError {

@@ -17,2 +19,5 @@ object: DatabaseObject;

}
export interface ExecuteBatchResult {
error?: any;
}
export declare class Batch {

@@ -46,5 +51,4 @@ /**

}
export declare class CrudError {
export declare class CrudError extends Error {
errors: BatchError[];
message: string;
constructor(errors: BatchError[]);

@@ -54,3 +58,5 @@ /**

*/
firstError: () => any;
firstError(): {
detail: string;
};
}
import { DatabaseObject } from './DatabaseObject';
import { ObjectType } from '@journeyapps/parser-schema';
import { DatabaseAdapter } from './database';
import { DatabaseAdapter } from './DatabaseAdapter';
import { Query } from './Query';

@@ -84,1 +84,2 @@ export declare class Collection<T extends DatabaseObject = DatabaseObject> {

}
export declare type TypedCollection<T> = Collection<DatabaseObject & T>;
import { ObjectType } from '@journeyapps/parser-schema';
import { DatabaseAdapter } from './database';
export interface GenericObject {
[key: string]: any;
}
import { DatabaseAdapter } from './DatabaseAdapter';
export declare class DatabaseObject {

@@ -39,1 +36,4 @@ /**

}
export declare type CreateAccessor = (name: string, set: (name: string, value: any) => void, get: (name: string) => any) => void;
export declare var createAccessor: CreateAccessor;
export declare function setCreateAccessor(fn: CreateAccessor): void;

@@ -1,29 +0,3 @@

import * as database from './database';
import * as evaluator from './evaluator';
import * as primitives from './primitives';
import * as query from './queryOperations';
import * as serializeInternal from './serializeInternal';
export { Day } from '@journeyapps/core-date';
/**
* @deprecated
*/
export { database, evaluator, primitives, query, serializeInternal };
export * from './credentials/ApiCredentials';
export * from './credentials/MobileCredentials';
export * from './Attachment';
export * from './BaseAdapter';
export * from './Batch';
export * from './Collection';
export * from './DatabaseObject';
export * from './DatabaseSet';
export * from './IndexedAdapter';
export * from './JourneyAPIAdapter';
export * from './Location';
export * from './ObjectRef';
export * from './browser';
export * from './OnlineDB';
export * from './Query';
export * from './WebSQLAdapter';
export * from './utils/base64';
export * from './utils/FunctionQueue';
export * from './utils/uuid';
export * from './database';
import './primitives';
import 'isomorphic-fetch';
import { BaseAdapter, ObjectData } from './BaseAdapter';
import { BaseAdapter } from './BaseAdapter';
import { Schema, ObjectType } from '@journeyapps/parser-schema';
import { Query } from './Query';
import { ExecuteBatchOperation } from './Batch';
import { ObjectData } from './ObjectData';
export interface ApiObjectData extends ObjectData {

@@ -7,0 +8,0 @@ _updated_at?: string;

import { ApiCredentialOptions } from './credentials/ApiCredentials';
import { Database } from './database';
import { Database } from './Database';
export interface OnlineDBCredentials extends ApiCredentialOptions {

@@ -4,0 +4,0 @@ adapter?: any;

@@ -1,14 +0,15 @@

import { DatabaseAdapter } from './database';
import { DatabaseAdapter } from './DatabaseAdapter';
import { ObjectType } from '@journeyapps/parser-schema';
import { Expression } from './queryOperations';
import { DatabaseObject } from './DatabaseObject';
import { FormatString } from '@journeyapps/evaluator';
interface RelationshipHash {
[key: string]: RelationshipHash;
}
export declare class Query<T extends DatabaseObject = DatabaseObject> {
static fromJSON(value: any, dbset: any): Query<DatabaseObject>;
readonly type: ObjectType;
private _freshness;
private _include;
constructor(adapter: DatabaseAdapter, type: ObjectType, expression?: Expression, ordering?: any[]);
private _reload;
private _explain;
private _fetchWithDisplay;
_fetchWithDisplay(columns?: FormatString[] | Record<string, FormatString>): Promise<T[]>;
/**

@@ -63,13 +64,2 @@ * Apply additional query filters, as a new query.

private _count;
toJSON(): {
$query: {
type: string;
database: string;
limit: number;
expression: any;
ordering: any[];
skip: number;
_freshness: number;
};
};
/**

@@ -130,3 +120,17 @@ * Execute the query and return the results.

orderBy(...fields: string[]): Query<T>;
/**
* For debugging purposes only.
*
* The format of the result is not defined.
*/
toJSON(): {
type: string;
expression: Expression;
ordering: any[];
limit: number;
skip: number;
include: RelationshipHash;
};
private _includeInternal;
}
export {};

@@ -1,10 +0,8 @@

import { Type, Variable } from '@journeyapps/parser-schema';
import { ObjectData } from './BaseAdapter';
export declare function expressionFromJSON(scopeType: Type, json: any): Expression;
export declare function expressionFromHash(scopeType: Type, hash: any): AndExpression;
import { Variable, Type } from '@journeyapps/parser-schema';
import { ObjectData } from './ObjectData';
export declare function expressionFromHash(scopeType: Type, hash: any): Expression;
export interface Expression {
normalize(): OrExpression<AndExpression>;
normalize(): NormalizedExpression;
evaluate(object: ObjectData): boolean;
toOriginalExpression(): any[];
toJSON(): any;
}

@@ -19,8 +17,2 @@ export declare class Operation implements Expression {

evaluate(object: ObjectData): boolean;
toJSON(): {
__type: string;
attribute: string;
operator: string;
value: any;
};
toString(): string;

@@ -35,7 +27,2 @@ toOriginalExpression(): any[];

evaluate(object: ObjectData): boolean;
toJSON(): {
__type: string;
name: string;
id: string;
};
toString(): string;

@@ -48,8 +35,4 @@ toOriginalExpression(): string[];

join(otherAnd: AndExpression): AndExpression;
normalize(): OrExpression<AndExpression>;
normalize(): any;
evaluate(object: ObjectData): boolean;
toJSON(): {
__type: string;
operands: any[];
};
toString(): string;

@@ -63,25 +46,21 @@ toOriginalExpression(): any;

evaluate(object: ObjectData): boolean;
toJSON(): {
__type: string;
operands: any[];
};
toString(): string;
toOriginalExpression(): any;
}
export declare type NormalizedExpression = OrExpression<AndExpression>;
export declare class TrueExpression implements Expression {
normalize(): OrExpression<AndExpression>;
constructor();
normalize(): any;
evaluate(object: ObjectData): boolean;
toString(): string;
toOriginalExpression(): string[];
toJSON(): {
__type: string;
};
}
export declare class Tokenizer {
expression: string;
i: number;
previousPosition: number;
private interpolatorCount;
private expression;
constructor(expression: string);
exception(message: string, start?: number, end?: number): Error;
isWordSeparator(p: number): boolean;
isWord(): boolean;

@@ -95,8 +74,5 @@ hasMore(): boolean;

readParenthesis(): string;
readInterpolator(): number;
readWord(): string;
readInterpolator(): number;
private advance;
private isWordSeparator;
private isLetter;
private isDigit;
private checkBuffer;

@@ -107,5 +83,5 @@ private readToken;

export declare class Parser {
tokenizer: Tokenizer;
scopeType: Type;
args: any[];
private scopeType;
private tokenizer;
private args;
constructor(scopeType: Type, tokenizer: Tokenizer, args: any[]);

@@ -112,0 +88,0 @@ parse(): Expression;

@@ -1,7 +0,12 @@

import { IndexSet } from './indexing/IndexSet';
import { IndexedAdapter, ExplainedResult } from './IndexedAdapter';
import { ObjectData } from './BaseAdapter';
import { IndexRange } from './indexing/IndexRange';
import { BaseAdapter } from './BaseAdapter';
import { Query } from './Query';
export declare class WebSQLAdapter extends IndexedAdapter {
import { ObjectData } from './ObjectData';
export interface ExplainedResult {
type: 'index' | 'full scan';
results: number;
scanned: number;
data: ObjectData[];
duration?: number;
}
export declare class WebSQLAdapter extends BaseAdapter {
static adapterName: string;

@@ -16,9 +21,2 @@ static supportsDiagnostics: boolean;

description(): string;
/**
* Update the indexes to the specified set.
* This runs in an exclusive lock, blocking all other database writes and all queries.
* This operation is idempotent, and should be fast if all the indexes
* are already up to date.
*/
updateIndexes(indexes: IndexSet): Promise<any>;
applyCrud(crud: any[]): Promise<{

@@ -34,3 +32,4 @@ updatedIds: string[];

applyBatch(crud: any[]): Promise<any[]>;
saveData(data: ObjectData, patch: ObjectData, syncInfo?: any): Promise<void>;
save(data: ObjectData, patch: ObjectData): Promise<any>;
saveData(data: ObjectData, patch?: ObjectData): Promise<void>;
/**

@@ -41,35 +40,13 @@ * Destroy an object.

*/
destroy(type: string, id: string, remoteChange?: boolean): Promise<void>;
destroy(type: string, id: string): Promise<void>;
/**
* Perform a query.
* Returns a promise that is resolved with the resultset.
*/
executeQuery(query: Query): Promise<ObjectData[]>;
explain(query: Query): Promise<ExplainedResult>;
executeTableScan(query: Query): Promise<ExplainedResult>;
getData(type: string, id: string): Promise<ObjectData>;
getAll(type: string, ids: string[]): Promise<ObjectData[]>;
getByIndex(range: IndexRange): Promise<ObjectData[]>;
getByIndexes(typeName: string, ranges: IndexRange[]): Promise<ObjectData[]>;
/**
* Get a batch of objects to send to the server.
* When the objects are successfully sent to the server, call crudComplete(t).
* Returns a promise resolving with: {crud: [], transaction: t}
*/
getCrudBatch(limit?: number): Promise<{
crud: any[];
transaction: any;
}>;
crudComplete(transaction: any): Promise<void>;
/**
* Delete all objects in the specified range, excluding those listed in the `skip` array (optional).
*/
clearRange(start: string, end: string, skip: string[]): Promise<void>;
clearLocal(): Promise<boolean>;
/**
* Sum the hashes of all objects in the specified range.
* */
calculateHash(start: string, end: string): Promise<{
hash: any;
count: any;
}>;
getLastUpdateId(): Promise<string>;
uidAtOffset(start: string, end: string, offset: number): Promise<any>;
uidAtOffsets(start: string, end: string, offsets: number[]): Promise<any[]>;
estimateBytesUsed(): Promise<number>;
estimateQueueBytesUsed(): Promise<number>;
openDatabase(name: string): any;

@@ -80,5 +57,3 @@ private promisedTransaction;

private transactionDestroy;
private _updateItemIndexes;
private _updateIndexData;
private logError;
}
import '@journeyapps/core-test-helpers';
import './CrudBatchSpec';
import './DatabaseAdapterSpec';

@@ -7,2 +6,1 @@ import './DatabaseSpec';

import './FunctionQueueSpec';
import './IndexKeySpec';

@@ -9,2 +9,11 @@ "use strict";

class Attachment {
static isAttachment(attachment) {
if (attachment instanceof Attachment) {
return true;
}
else if (typeof attachment.id == 'string' && typeof attachment.present == 'function') {
return true;
}
return false;
}
constructor(attrs) {

@@ -11,0 +20,0 @@ attrs = attrs || {};

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

}
async count(query) {
const data = await this.executeQuery(query);
return data.length;
}
/**

@@ -82,3 +86,2 @@ * Destroy an object.

destroy(type, id, dontLogCrud) {
this.dataChanged();
return Promise.resolve();

@@ -94,87 +97,7 @@ }

}
// --- Indexing functionality ---
updateSchemaIndexes(schema) {
// no-op
return Promise.resolve();
}
// --- Sync functionality ---
dataChanged() {
// Called when data has been saved, to trigger sync.
// Replace this function with one that can handle the change.
}
getCrudBatch(limit) {
// It is up to implementations to override this to implement crud tracking.
// With the default behaviour all tests should pass, but no crud is done.
return Promise.resolve(null);
}
crudComplete(transaction) {
return Promise.resolve(null);
}
// Sum the hashes of all objects in the specified range.
// Both start and end are required.
calculateHash(start, end) {
return Promise.reject('Not implemented');
}
// Delete all objects in the specified range, excluding those listed in the `skip` array (optional).
clearRange(start, end, skip) {
return Promise.resolve(null);
}
// Delete all objects without an uid.
clearLocal() {
return Promise.resolve(null);
}
// Return the highest update id in the database, as a promise.
getLastUpdateId() {
return Promise.reject('Not implemented');
}
/**
* Range start and end must be defined (no open-ended ranges).
*
* Returns a list of start update id's for the ranges. Each range is closed by the next range's start UID,
* and the last range is closed by the end parameter (not included in the results).
*
* This first number in the returned list will be the provided start value.
*
* The return list will have a minimum length of 1, and a maximum length of `split`.
*
* This function will attempt to split the range into `split` subranges, but with no subrange having
* less than `minimum` objects, and each subrange having approximately the same number of objects.
*/
splitRange(start, end, split, minimum) {
this.ensureOpen();
var self = this;
start = start || '';
return this.calculateHash(start, end).then(function (result) {
// We're not interested in the hash, only the count
var count = result.count;
var sectionSize = Math.max(Math.ceil(count / split), minimum);
var numberOfSections = count / sectionSize; // number <= split
var offsets = [];
// We don't include the offset of 0 - we use `start` for this, so that the entire range is covered
for (var i = 1; i < numberOfSections; i++) {
offsets[i - 1] = i * sectionSize;
}
return self.uidAtOffsets(start, end, offsets).then(function (uids) {
// We need to filter, in case the data has been modified since
var filtered = [start];
var last = '';
for (var index = 0; index < uids.length; index++) {
// Check that it is non-null, and strictly increasing
if (uids[index] != null && uids[index] > last) {
filtered.push(uids[index]);
last = uids[index];
}
}
return filtered;
});
});
}
explain(query) {
throw new Error('Method not implemented.');
}
uidAtOffsets(start, end, offsets) {
throw new Error('Method not implemented.');
}
}
exports.BaseAdapter = BaseAdapter;
//# sourceMappingURL=BaseAdapter.js.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function validateAdapter(batchAdapter, object) {
if (object._adapter === batchAdapter || object._adapter.name == batchAdapter.name) {
return;
}
throw new Error('Cannot add an object in ' + object._adapter.description() + ' to a Batch in ' + batchAdapter.description());
}
class Batch {

@@ -25,5 +31,3 @@ /**

save(object) {
if (object._adapter !== this.adapter) {
throw new Error('Batch cannot save an object from a different database');
}
validateAdapter(this.adapter, object);
this._operations.push({ op: 'save', object: object });

@@ -35,5 +39,3 @@ }

destroy(object) {
if (object._adapter !== this.adapter) {
throw new Error('Batch cannot save an object from a different database');
}
validateAdapter(this.adapter, object);
this._operations.push({ op: 'destroy', object: object });

@@ -49,2 +51,8 @@ }

execute() {
return this._execute();
}
/**
* @internal
*/
_execute() {
const ops = this._getOps();

@@ -165,4 +173,3 @@ if (ops.length == 0) {

if (op.op == 'patch') {
if (Object.keys(op.patch.attributes).length === 0 &&
Object.keys(op.patch.belongs_to).length === 0) {
if (Object.keys(op.patch.attributes).length === 0 && Object.keys(op.patch.belongs_to).length === 0) {
// No-op

@@ -178,25 +185,20 @@ continue;

exports.Batch = Batch;
class CrudError {
class CrudError extends Error {
constructor(errors) {
/**
* Return the first error. Useful if this was used for a single operation.
*/
this.firstError = function () {
return this.errors[0].error;
};
super();
this.errors = errors;
let message = 'Crud operations failed.';
errors.forEach(function (error) {
message +=
'\n ' +
error.object.type.name +
' ' +
error.object.id +
': ' +
error.error.detail;
message += '\n ' + error.object.type.name + ' ' + error.object.id + ': ' + error.error.detail;
});
this.message = message;
}
/**
* Return the first error. Useful if this was used for a single operation.
*/
firstError() {
return this.errors[0].error;
}
}
exports.CrudError = CrudError;
//# sourceMappingURL=Batch.js.map

@@ -28,3 +28,3 @@ "use strict";

create(attributes) {
var object = DatabaseObject_1.DatabaseObject.build(this.adapter, this.type);
let object = DatabaseObject_1.DatabaseObject.build(this.adapter, this.type);
object.setAll(attributes);

@@ -39,15 +39,21 @@ return object;

// TODO: varargs
var self = this;
if (arguments.length == 1 && typeof arguments[0] == 'string') {
// Find by ID - return a placeholder
var promise = this.adapter.get(this.type.name, id);
return promise.then(function (data) {
const promise = this.adapter.get(this.type.name, id);
return promise.then(data => {
if (data == null) {
if (this.adapter.logWarnings) {
console.warn('Could not find ' + this.type.name + ' with ' + id);
}
return null;
}
else {
return DatabaseObject_1.DatabaseObject.build(self.adapter, self.type, id, data);
return DatabaseObject_1.DatabaseObject.build(this.adapter, this.type, id, data);
}
});
}
else if (arguments.length == 1 && arguments[0] == null) {
// This can happen when passing in null/undefined as an ID.
return Promise.reject('Query expression or ID required');
}
else {

@@ -54,0 +60,0 @@ // Same as a where query, but only return a single result.

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const parser_schema_1 = require("@journeyapps/parser-schema");
const database_1 = require("./database");
const Query_1 = require("./Query");
const Batch_1 = require("./Batch");
const queryOperations_1 = require("./queryOperations");
const uuid = require("uuid/v1");
const uuid = require("uuid/v4");
const evaluator_1 = require("@journeyapps/evaluator");
// type is the type object, not the name

@@ -20,3 +21,3 @@ class DatabaseObject {

constructor(adapter, type, id) {
if (adapter == null || typeof adapter.save != 'function') {
if (adapter == null || typeof adapter.getData != 'function') {
throw new Error('adapter is required');

@@ -27,9 +28,9 @@ }

}
var objself = this;
const objself = this;
// This is where all the attributes are stored
var attributes = {};
const attributes = {};
// Attributes that have been set by the user.
var attributesDirty = {};
let attributesDirty = {};
// belongsToIds is only used when there is no corresponding object in belongsToCache.
var belongsToIds = {};
const belongsToIds = {};
// belongsToCache serves as a cache for relationships. The id in belongsToIds should always correspond to

@@ -39,13 +40,13 @@ // the id here, if the object is present.

// means that we haven't queried yet.
var belongsToCache = {};
let belongsToCache = {};
// Relationships that have been set by the user.
// true means set by user, false or not present means not set
var belongsToDirty = {};
let belongsToDirty = {};
// We keep track of what we are currently loading, so that we don't execute the same query many times
// in succession.
var belongsToLoading = {};
const belongsToLoading = {};
// Caching the queries prevents them from being re-executed all the time.
var hasManyCache = {};
var persisted;
var destroyed = false;
let hasManyCache = {};
let persisted;
let destroyed = false;
if (id == null) {

@@ -91,9 +92,9 @@ // New object

if (data != null) {
var resolveAttributes = data.attributes || {};
const resolveAttributes = data.attributes || {};
Object.keys(type.attributes).forEach(function (key) {
var attribute = type.attributes[key];
var value = resolveAttributes[key];
const attribute = type.attributes[key];
const value = resolveAttributes[key];
// We don't override any attributes that have already been set.
if (!attributesDirty[key]) {
var realValue = value == null ? null : attribute.type.valueFromJSON(value);
const realValue = value == null ? null : attribute.type.valueFromJSON(value);
// We use the setter so that type checking occurs...

@@ -135,3 +136,3 @@ try {

if (values != null) {
for (var key in values) {
for (let key in values) {
if (values.hasOwnProperty(key)) {

@@ -143,3 +144,3 @@ _set(key, values[key]);

}
var saving = false;
let saving = false;
// Returns a promise that is resolved when this object is saved.

@@ -154,5 +155,5 @@ function _save() {

// belongs-to relationships.
var batch = new Batch_1.Batch(adapter);
let batch = new Batch_1.Batch(adapter);
batch.save(this);
return batch.execute().catch(function (error) {
return batch._execute().catch(function (error) {
if (error instanceof Batch_1.CrudError) {

@@ -203,3 +204,3 @@ return Promise.reject(error.firstError());

Object.keys(belongsToCache).forEach(function (key) {
var related = belongsToCache[key];
const related = belongsToCache[key];
if (related != null) {

@@ -238,7 +239,7 @@ if (related._adapter === adapter) {

var displayFormat = type.displayFormat;
return displayFormat.evaluate(objself);
return displayFormat.evaluate(new evaluator_1.VariableFormatStringScope(objself));
}
function toData(patch) {
// We don't modify belongToIds here - this must be a read-only method.
var jsonBelongsTo = {};
let jsonBelongsTo = {};
Object.keys(type.belongsTo).forEach(function (name) {

@@ -257,6 +258,6 @@ let belongsToId = belongsToIds[name];

});
var jsonAttributes = {};
let jsonAttributes = {};
Object.keys(type.attributes).forEach(function (name) {
var attribute = type.attributes[name];
var value = attributes[name];
const attribute = type.attributes[name];
const value = attributes[name];
if (patch) {

@@ -286,5 +287,5 @@ if (attributesDirty[name]) {

// Getters and setters for attributes
var blacklist = ['save', 'id', '_database', 'reload'];
const blacklist = ['save', 'id', '_database', 'reload'];
function setAttribute(name, value) {
var attribute = type.attributes[name];
const attribute = type.attributes[name];
if (attribute == null) {

@@ -343,3 +344,3 @@ return;

function triggerLoad(name) {
var rel = type.belongsTo[name];
const rel = type.belongsTo[name];
if (rel == null) {

@@ -356,3 +357,3 @@ return 'nothing to load';

else {
getBelongsTo(name);
const _ignorePromise = getBelongsTo(name);
return 'loading';

@@ -366,3 +367,3 @@ }

function getBelongsTo(name) {
var rel = type.belongsTo[name];
const rel = type.belongsTo[name];
if (rel == null) {

@@ -379,7 +380,7 @@ return Promise.resolve(undefined);

else {
var foreignType = rel.foreignType;
var relatedId = belongsToIds[name];
var promise = adapter.getData(foreignType.name, relatedId);
var promise2 = promise.then(function (data) {
var obj = null;
const foreignType = rel.foreignType;
const relatedId = belongsToIds[name];
const promise = adapter.getData(foreignType.name, relatedId);
const promise2 = promise.then(function (data) {
let obj = null;
if (data) {

@@ -410,3 +411,3 @@ obj = DatabaseObject.build(adapter, foreignType, relatedId, data);

}
var accessor = database_1.createAccessor(name, setBelongsTo, getBelongsTo);
var accessor = exports.createAccessor(name, setBelongsTo, getBelongsTo);
if (accessor != null) {

@@ -449,3 +450,3 @@ Object.defineProperty(objself, name, {

Object.keys(type.hasMany).forEach(function (name) {
var rel = type.hasMany[name];
const rel = type.hasMany[name];
if (blacklist.indexOf(name) != -1) {

@@ -460,4 +461,4 @@ return;

// This does not cache the results - widgets are responsible for that.
var expr = new queryOperations_1.RelationMatch(rel.name, objself.id);
hasManyCache[name] = new database_1.Query(adapter, rel.objectType, expr);
const expr = new queryOperations_1.RelationMatch(rel.name, objself.id);
hasManyCache[name] = new Query_1.Query(adapter, rel.objectType, expr);
}

@@ -474,3 +475,3 @@ return hasManyCache[name];

if (name === 'id') {
return id;
return Promise.resolve(id);
}

@@ -534,7 +535,7 @@ else if (type.attributes[name]) {

}
var data = toData(false); // TODO: should we convert to JSON and back?
const data = toData(false); // TODO: should we convert to JSON and back?
// If the object is not persisted, we generate a create an object
// without an id. Otherwise the clone thinks it is persisted.
var newId = persisted ? id : null;
var clone = new DatabaseObject(adapter, newType, newId);
const newId = persisted ? id : null;
let clone = new DatabaseObject(adapter, newType, newId);
clone.resolve(data);

@@ -544,4 +545,4 @@ return clone;

function _display() {
var displayFormat = type.displayFormat;
return displayFormat.evaluatePromise(objself);
const displayFormat = type.displayFormat;
return displayFormat.evaluatePromise(new evaluator_1.VariableFormatStringScope(objself));
}

@@ -620,2 +621,17 @@ // public functions, but not enumerable

}
exports.createAccessor = (name, set, get) => {
return (value) => {
if (typeof value != 'undefined') {
return set(name, value);
}
else {
return get(name);
}
};
};
// For internal use only
function setCreateAccessor(fn) {
exports.createAccessor = fn;
}
exports.setCreateAccessor = setCreateAccessor;
//# sourceMappingURL=DatabaseObject.js.map

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

Object.defineProperty(exports, "__esModule", { value: true });
const database = require("./database");
exports.database = database;
const evaluator = require("./evaluator");
exports.evaluator = evaluator;
const primitives = require("./primitives");
exports.primitives = primitives;
const query = require("./queryOperations");
exports.query = query;
const serializeInternal = require("./serializeInternal");
exports.serializeInternal = serializeInternal;
// Convenience export
var core_date_1 = require("@journeyapps/core-date");
exports.Day = core_date_1.Day;
__export(require("./credentials/ApiCredentials"));
__export(require("./credentials/MobileCredentials"));
__export(require("./Attachment"));
__export(require("./BaseAdapter"));
__export(require("./Batch"));
__export(require("./Collection"));
__export(require("./DatabaseObject"));
__export(require("./DatabaseSet"));
__export(require("./IndexedAdapter"));
__export(require("./JourneyAPIAdapter"));
__export(require("./Location"));
__export(require("./ObjectRef"));
// Everything from browser.ts, as well as OnlineDB
__export(require("./browser"));
__export(require("./OnlineDB"));
__export(require("./Query"));
__export(require("./WebSQLAdapter"));
__export(require("./utils/base64"));
__export(require("./utils/FunctionQueue"));
__export(require("./utils/uuid"));
__export(require("./database"));
require("./primitives");
//# sourceMappingURL=index.js.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
require("isomorphic-fetch");
const retryableFetch_1 = require("./utils/retryableFetch");
const BaseAdapter_1 = require("./BaseAdapter");

@@ -218,3 +219,3 @@ const parser_schema_1 = require("@journeyapps/parser-schema");

async loadDataModel() {
const response = await fetch(this.credentials.api4Url() + 'datamodel.xml', {
const response = await retryableFetch_1.retryableFetch(this.credentials.api4Url() + 'datamodel.xml', {
headers: {

@@ -239,3 +240,6 @@ Accept: 'application/xml',

};
return fetch(url, Object.assign({}, this.options.fetch, getOptions)).then(responseHandler);
return retryableFetch_1.retryableFetch(url, {
...this.options.fetch,
...getOptions
}).then(responseHandler);
}

@@ -251,3 +255,6 @@ apiPost(url, data) {

};
return fetch(url, Object.assign({}, this.options.fetch, postOptions)).then(responseHandler);
return retryableFetch_1.retryableFetch(url, {
...this.options.fetch,
...postOptions
}).then(responseHandler);
}

@@ -275,3 +282,3 @@ /**

// empty query expressions - eg. DB.user.all() - must use the standard API 'retrieve all objects' method.
if (typeof queryExpression == 'undefined') {
if (typeof queryExpression == 'undefined' || queryExpression == '') {
url = this.credentials.api4Url() + 'objects/' + typeName + '.json';

@@ -278,0 +285,0 @@ var limitUrl = 'limit=' +

@@ -41,15 +41,4 @@ "use strict";

}
/** @internal */
toInternalJSON() {
return {
latitude: this.latitude,
longitude: this.longitude,
altitude: this.altitude,
horizontal_accuracy: this.horizontal_accuracy,
vertical_accuracy: this.vertical_accuracy,
timestamp: this.timestamp.toISOString()
};
}
}
exports.Location = Location;
//# sourceMappingURL=Location.js.map

@@ -7,14 +7,14 @@ "use strict";

const ApiCredentials_1 = require("./credentials/ApiCredentials");
const database_1 = require("./database");
const Database_1 = require("./Database");
function OnlineDB(options) {
var fs = require('fs');
var datamodelXml = fs.readFileSync(options.dataModelPath, 'utf8');
var schema = new parser_schema_1.Schema().loadXml(datamodelXml, {
const fs = require('fs');
const datamodelXml = fs.readFileSync(options.dataModelPath, 'utf8');
const schema = new parser_schema_1.Schema().loadXml(datamodelXml, {
apiVersion: new parser_common_1.Version('4.0')
});
var credentials = new ApiCredentials_1.ApiCredentials(options);
var adapter = new JourneyAPIAdapter_1.JourneyAPIAdapter(credentials, schema, options.adapter);
return new database_1.Database(schema, adapter);
const credentials = new ApiCredentials_1.ApiCredentials(options);
const adapter = new JourneyAPIAdapter_1.JourneyAPIAdapter(credentials, schema, options.adapter);
return new Database_1.Database(schema, adapter);
}
exports.OnlineDB = OnlineDB;
//# sourceMappingURL=OnlineDB.js.map

@@ -319,3 +319,3 @@ "use strict";

parser_schema_1.primitives.attachment.prototype.cast = function (value) {
if (value instanceof Attachment_1.Attachment) {
if (Attachment_1.Attachment.isAttachment(value)) {
return value;

@@ -322,0 +322,0 @@ }

@@ -26,2 +26,3 @@ "use strict";

this.skipNumber = 0;
// Relationship structure to preload.
this._include = {};

@@ -43,17 +44,2 @@ // Watch this variable for changes to determine when the query should be reloaded.

}
static fromJSON(value, dbset) {
const q = value.$query;
if (dbset == null) {
throw new Error('Database is required to load query');
}
else if (dbset.schema == null) {
throw new Error('Schema is required to load query');
}
const objectType = dbset.schema.objects[q.type];
const adapter = dbset.adapters[q.database];
const qq = new Query(adapter, objectType, queryOperations_1.expressionFromJSON(objectType, q.expression), q.ordering);
qq.limitNumber = q.limit;
qq.skipNumber = q.skip;
return qq;
}
/** @internal */

@@ -88,8 +74,8 @@ _clone(newType) {

_sort(objects) {
var ordering = this.ordering;
const ordering = this.ordering;
if (ordering.length > 0) {
objects.sort(function (a, b) {
for (var i = 0; i < ordering.length; i++) {
var attribute = ordering[i];
var ascending = 1;
for (let i = 0; i < ordering.length; i++) {
let attribute = ordering[i];
let ascending = 1;
if (attribute[0] == '-') {

@@ -99,5 +85,5 @@ ascending = -1;

}
var valueA = a.attributes[attribute];
var valueB = b.attributes[attribute];
var diff = compare(valueA, valueB);
const valueA = a.attributes[attribute];
const valueB = b.attributes[attribute];
const diff = compare(valueA, valueB);
if (diff !== 0) {

@@ -107,3 +93,5 @@ return diff * ascending;

}
return 0;
const idDiff = compare(a.id, b.id);
// Do final sorting by ID to make it deterministic.
return idDiff;
});

@@ -117,5 +105,5 @@ }

var result = [];
for (var i = 0; i < data.length; i++) {
var objdata = data[i];
var object = DatabaseObject_1.DatabaseObject.build(this.adapter, this.type, objdata.id, objdata);
for (let i = 0; i < data.length; i++) {
const objdata = data[i];
const object = DatabaseObject_1.DatabaseObject.build(this.adapter, this.type, objdata.id, objdata);
result.push(object);

@@ -162,5 +150,5 @@ }

where(filters, ...args) {
var cloned = this._clone();
const cloned = this._clone();
if (arguments.length > 0) {
var e;
let e;
if (typeof filters == 'object') {

@@ -174,3 +162,3 @@ // example: where({make: 'Nokia', model: '5800})

}
var combined = new queryOperations_1.AndExpression([this.expression, e]);
const combined = new queryOperations_1.AndExpression([this.expression, e]);
cloned.expression = combined;

@@ -180,5 +168,5 @@ }

}
order_by() {
var attributes = Array.prototype.slice.call(arguments);
var q = this._clone();
order_by(...fields) {
const attributes = Array.prototype.slice.call(fields);
let q = this._clone();
q.ordering = attributes;

@@ -195,3 +183,3 @@ return q;

limit(n) {
var q = this._clone();
let q = this._clone();
q.limitNumber = n;

@@ -208,3 +196,3 @@ return q;

skip(n) {
var q = this._clone();
let q = this._clone();
q.skipNumber = n;

@@ -234,27 +222,12 @@ return q;

return this._fetch().then((objects) => {
var batch = new Batch_1.Batch(this.adapter);
let batch = new Batch_1.Batch(this.adapter);
objects.forEach(function (object) {
batch.destroy(object);
});
return batch.execute();
return batch._execute();
});
}
_count() {
return this.adapter.executeQuery(this).then(function (data) {
return data.length;
});
return this.adapter.count(this);
}
toJSON() {
return {
$query: {
type: this.type.name,
database: this.adapter.name,
limit: this.limitNumber,
expression: this.expression.toJSON(),
ordering: this.ordering,
skip: this.skipNumber,
_freshness: this._freshness
}
};
}
// Aliases

@@ -314,4 +287,19 @@ /**

}
/**
* For debugging purposes only.
*
* The format of the result is not defined.
*/
toJSON() {
return {
type: this.type.name,
expression: this.expression,
ordering: this.ordering,
limit: this.limitNumber,
skip: this.skipNumber,
include: this._include
};
}
_includeInternal(relationshipHash) {
var q = this._clone();
let q = this._clone();
deepMerge(q._include, relationshipHash);

@@ -328,5 +316,17 @@ return q;

}
if (a > b) {
// We can't > or < with `null` or `undefined` - do this manually.
// null, undefined < anything else
// Note that `== null` also matches `undefined`.
if (a == null && b == null) {
return 0;
}
else if (a == null) {
return -1;
}
else if (b == null) {
return 1;
}
else if (a > b) {
return 1;
}
else if (a < b) {

@@ -360,3 +360,3 @@ return -1;

// compared to querying the database.
var relationships = {};
let relationships = {};
if (columns == null) {

@@ -368,5 +368,17 @@ // object-list, use the default display format for the object

// object-table, use the specified column values
for (let display of columns) {
deepMerge(relationships, display.extractRelationshipStructure(type));
if (Array.isArray(columns)) {
for (let display of columns) {
if (display && typeof display.extractRelationshipStructure == 'function') {
deepMerge(relationships, display.extractRelationshipStructure(type));
}
}
}
else {
for (let key in columns) {
const display = columns[key];
if (display && typeof display.extractRelationshipStructure == 'function') {
deepMerge(relationships, display.extractRelationshipStructure(type));
}
}
}
}

@@ -408,9 +420,9 @@ return relationships;

}
var nestedObjects = [];
let nestedObjects = [];
const promise = adapter.getAll(relatedType.name, ids).then(async (data) => {
for (let i = 0; i < objects.length; i++) {
var object = objects[i];
var relatedData = data[i];
const object = objects[i];
const relatedData = data[i];
if (relatedData != null) {
var related = DatabaseObject_1.DatabaseObject.build(adapter, relatedType, relatedData.id, relatedData);
const related = DatabaseObject_1.DatabaseObject.build(adapter, relatedType, relatedData.id, relatedData);
object._cache(key, related);

@@ -417,0 +429,0 @@ nestedObjects.push(related);

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

Object.defineProperty(exports, "__esModule", { value: true });
const primitives = require("./primitives");
const internal = require("./serializeInternal");
const parser_schema_1 = require("@journeyapps/parser-schema");
var _flatten = require('lodash/flatten'); // tslint:disable-line
var _tail = require('lodash/tail'); // tslint:disable-line
var Day = primitives.Day;
parser_schema_1.QueryType.prototype.cast = function (value) {
if (typeof value != 'object') {
throw new Error(value + ' is not an object');
}
var thisTypeName = this.objectType.name;
if (value.type != null &&
value.type instanceof parser_schema_1.ObjectType &&
value.type.name == thisTypeName &&
typeof value._fetch == 'function') {
// This implies that value is (likely) also an instance of Query.
return value;
}
else {
// We do not print the value here, since it may be a massive array.
throw new Error('Expected value to have query type ' + thisTypeName);
}
};
// Parse a serialized expression
function expressionFromJSON(scopeType, json) {
if (json == null) {
return new TrueExpression();
}
var expressionType = json.__type;
if (expressionType == 'Operation') {
const attribute = scopeType.getAttribute(json.attribute);
if (attribute == null) {
throw new Error("'" + json.attribute + "' is not defined on '" + scopeType.name + "'");
}
const value = internal.deserialize(json.value);
return new Operation(attribute, json.operator, value);
}
else if (expressionType == 'TrueExpression') {
return new TrueExpression();
}
else if (expressionType == 'AndExpression' ||
expressionType == 'OrExpression') {
var operands = [];
for (let value of json.operands) {
operands.push(expressionFromJSON(scopeType, value));
}
if (expressionType == 'AndExpression') {
return new AndExpression(operands);
}
else {
return new OrExpression(operands);
}
}
else if (expressionType == 'RelationMatch') {
return new RelationMatch(json.name, json.id);
}
else {
throw new Error('Unknown expression: ' + JSON.stringify(json));
}
}
exports.expressionFromJSON = expressionFromJSON;
const core_date_1 = require("@journeyapps/core-date");
const _ = require("lodash");
// Build an expression from a hash such as {make: 'Nokia', model: '5800'}
function expressionFromHash(scopeType, hash) {
var operations = [];
for (var key in hash) {
let operations = [];
for (let key in hash) {
if (hash.hasOwnProperty(key)) {
var value = hash[key];
var attribute = scopeType.getAttribute(key);
let value = hash[key];
const attribute = scopeType.getAttribute(key);
if (attribute == null) {

@@ -82,3 +23,3 @@ throw new Error("'" + key + "' is not defined on '" + scopeType.name + "'");

}
var operation = new Operation(attribute, '=', value);
const operation = new Operation(attribute, '=', value);
operations.push(operation);

@@ -92,2 +33,5 @@ }

// An operation has an attribute (variable), operator and (constant) value to compare with.
function discardMillis(ms) {
return Math.floor(ms / 1000) * 1000;
}
class Operation {

@@ -106,4 +50,4 @@ constructor(attribute, operator, value) {

evaluate(object) {
var rawAttributeValue;
var attributeValue;
let rawAttributeValue;
let attributeValue;
if (this.attribute.relationship) {

@@ -126,10 +70,22 @@ attributeValue = object.belongs_to[this.attribute.relationship];

}
var compareDiff = null;
let compareDiff = null;
if (typeof attributeValue == 'number' && typeof this.value == 'number') {
compareDiff = attributeValue - this.value;
}
else if (typeof attributeValue == 'string' && typeof this.value == 'string') {
if (attributeValue < this.value) {
compareDiff = -1;
}
else if (attributeValue > this.value) {
compareDiff = 1;
}
else {
compareDiff = 0;
}
}
else if (attributeValue instanceof Date && this.value instanceof Date) {
compareDiff = attributeValue.getTime() - this.value.getTime();
// Compare seconds only
compareDiff = discardMillis(attributeValue.getTime()) - discardMillis(this.value.getTime());
}
else if (attributeValue instanceof Day || this.value instanceof Day) {
else if (attributeValue instanceof core_date_1.Day || this.value instanceof core_date_1.Day) {
// New syntax only

@@ -139,4 +95,3 @@ try {

// Also works for JSON strings.
compareDiff =
new Day(attributeValue).valueOf() - new Day(this.value).valueOf();
compareDiff = new core_date_1.Day(attributeValue).valueOf() - new core_date_1.Day(this.value).valueOf();
}

@@ -185,3 +140,3 @@ catch (err) {

if (typeof attributeValue == 'string' && typeof this.value == 'string') {
return (attributeValue.toLowerCase().indexOf(this.value.toLowerCase()) >= 0);
return attributeValue.toLowerCase().indexOf(this.value.toLowerCase()) >= 0;
}

@@ -194,3 +149,3 @@ else {

if (typeof attributeValue == 'string' && typeof this.value == 'string') {
return (attributeValue.toLowerCase().indexOf(this.value.toLowerCase()) === 0);
return attributeValue.toLowerCase().indexOf(this.value.toLowerCase()) === 0;
}

@@ -205,21 +160,9 @@ else {

}
toJSON() {
return {
__type: 'Operation',
attribute: this.attribute.name,
operator: this.operator,
value: internal.serialize(this.value)
};
}
toString() {
return this.attribute.name + ' ' + this.operator + ' ' + this.value;
}
// This is relevant only for the Backend JS Console
toOriginalExpression() {
if (this.attribute.relationship) {
// Works for both relationships (user = ?) and relationship ids (user_id = ?)
return [
this.attribute.relationship + '_id ' + this.operator + ' ?',
this.value
];
return [this.attribute.relationship + '_id ' + this.operator + ' ?', this.value];
}

@@ -243,16 +186,8 @@ else {

evaluate(object) {
var relatedId = object.belongs_to[this.name];
const relatedId = object.belongs_to[this.name];
return relatedId == this.id;
}
toJSON() {
return {
__type: 'RelationMatch',
name: this.name,
id: this.id
};
}
toString() {
return this.name + ' = ' + this.id;
}
// This is relevant only for the Backend JS Console
toOriginalExpression() {

@@ -270,11 +205,11 @@ return [this.name + '_id = ?', this.id];

join(otherAnd) {
var ops = this.operands.concat(otherAnd.operands);
const ops = this.operands.concat(otherAnd.operands);
return new AndExpression(ops);
}
normalize() {
var i;
let i;
// Step 1: filter out TrueExpression
var operands = [];
let operands = [];
for (i = 0; i < this.operands.length; i++) {
var op = this.operands[i];
const op = this.operands[i];
if (!(op instanceof TrueExpression)) {

@@ -291,12 +226,12 @@ operands.push(op);

else if (operands.length > 2) {
var a = new AndExpression(operands.slice(0, 2));
var b = new AndExpression(operands.slice(2));
const a = new AndExpression(operands.slice(0, 2));
const b = new AndExpression(operands.slice(2));
return new AndExpression([a, b]).normalize();
}
else {
var left = operands[0].normalize().operands;
var right = operands[1].normalize().operands;
var newOperands = [];
const left = operands[0].normalize().operands;
const right = operands[1].normalize().operands;
let newOperands = [];
for (i = 0; i < left.length; i++) {
for (var j = 0; j < right.length; j++) {
for (let j = 0; j < right.length; j++) {
newOperands.push(left[i].join(right[j]));

@@ -309,4 +244,4 @@ }

evaluate(object) {
for (var i = 0; i < this.operands.length; i++) {
var operand = this.operands[i];
for (let i = 0; i < this.operands.length; i++) {
const operand = this.operands[i];
if (!operand.evaluate(object)) {

@@ -318,14 +253,6 @@ return false;

}
toJSON() {
return {
__type: 'AndExpression',
operands: this.operands.map(function (o) {
return o.toJSON();
})
};
}
toString() {
var s = '(';
for (var i = 0; i < this.operands.length; i++) {
var operand = this.operands[i];
let s = '(';
for (let i = 0; i < this.operands.length; i++) {
const operand = this.operands[i];
s += operand.toString();

@@ -339,21 +266,27 @@ if (i != this.operands.length - 1) {

}
// This is relevant only for the Backend JS Console
toOriginalExpression() {
var args = [];
var s = '(';
for (var i = 0; i < this.operands.length; i++) {
var operand = this.operands[i];
if (operand instanceof TrueExpression) {
let args = [];
let s = '(';
for (let i = 0; i < this.operands.length; i++) {
const operand = this.operands[i];
if (operand instanceof TrueExpression)
continue;
let opPair = operand.toOriginalExpression();
if (opPair[0] == '') {
// nested TrueExpression
continue;
}
var opPair = operand.toOriginalExpression();
s += opPair[0];
args.push(_tail(opPair));
args = _flatten(args);
if (i != this.operands.length - 1) {
if (s.length > 1) {
// Not the first operand
s += ' and ';
}
s += opPair[0];
args.push(_.tail(opPair));
args = _.flatten(args);
}
s += ')';
return _flatten([s, args]);
if (s.length == 2) {
return new TrueExpression().toOriginalExpression();
}
return _.flatten([s, args]);
}

@@ -369,3 +302,3 @@ }

normalize() {
var newOperands = [];
const newOperands = [];
this.operands.forEach(function (op) {

@@ -380,4 +313,4 @@ const norm = op.normalize();

evaluate(object) {
for (var i = 0; i < this.operands.length; i++) {
var operand = this.operands[i];
for (let i = 0; i < this.operands.length; i++) {
const operand = this.operands[i];
if (operand.evaluate(object)) {

@@ -389,14 +322,6 @@ return true;

}
toJSON() {
return {
__type: 'OrExpression',
operands: this.operands.map(function (o) {
return o.toJSON();
})
};
}
toString() {
var s = '(';
for (var i = 0; i < this.operands.length; i++) {
var operand = this.operands[i];
let s = '(';
for (let i = 0; i < this.operands.length; i++) {
const operand = this.operands[i];
s += operand.toString();

@@ -410,15 +335,15 @@ if (i != this.operands.length - 1) {

}
// This is relevant only for the Backend JS Console
toOriginalExpression() {
var args = [];
var s = '(';
for (var i = 0; i < this.operands.length; i++) {
var operand = this.operands[i];
let args = [];
let s = '(';
for (let i = 0; i < this.operands.length; i++) {
const operand = this.operands[i];
if (operand instanceof TrueExpression) {
continue;
// One TrueExpression makes the entire OR clause true
return operand.toOriginalExpression();
}
var opPair = operand.toOriginalExpression();
const opPair = operand.toOriginalExpression();
s += opPair[0];
args.push(_tail(opPair));
args = _flatten(args);
args.push(_.tail(opPair));
args = _.flatten(args);
if (i != this.operands.length - 1) {

@@ -429,3 +354,3 @@ s += ' or ';

s += ')';
return _flatten([s, args]);
return _.flatten([s, args]);
}

@@ -437,2 +362,3 @@ }

class TrueExpression {
constructor() { }
normalize() {

@@ -448,11 +374,13 @@ return new OrExpression([new AndExpression([this])]);

toOriginalExpression() {
return [];
return [''];
}
toJSON() {
return {
__type: 'TrueExpression'
};
}
}
exports.TrueExpression = TrueExpression;
// We should probably support international characters as well
function isLetter(character) {
return (character >= 'a' && character <= 'z') || (character >= 'A' && character <= 'Z');
}
function isDigit(character) {
return character >= '0' && character <= '9';
}
const OPERATORS = ['>=', '<=', '=', '!=', '>', '<', 'starts with', 'contains'];

@@ -465,14 +393,12 @@ const BOOLEAN_LOGIC = ['and', 'or'];

constructor(expression) {
this.expression = expression;
this.i = 0;
this.interpolatorCount = 0;
this.expression = expression;
if (expression == null) {
throw new Error('expression is required');
}
this.advance();
}
exception(message, start, end) {
var error = new Error(message +
'\n' +
this.expression +
'\n' +
new Array(this.i + 1).join(' ') +
'^');
let error = new Error(message + '\n' + this.expression + '\n' + new Array(this.i + 1).join(' ') + '^');
if (start == null) {

@@ -486,5 +412,8 @@ start = this.i;

}
isWordSeparator(p) {
return p >= this.expression.length || this.expression[p] == ' ';
}
isWord() {
this.checkBuffer();
return (this.isLetter(this.expression[this.i]) || this.expression[this.i] == '_');
return isLetter(this.expression[this.i]) || this.expression[this.i] == '_';
}

@@ -520,3 +449,3 @@ hasMore() {

}
var c = this.expression[this.i];
const c = this.expression[this.i];
this.i++;

@@ -526,26 +455,6 @@ this.advance();

}
// Read a single alphanumeric word. May contain underscores.
readWord() {
this.checkBuffer();
var word = '';
word += this.expression[this.i];
var offset = 1;
while (this.expression.length > this.i + offset) {
const char = this.expression[this.i + offset];
if (this.isLetter(char) || this.isDigit(char) || char == '_') {
word += this.expression[this.i + offset++];
}
else {
break;
}
}
this.i += offset;
this.advance();
return word;
}
// Read an interpolation character "?"
readInterpolator() {
this.checkBuffer();
if (this.expression[this.i] == '?' &&
(this.isWordSeparator(this.i + 1) || this.expression[this.i + 1] == ')')) {
if (this.expression[this.i] == '?' && (this.isWordSeparator(this.i + 1) || this.expression[this.i + 1] == ')')) {
this.i += 1;

@@ -559,2 +468,18 @@ this.advance();

}
// Read a single alphanumeric word. May contain underscores.
readWord() {
this.checkBuffer();
let word = '';
word += this.expression[this.i];
let offset = 1;
while (this.expression.length > this.i + offset &&
(isLetter(this.expression[this.i + offset]) ||
isDigit(this.expression[this.i + offset]) ||
this.expression[this.i + offset] == '_')) {
word += this.expression[this.i + offset++];
}
this.i += offset;
this.advance();
return word;
}
// Advance to the next non-whitespace character.

@@ -567,13 +492,2 @@ advance() {

}
isWordSeparator(p) {
return p >= this.expression.length || this.expression[p] == ' ';
}
// We should probably support international characters as well
isLetter(character) {
return ((character >= 'a' && character <= 'z') ||
(character >= 'A' && character <= 'Z'));
}
isDigit(character) {
return character >= '0' && character <= '9';
}
checkBuffer() {

@@ -589,4 +503,4 @@ if (!this.hasMore()) {

this.checkBuffer();
for (var j = 0; j < tokens.length; j++) {
var token = tokens[j];
for (let j = 0; j < tokens.length; j++) {
const token = tokens[j];
if (this.i + token.length <= this.expression.length) {

@@ -605,8 +519,7 @@ if (token == this.expression.substring(this.i, this.i + token.length)) {

this.checkBuffer();
for (var j = 0; j < tokens.length; j++) {
var token = tokens[j];
for (let j = 0; j < tokens.length; j++) {
const token = tokens[j];
if (this.i + token.length <= this.expression.length) {
if (token == this.expression.substring(this.i, this.i + token.length)) {
if (!this.isLetter(token[token.length - 1]) ||
this.isWordSeparator(this.i + token.length)) {
if (!isLetter(token[token.length - 1]) || this.isWordSeparator(this.i + token.length)) {
return true;

@@ -625,13 +538,13 @@ }

constructor(scopeType, tokenizer, args) {
this.scopeType = scopeType;
this.tokenizer = tokenizer;
this.args = args;
if (args == null) {
args = [];
this.args = [];
}
this.args = args;
this.scopeType = scopeType;
this.tokenizer = tokenizer;
}
parse() {
var e = this.parseOrExpression();
const e = this.parseOrExpression();
if (this.tokenizer.hasMore()) {
throw this.tokenizer.exception('Unexpected token');
throw this.tokenizer.exception('Invalid expression (expected expression to end)');
}

@@ -641,10 +554,10 @@ return e;

/*
expr : term ( ( AND | OR ) term ) *
term : ( attribute operator value ) | ( \( expression \) )
factor : NUMBER ;
expr : term ( ( AND | OR ) term ) *
term : ( attribute operator value ) | ( \( expression \) )
factor : NUMBER ;
*/
parseOrExpression() {
var e = this.parseAndExpression();
const e = this.parseAndExpression();
if (this.tokenizer.hasMore() && this.tokenizer.isOr()) {
var expressions = [e];
let expressions = [e];
while (this.tokenizer.hasMore() && this.tokenizer.isOr()) {

@@ -661,5 +574,5 @@ this.tokenizer.readBooleanLogic();

parseAndExpression() {
var e = this.parseTerm();
const e = this.parseTerm();
if (this.tokenizer.hasMore() && this.tokenizer.isAnd()) {
var expressions = [e];
let expressions = [e];
while (this.tokenizer.hasMore() && this.tokenizer.isAnd()) {

@@ -678,14 +591,10 @@ this.tokenizer.readBooleanLogic();

let attributeStart = this.tokenizer.i;
var attributeName = this.tokenizer.readWord();
const attributeName = this.tokenizer.readWord();
let attributeEnd = this.tokenizer.previousPosition + 1;
var operator = this.tokenizer.readOperator();
const operator = this.tokenizer.readOperator();
let interpolatorPosition = this.tokenizer.i;
var valueIndex = this.tokenizer.readInterpolator();
var attribute = this.scopeType.getAttribute(attributeName);
const valueIndex = this.tokenizer.readInterpolator();
const attribute = this.scopeType.getAttribute(attributeName);
if (attribute == null) {
throw this.tokenizer.exception("'" +
attributeName +
"' is not a valid field of '" +
this.scopeType.name +
"'", attributeStart, attributeEnd);
throw this.tokenizer.exception("'" + attributeName + "' is not a valid field of '" + this.scopeType.name + "'", attributeStart, attributeEnd);
}

@@ -696,3 +605,3 @@ else if (attribute.type.isCollection) {

if (this.args.length > valueIndex) {
var value = this.args[valueIndex];
let value = this.args[valueIndex];
if (attribute.type.isObject && value != null) {

@@ -708,7 +617,7 @@ value = value.id;

else if (this.tokenizer.isParenthesis()) {
var c = this.tokenizer.readParenthesis();
let c = this.tokenizer.readParenthesis();
if (c != '(') {
throw this.tokenizer.exception('Expected (', this.tokenizer.previousPosition);
}
var e = this.parseOrExpression();
const e = this.parseOrExpression();
c = this.tokenizer.readParenthesis();

@@ -715,0 +624,0 @@ if (c != ')') {

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const IndexedAdapter_1 = require("./IndexedAdapter");
const BaseAdapter_1 = require("./BaseAdapter");

@@ -14,5 +13,5 @@ var logQuery = BaseAdapter_1.BaseAdapter.logQuery;

}
class WebSQLAdapter extends IndexedAdapter_1.IndexedAdapter {
class WebSQLAdapter extends BaseAdapter_1.BaseAdapter {
constructor(options) {
super(options);
super();
this.db = null;

@@ -52,18 +51,10 @@ if (options.stf) {

}
if (version < 4) {
if (version < 6) {
tx.loggedSql('DROP TABLE IF EXISTS object_indexes', []);
tx.loggedSql('CREATE TABLE IF NOT EXISTS object_indexes (id TEXT, type TEXT, index_name TEXT, key BLOB, index_version)', []);
tx.loggedSql('CREATE INDEX IF NOT EXISTS indexes_by_object ON object_indexes(type, id)', []);
tx.loggedSql('CREATE INDEX IF NOT EXISTS indexes_by_key ON object_indexes(type, index_name, key)', []);
tx.loggedSql('ALTER TABLE objects ADD COLUMN index_version INTEGER', []);
tx.loggedSql('CREATE INDEX IF NOT EXISTS objects_by_index_version ON objects(type, index_version)', []);
tx.loggedSql('DROP INDEX IF EXISTS objects_by_index_version', []);
}
if (version < 5) {
tx.loggedSql('CREATE INDEX IF NOT EXISTS indexes_by_type_version ON object_indexes(type, index_version)', []);
}
version = 5;
version = 6;
tx.loggedSql('INSERT OR REPLACE INTO versions(name, version) VALUES(?, ?)', ['db', version]);
});
})
.then(this.loadIndexes.bind(this));
});
}

@@ -102,32 +93,2 @@ /**

}
/**
* Update the indexes to the specified set.
* This runs in an exclusive lock, blocking all other database writes and all queries.
* This operation is idempotent, and should be fast if all the indexes
* are already up to date.
*/
updateIndexes(indexes) {
var self = this;
var totalCount = 0;
return this.indexQueue.enqueue(function () {
var promises = [];
indexes.modelIndexes().forEach(function (modelIndexes) {
// modelIndexes is the index per model.
// TODO: it may be better to do these updates sequentially.
var promise = self._updateIndexData(modelIndexes).then(function (count) {
totalCount += count;
});
promises.push(promise);
});
return Promise.all(promises).then(function () {
// Update the current version of index (for queries and writes).
// Do this inside the indexQueue block, so that any queries
// waiting on us will use the new indexes.
self.indexes = indexes;
// The count is useful mostly for specs, so that we can confirm that the correct number
// of objects were updated.
return { updated: totalCount };
});
});
}
applyCrud(crud) {

@@ -142,11 +103,7 @@ this.ensureOpen();

if (action == 'put') {
var syncInfo = {
hash: data.hash,
update_id: data.update_id
};
ids.push(data.id);
this.transactionSaveData(tx, data, null, syncInfo);
this.transactionSaveData(tx, data, null);
}
else if (action == 'delete') {
this.transactionDestroy(tx, data.type, data.id, true);
this.transactionDestroy(tx, data.type, data.id);
}

@@ -167,6 +124,6 @@ else {

*/
applyBatch(crud) {
async applyBatch(crud) {
this.ensureOpen();
var results = [];
return this.promisedTransaction((tx) => {
await this.promisedTransaction((tx) => {
for (var i = 0; i < crud.length; i++) {

@@ -189,17 +146,23 @@ var operation = crud[i];

}
})
.then(() => {
return this.dataChanged();
})
.then(() => {
return results;
});
return results;
}
async save(data, patch) {
this.ensureOpen();
if (patch != null) {
if (Object.keys(patch.attributes).length === 0 &&
Object.keys(patch.belongs_to).length === 0) {
// No change - don't save anything
return null;
}
}
await this.saveData(data, patch);
}
// Persist an object and its relationships.
// The object and it's relationships MUST be loaded before this is called.
// Returns a promise that is resolved when the object is persisted.
saveData(data, patch, syncInfo) {
saveData(data, patch) {
this.ensureOpen();
return this.promisedTransaction(tx => {
this.transactionSaveData(tx, data, patch, syncInfo);
this.transactionSaveData(tx, data, patch);
});

@@ -212,11 +175,34 @@ }

*/
destroy(type, id, remoteChange) {
async destroy(type, id) {
this.ensureOpen();
var self = this;
return this.promisedTransaction(function (tx) {
self.transactionDestroy(tx, type, id, remoteChange);
}).then(function () {
IndexedAdapter_1.IndexedAdapter.prototype.destroy.call(self, type, id, remoteChange);
await this.promisedTransaction(async (tx) => {
await this.transactionDestroy(tx, type, id);
});
await super.destroy(type, id);
}
/**
* Perform a query.
* Returns a promise that is resolved with the resultset.
*/
async executeQuery(query) {
const skip = query.skipNumber;
const limit = query.limitNumber;
const { data } = await this.executeTableScan(query);
let result = [];
if (skip >= data.length) {
return result;
}
const startIndex = !skip ? 0 : skip;
for (let i = startIndex, recordCount = 0; i < data.length && (limit == null || recordCount < limit); i++, recordCount++) {
result.push(data[i]);
}
return result;
}
explain(query) {
const start = new Date();
return this.executeTableScan(query).then(function (results) {
results.duration = new Date().getTime() - start.getTime();
return results;
});
}
executeTableScan(query) {

@@ -311,191 +297,2 @@ this.ensureOpen();

}
getByIndex(range) {
var key = range.toSqlRange('object_indexes.key');
var query = 'SELECT objects.* FROM objects INNER JOIN object_indexes ON objects.type = object_indexes.type AND objects.id = object_indexes.id' +
' WHERE object_indexes.type=? AND object_indexes.index_name=? AND ' +
key.clause;
return this.simpleQuery(query, [
key.type,
key.index,
key.lower,
key.upper
]).then(function (rs) {
var all = [];
for (var i = 0; i < rs.rows.length; i++) {
var row = rs.rows.item(i);
var data = JSON.parse(row.data);
data.update_id = row.uid;
data.hash = row.hash;
all.push(data);
}
return all;
});
}
getByIndexes(typeName, ranges) {
var self = this;
var all = {};
var promises = [];
ranges.forEach(function (range) {
promises.push(self.getByIndex(range).then(function (results) {
results.forEach(function (object) {
all[object.id] = object;
});
}));
});
return Promise.all(promises).then(function () {
var objects = [];
for (var id in all) {
objects.push(all[id]);
}
return objects;
});
}
/**
* Get a batch of objects to send to the server.
* When the objects are successfully sent to the server, call crudComplete(t).
* Returns a promise resolving with: {crud: [], transaction: t}
*/
getCrudBatch(limit) {
this.ensureOpen();
limit = limit || 100;
return this.simpleQuery('SELECT * FROM crud ORDER BY id ASC LIMIT ?', [
limit
]).then(function (rs) {
var all = [];
var transactionDetails = [];
for (var i = 0; i < rs.rows.length; i++) {
var row = rs.rows.item(i);
var data = JSON.parse(row.data);
var id = row.id;
all.push(data);
transactionDetails.push(id);
}
if (all.length === 0) {
return null;
}
else {
return { crud: all, transaction: transactionDetails };
}
});
}
crudComplete(transaction) {
this.ensureOpen();
// Ugly, but faster than a separate query for every CRUD message (unconfirmed)
var q = queryIn(transaction.length);
return this.simpleQuery('DELETE FROM crud WHERE id IN (' + q + ')', transaction).then(() => null);
}
/**
* Delete all objects in the specified range, excluding those listed in the `skip` array (optional).
*/
clearRange(start, end, skip) {
// There is a limit to the number of variables allowed
this.ensureOpen();
skip = skip || [];
var q = queryIn(skip.length);
start = start || '';
return this.simpleQuery('DELETE FROM objects WHERE uid >= ? AND uid < ? AND id NOT IN (' +
q +
')', [start, end].concat(skip)).then(() => null);
}
// Clear all objects without an uid.
// We ONLY do this if the crud table is empty. Otherwise, we may get issues where the local data is cleared
// before it was even sent to the server.
clearLocal() {
this.ensureOpen();
var cleared;
var error = null;
// It is important that this happens in the same transaction, so that it doesn't overlap with a saveData() call.
return this.promisedTransaction(tx => {
tx.loggedSql('SELECT COUNT(*) as count FROM crud', [], function (tx2, rs) {
try {
var count = 0;
if (rs.rows.length >= 1) {
var row = rs.rows.item(0);
count = row.count;
}
else {
// Should not happen. Assume count = 0.
}
if (count === 0) {
cleared = true;
tx2.loggedSql('DELETE FROM objects WHERE uid IS NULL', []);
}
else {
cleared = false;
}
}
catch (err) {
this.logError('Error during clearLocal() callback', err);
error = err;
}
});
}).then(() => {
if (error != null) {
throw error;
}
else {
return cleared;
}
});
}
/**
* Sum the hashes of all objects in the specified range.
* */
calculateHash(start, end) {
this.ensureOpen();
start = start || '';
return this.simpleQuery('SELECT SUM(hash) AS hash, COUNT(id) AS count FROM objects WHERE uid >= ? AND uid < ?', [start, end]).then(function (rs) {
if (rs.rows.length >= 1) {
var row = rs.rows.item(0);
// row.hash is null if there are nothing in the specified range.
var hash = row.hash || 0;
// Hash should be 32 bits only
hash = hash & 0xffffffff;
if (hash >= 0x80000000) {
hash -= 0x100000000;
}
return { hash: hash, count: row.count };
}
else {
// Should not happen
return { hash: 0, count: 0 };
}
});
}
// Return the highest update id in the database, as a promise.
getLastUpdateId() {
this.ensureOpen();
return this.simpleQuery('SELECT MAX(uid) AS uid FROM objects', []).then(function (rs) {
if (rs.rows.length >= 1) {
var row = rs.rows.item(0);
return row.uid;
}
else {
// Empty table
return null;
}
});
}
// Private function, but exported for tests
uidAtOffset(start, end, offset) {
this.ensureOpen();
return this.simpleQuery('SELECT uid FROM objects where uid >= ? AND uid < ? ORDER BY uid LIMIT 1 offset ?', [start, end, offset]).then(function (rs) {
if (rs.rows.length >= 1) {
var row = rs.rows.item(0);
return row.uid;
}
else {
return null;
}
});
}
uidAtOffsets(start, end, offsets) {
this.ensureOpen();
// TODO: wrap this in a single transaction
var promises = [];
for (var i = 0; i < offsets.length; i++) {
promises.push(this.uidAtOffset(start, end, offsets[i]));
}
return Promise.all(promises);
}
estimateBytesUsed() {

@@ -532,32 +329,2 @@ // We only count the length of the dynamically-sized data here

}
estimateQueueBytesUsed() {
// We only count the length of the dynamically-sized data here
var dataSum = this.simpleQuery('SELECT SUM(LENGTH(data)) as sum FROM crud').then(function (rs) {
if (rs.rows.length >= 1) {
var row = rs.rows.item(0);
return row.sum;
}
else {
return 0;
}
});
var objectCount = this.simpleQuery('SELECT COUNT(id) as count FROM crud').then(function (rs) {
if (rs.rows.length >= 1) {
var row = rs.rows.item(0);
return row.count;
}
else {
return 0;
}
});
return Promise.all([dataSum, objectCount]).then(function (results) {
var sum = results[0];
var count = results[1];
var stringCharacters = sum;
// 20 bytes overhead per record (including the ID)
var overhead = 20 * count;
// 2 bytes per character
return stringCharacters * 2 + overhead;
});
}
openDatabase(name) {

@@ -610,136 +377,12 @@ return window.openDatabase(name, 'Objects', 20 * 1024 * 1024, function () {

}
transactionSaveData(tx, data, patch, syncInfo) {
var updateId = null;
var hash = null;
// Save to crud queue, only if:
// 1. Not downloaded through sync service (sync_info == null)
// 2. This is not a local-only database (self.sync)
if (syncInfo == null) {
if (this.sync) {
if (patch != null) {
tx.loggedSql('INSERT INTO crud(data) VALUES (?)', [
JSON.stringify({ patch: patch })
]);
}
else {
tx.loggedSql('INSERT INTO crud(data) VALUES (?)', [
JSON.stringify({ put: data })
]);
}
}
}
else {
updateId = syncInfo.update_id;
hash = syncInfo.hash;
}
var modelIndexes = this.indexes.indexesFor(data.type);
tx.loggedSql('INSERT OR REPLACE INTO objects(id, type, data, uid, hash, index_version) VALUES (?,?,?,?,?,?)', [
transactionSaveData(tx, data, patch) {
tx.loggedSql('INSERT OR REPLACE INTO objects(id, type, data) VALUES (?,?,?)', [
data.id,
data.type,
JSON.stringify(data),
updateId,
hash,
modelIndexes.version
JSON.stringify(data)
]);
// Update indexes
this._updateItemIndexes(tx, modelIndexes, data);
}
transactionDestroy(tx, type, id, remoteChange) {
if (!remoteChange) {
tx.loggedSql('INSERT INTO crud(data) VALUES (?)', [
JSON.stringify({ delete: { id: id, type: type } })
]);
}
transactionDestroy(tx, type, id) {
tx.loggedSql('DELETE FROM objects WHERE type=? AND id=?', [type, id]);
// Update indexes
tx.loggedSql('DELETE FROM object_indexes WHERE id=? AND type=?', [
id,
type
]);
}
_updateItemIndexes(transaction, modelIndexes, data, del) {
if (del != 'NO_DELETE') {
transaction.loggedSql('DELETE FROM object_indexes WHERE id=? AND type=?', [data.id, data.type]);
}
var indexKeys = modelIndexes.generateSqlKeys(data);
Object.keys(indexKeys).forEach(function (indexName) {
var key = indexKeys[indexName];
transaction.loggedSql('INSERT INTO object_indexes(id, type, index_name, key, index_version) VALUES (?,?,?,?,?)', [data.id, data.type, indexName, key, modelIndexes.version]);
});
}
// Update the index data for a model.
_updateIndexData(modelIndexes) {
var self = this;
var typeName = modelIndexes.type;
var version = modelIndexes.version;
// We split this into batches of 1000, each batch inside a transaction.
// Larger transactions use too much memory, and small transactions have
// too much transaction overhead.
var BATCH_SIZE = 1000;
function processBatch() {
var count;
return self
.promisedTransaction(function (transaction) {
return new Promise(function (resolve, reject) {
function processResults(tx, rs) {
var n = rs.rows.length;
for (var i = 0; i < n; i++) {
var row = rs.rows.item(i);
var data = JSON.parse(row.data);
// Update the indexes for this item.
self._updateItemIndexes(transaction, modelIndexes, data, 'NO_DELETE');
transaction.loggedSql('UPDATE objects SET index_version = ? WHERE type = ? and id = ?', [version, typeName, row.id]);
}
count = n;
resolve();
}
// Find a batch of objects of this model with outdated indexes.
// We want a query for:
// SELECT * FROM objects WHERE objects.type = ? AND objects.index_version != ?
// However, that doesn't use index_version in the index.
// (index_version < ? OR index_version > ?) seems to work for select queries.
transaction.loggedSql('SELECT * FROM objects WHERE objects.type = ? AND (objects.index_version < ? OR objects.index_version > ?) LIMIT ?', [
typeName,
modelIndexes.version,
modelIndexes.version,
BATCH_SIZE
], processResults);
});
})
.then(function () {
return count;
});
}
function recursiveBatches() {
return processBatch().then(function (count) {
if (count > 0) {
// We processed data, and there may be more to process.
return recursiveBatches().then(function (nextCount) {
return count + nextCount;
});
}
else {
// We are done here
return count;
}
});
}
return recursiveBatches().then(count => {
// After processing all the data, delete the old indexes.
// We only delete the index afterwards, so that we're not in a
// completely inconsistent state if the rebuild is interrupted.
return this.promisedTransaction(function (transaction) {
// We want a query for:
// DELETE FROM object_indexes WHERE type = ? and index_version != ?
// However, that doesn't use index_version in the index.
// (index_version < ? OR index_version > ?) uses the index for SELECT, but not DELETE.
// Doing this in two separate queries seems to be the best solution for now.
// TODO: if we guaruntee that index_version is always increasing, we can remove the > query.
transaction.loggedSql('DELETE FROM object_indexes WHERE type = ? and index_version < ?', [typeName, version]);
transaction.loggedSql('DELETE FROM object_indexes WHERE type = ? and index_version > ?', [typeName, version]);
}).then(function () {
return count;
});
});
}
logError(...args) {

@@ -746,0 +389,0 @@ console.error(...args); // tslint:disable-line

{
"name": "@journeyapps/db",
"version": "0.0.0-dev.61472d2.0a3ef77",
"version": "0.0.0-dev.62eaa55.99ffd7e",
"description": "Journey JS library",
"main": "./dist/src/index.js",
"browser": "./dist/src/browser.js",
"typings": "./dist/@types/src/index",

@@ -14,6 +15,6 @@ "scripts": {

"dependencies": {
"@journeyapps/core-date": "0.0.0-dev.61472d2.0a3ef77",
"@journeyapps/core-xml": "0.0.0-dev.61472d2.0a3ef77",
"@journeyapps/evaluator": "0.0.0-dev.61472d2.0a3ef77",
"@journeyapps/parser-schema": "0.0.0-dev.61472d2.0a3ef77",
"@journeyapps/core-date": "0.0.0-dev.62eaa55.99ffd7e",
"@journeyapps/core-xml": "0.0.0-dev.62eaa55.99ffd7e",
"@journeyapps/evaluator": "0.0.0-dev.62eaa55.99ffd7e",
"@journeyapps/parser-schema": "0.0.0-dev.62eaa55.99ffd7e",
"isomorphic-fetch": "^2.2.1",

@@ -31,3 +32,3 @@ "moment": "^2.24.0",

],
"gitHead": "ef21921a0f0c800a891a7402158a8be9b0195221"
"gitHead": "c271d9ed4e12763d14e6955c356ae2763bf2e3a2"
}

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