@deep-foundation/deeplinks
Version:
[](https://www.npmjs.com/package/@deep-foundation/deeplinks) [](https://gitpod.io/#https://github.com/deep-fo
874 lines • 103 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
import { Observable, gql, useApolloClient, useQuery, useSubscription } from '@apollo/client/index.js';
import { generateApolloClient } from '@deep-foundation/hasura/client.js';
import { useLocalStore } from '@deep-foundation/store/local.js';
import atob from 'atob';
import React, { createContext, memo, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
import { corePckg } from './core.js';
import { debug } from './debug.js';
import { deleteMutation, generateQuery, generateQueryData, generateSerial, insertMutation, updateMutation } from './gql/index.js';
import { MinilinkCollection, MinilinksLink, useMinilinks, useMinilinksApply, useMinilinksId, useMinilinksQuery, useMinilinksSubscription } from './minilinks.js';
import { awaitPromise } from './promise.js';
import { useTokenController } from './react-token.js';
import { reserve } from './reserve.js';
import { Traveler as NativeTraveler } from './traveler.js';
import { evalClientHandler } from './client-handler.js';
import { Packager } from './packager.js';
import isEqual from 'lodash/isEqual.js';
import _ from 'lodash';
import isNaN from 'lodash/isNaN.js';
import JSON5 from 'json5';
import axios from 'axios';
import EventEmitter from 'events';
import { matchSorter } from 'match-sorter';
import { useDebounce } from '@react-hook/debounce';
import { Packages } from './packages.js';
import { serializeError } from 'serialize-error';
import { ApolloClientTokenizedProvider } from '@deep-foundation/react-hasura/apollo-client-tokenized-provider.js';
const moduleLog = debug.extend('client');
const log = debug.extend('log');
const error = debug.extend('error');
const corePckgIds = {};
corePckg.data.filter(l => !!l.type).forEach((l, i) => {
corePckgIds[l.id] = i + 1;
});
export const random = () => Math.random().toString(36).slice(2, 7);
export function upload(linkId, file, deep) {
return __awaiter(this, void 0, void 0, function* () {
var formData = new FormData();
formData.append("file", file);
console.log('upload formData', formData);
yield axios.post(`http${deep.client.ssl ? 's' : ''}://${deep.client.path.slice(0, -4)}/file?linkId=${linkId}&token=${deep.token}`, formData, {
headers: {
'linkId': linkId,
"Authorization": `Bearer ${deep.token}`,
},
});
});
}
export const _ids = {
'@deep-foundation/core': corePckgIds,
};
export const _serialize = {
links: {
returning: 'id type_id from_id to_id value',
virtualize: {
id: ['id', '_id'],
type_id: ['type_id', '_type_id'],
from_id: ['from_id', '_from_id'],
to_id: ['to_id', '_to_id'],
},
fields: {
id: 'number',
from_id: 'number',
to_id: 'number',
type_id: 'number',
_id: 'number',
_from_id: 'number',
_to_id: 'number',
_type_id: 'number',
},
relations: {
from: 'links',
to: 'links',
type: 'links',
in: 'links',
out: 'links',
typed: 'links',
selected: 'selector',
selectors: 'selector',
value: 'value',
string: 'strings',
number: 'numbers',
object: 'objects',
file: 'files',
can_rule: 'can',
can_action: 'can',
can_object: 'can',
can_subject: 'can',
down: 'tree',
up: 'tree',
tree: 'tree',
root: 'tree',
},
},
selector: {
returning: 'item_id selector_id',
fields: {
item_id: 'number',
selector_id: 'number',
query_id: 'number',
selector_include_id: 'number',
},
relations: {
item: 'links',
selector: 'links',
query: 'links',
}
},
can: {
returning: 'rule_id action_id object_id subject_id',
fields: {
rule_id: 'number',
action_id: 'number',
object_id: 'number',
subject_id: 'number',
},
relations: {
rule: 'links',
action: 'links',
object: 'links',
subject: 'links',
}
},
tree: {
returning: 'id link_id tree_id root_id parent_id depth position_id',
fields: {
id: 'number',
link_id: 'number',
tree_id: 'number',
root_id: 'number',
parent_id: 'number',
depth: 'number',
position_id: 'string',
},
relations: {
link: 'links',
tree: 'links',
root: 'links',
parent: 'links',
by_link: 'tree',
by_tree: 'tree',
by_root: 'tree',
by_parent: 'tree',
by_position: 'tree',
}
},
value: {
returning: 'id link_id value',
fields: {
id: 'number',
link_id: 'number',
value: 'value',
},
relations: {
link: 'links',
},
},
strings: {
returning: 'id link_id value',
fields: {
id: 'number',
link_id: 'number',
value: 'string',
},
relations: {
link: 'links',
},
},
numbers: {
returning: 'id link_id value',
fields: {
id: 'number',
link_id: 'number',
value: 'number',
},
relations: {
link: 'links',
},
},
objects: {
returning: 'id link_id value',
fields: {
id: 'number',
link_id: 'number',
value: 'object',
},
relations: {
link: 'links',
},
},
files: {
returning: 'id link_id mimeType name size',
fields: {
bucketId: 'string',
etag: 'string',
id: 'number',
isUploaded: 'boolean',
link_id: 'number',
mimeType: 'string',
name: 'string',
size: 'number',
},
relations: {
link: 'links',
},
},
handlers: {
returning: 'dist_id src_id handler_id execution_provider_id isolation_provider_id',
fields: {
dist_id: 'number',
execution_provider_id: 'number',
handler_id: 'number',
isolation_provider_id: 'number',
src_id: 'number',
},
relations: {
link: 'links',
dist: 'links',
execution_provider: 'links',
handler: 'links',
isolation_provider: 'links',
src: 'links',
},
},
};
_serialize.strings = _serialize.value;
_serialize.numbers = _serialize.value;
_serialize.objects = _serialize.value;
export const _boolExpFields = {
_and: true,
_not: true,
_or: true,
};
export const pathToWhere = (start, ...path) => {
var _a, _b;
const pckg = typeof (start) === 'string' ? { type_id: (_a = _ids === null || _ids === void 0 ? void 0 : _ids['@deep-foundation/core']) === null || _a === void 0 ? void 0 : _a.Package, value: start } : { id: start };
let where = pckg;
for (let p = 0; p < path.length; p++) {
const item = path[p];
if (typeof (item) !== 'boolean') {
const nextWhere = { in: { type_id: (_b = _ids === null || _ids === void 0 ? void 0 : _ids['@deep-foundation/core']) === null || _b === void 0 ? void 0 : _b.Contain, value: item, from: where } };
where = nextWhere;
}
}
return where;
};
export const serializeWhere = (exp, env = 'links', unvertualizeId = defaultUnvertualizeId, globalExp) => {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _p, _r, _s;
if (Object.prototype.toString.call(exp) === '[object Array]')
return exp.map((e) => serializeWhere(e, env, unvertualizeId, globalExp));
else if (typeof (exp) === 'object') {
const keys = Object.keys(exp);
const result = {};
for (let k = 0; k < keys.length; k++) {
let key = keys[k];
let value = exp[key];
let type = typeof (value);
if (typeof (value) === 'undefined')
throw new Error(`${key} === undefined${globalExp ? `in exp ${JSON.stringify(globalExp)}` : ''}`);
let setted = false;
key = addIdsToRelationsIfSimple(exp, key, env);
if (env === 'links' && key === 'value' && (type === 'string' || type === 'number')) {
key = type;
}
if (env === 'links' && (key === 'string' || key === 'number') && (type === key)) {
value = { value: { _eq: value } };
}
if (((_b = (_a = _serialize === null || _serialize === void 0 ? void 0 : _serialize[env]) === null || _a === void 0 ? void 0 : _a.fields) === null || _b === void 0 ? void 0 : _b[key]) && (type === 'string' || type === 'number')) {
value = { _eq: key.slice(-3) === '_id' ? unvertualizeId(value) : value };
}
const is_id_field = !!~['type_id', 'from_id', 'to_id'].indexOf(key);
if (env === 'links') {
if (key === 'relation') {
setted = result[key] = value;
}
else if (!_boolExpFields[key] && Object.prototype.toString.call(value) === '[object Array]') {
if ((_d = (_c = _serialize === null || _serialize === void 0 ? void 0 : _serialize[env]) === null || _c === void 0 ? void 0 : _c.relations) === null || _d === void 0 ? void 0 : _d[key]) {
setted = result[key] = serializeWhere(value, (_f = (_e = _serialize === null || _serialize === void 0 ? void 0 : _serialize[env]) === null || _e === void 0 ? void 0 : _e.relations) === null || _f === void 0 ? void 0 : _f[key], unvertualizeId, globalExp);
}
else {
setted = result[key] = serializeWhere(pathToWhere(...value), 'links', unvertualizeId, globalExp);
}
}
}
else if (env === 'tree') {
if (!_boolExpFields[key] && Object.prototype.toString.call(value) === '[object Array]') {
setted = result[key] = serializeWhere(pathToWhere(...value), 'links', unvertualizeId, globalExp);
}
}
if (key === 'return') {
setted = result[key] = {};
for (let r in value) {
const relation = (_g = value[r]) === null || _g === void 0 ? void 0 : _g.relation;
if ((_j = (_h = _serialize === null || _serialize === void 0 ? void 0 : _serialize[env]) === null || _h === void 0 ? void 0 : _h.relations) === null || _j === void 0 ? void 0 : _j[relation])
result[key][r] = serializeWhere(value[r], ((_l = (_k = _serialize === null || _serialize === void 0 ? void 0 : _serialize[env]) === null || _k === void 0 ? void 0 : _k.relations) === null || _l === void 0 ? void 0 : _l[relation]) || env, unvertualizeId, globalExp);
}
}
if (type === 'object' && (value === null || value === void 0 ? void 0 : value.hasOwnProperty('_type_of')) && ((env === 'links' && (is_id_field || key === 'id')) ||
(env === 'selector' && key === 'item_id') ||
(env === 'can' && !!~['rule_id', 'action_id', 'subject_id', 'object_id',].indexOf(key)) ||
(env === 'tree' && !!~['link_id', 'tree_id', 'root_id', 'parent_id'].indexOf(key)) ||
(env === 'value' && key === 'link_id'))) {
const _temp = setted = { _by_item: { path_item_id: { _eq: unvertualizeId(value._type_of) }, group_id: { _eq: _ids['@deep-foundation/core'].typesTree } } };
if (key === 'id') {
result._and = result._and ? [...result._and, _temp] : [_temp];
}
else {
result[key.slice(0, -3)] = _temp;
}
}
else if (type === 'object' && (value === null || value === void 0 ? void 0 : value.hasOwnProperty('_id')) && ((env === 'links' && (is_id_field || key === 'id')) ||
(env === 'selector' && key === 'item_id') ||
(env === 'can' && !!~['rule_id', 'action_id', 'subject_id', 'object_id',].indexOf(key)) ||
(env === 'tree' && !!~['link_id', 'tree_id', 'root_id', 'parent_id'].indexOf(key)) ||
(env === 'value' && key === 'link_id')) && Object.prototype.toString.call(value._id) === '[object Array]' && value._id.length >= 1) {
const root = value._id[0];
const _temp = setted = serializeWhere(pathToWhere(typeof (root) === 'number' ? unvertualizeId(root) : root, ...value._id.slice(1)), 'links', unvertualizeId, globalExp);
if (key === 'id') {
result._and = result._and ? [...result._and, _temp] : [_temp];
}
else {
result[key.slice(0, -3)] = _temp;
}
}
if (!setted) {
const _temp = (_boolExpFields[key]) ? (serializeWhere(value, env, unvertualizeId, globalExp)) : ((_p = (_m = _serialize === null || _serialize === void 0 ? void 0 : _serialize[env]) === null || _m === void 0 ? void 0 : _m.relations) === null || _p === void 0 ? void 0 : _p[key]) ? (serializeWhere(value, (_s = (_r = _serialize === null || _serialize === void 0 ? void 0 : _serialize[env]) === null || _r === void 0 ? void 0 : _r.relations) === null || _s === void 0 ? void 0 : _s[key], unvertualizeId, globalExp)) : (value);
if (key === '_and')
result._and ? result._and.push(..._temp) : result._and = _temp;
else
result[key] = _temp;
}
}
return result;
}
else {
if (typeof (exp) === 'undefined')
throw new Error('undefined in query');
return exp;
}
};
const defaultUnvertualizeId = (id) => id;
export const serializeQuery = (exp, env = 'links', unvertualizeId = defaultUnvertualizeId) => {
const { limit, order_by, offset, distinct_on } = exp, where = __rest(exp, ["limit", "order_by", "offset", "distinct_on"]);
const result = { where: typeof (exp) === 'object' ? Object.prototype.toString.call(exp) === '[object Array]' ? { id: { _in: exp.map(id => unvertualizeId(id)) } } : serializeWhere(where, env, unvertualizeId, exp) : { id: { _eq: unvertualizeId(exp) } } };
if (limit)
result.limit = limit;
if (order_by)
result.order_by = order_by;
if (offset)
result.offset = offset;
if (distinct_on)
result.distinct_on = distinct_on;
return result;
};
export function parseJwt(token) {
var base64Url = token.split('.')[1];
var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
var jsonPayload = decodeURIComponent(atob(base64).split('').map(function (c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
const parsed = JSON.parse(jsonPayload);
const _a = parsed['https://hasura.io/jwt/claims'] || {}, { 'x-hasura-allowed-roles': roles, 'x-hasura-default-role': role, 'x-hasura-user-id': userId } = _a, other = __rest(_a, ['x-hasura-allowed-roles', 'x-hasura-default-role', 'x-hasura-user-id']);
return Object.assign({ userId: +userId, role, roles }, other);
}
;
;
;
export function addIdsToRelationsIfSimple(exp, key, env) {
var _a, _b;
const type = typeof (exp[key]);
if (((_b = (_a = _serialize === null || _serialize === void 0 ? void 0 : _serialize[env]) === null || _a === void 0 ? void 0 : _a.relations) === null || _b === void 0 ? void 0 : _b[key]) === 'links' && (type === 'string' || type === 'number')) {
if (exp[`${key}_id`])
throw new Error(`Cant work with ${key} and ${key}_id in one link`);
return key + '_id';
}
return key;
}
export function checkAndFillShorts(obj, table, containerId, Contain, field) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
if (obj.hasOwnProperty('containerId') && !obj.containerId && obj.containerId != 0) {
throw new Error(`containerId is undefined`);
}
const cId = obj.containerId || containerId;
for (var _key in obj) {
let key = _key;
const type = obj[key];
key = addIdsToRelationsIfSimple(obj, key, table);
if (!obj.hasOwnProperty(key))
continue;
if ((typeof obj[key]) == 'object' && obj[key] !== null) {
if (typeof obj[key] === 'object' && key === 'object' && ((_b = (_a = obj[key]) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.value) === undefined) {
obj[key] = { data: { value: obj[key] } };
continue;
}
if (typeof obj[key] === 'object' && (key === 'to' || key === 'from' || key === 'in' || key === 'out' || key === 'typed' || key === 'type') && ((_c = obj[key]) === null || _c === void 0 ? void 0 : _c.data) === undefined)
obj[key] = { data: obj[key] };
checkAndFillShorts(obj[key], ((_e = (_d = _serialize[table]) === null || _d === void 0 ? void 0 : _d.relations) === null || _e === void 0 ? void 0 : _e[key]) || table, cId, Contain, key);
}
else if (key === 'string' && typeof obj[key] === 'string' || key === 'number' && typeof obj[key] === 'number')
obj[key] = { data: { value: obj[key] } };
}
if (cId && !Array.isArray(obj) && !obj.data && table === 'links' && ((!field || [
'to', 'from', 'in', 'out', 'type', 'typed'
].includes(field)) || obj.type_id || obj.type)) {
obj.in = obj.in || {};
obj.in.data = ((_f = obj === null || obj === void 0 ? void 0 : obj.in) === null || _f === void 0 ? void 0 : _f.data) ? Array.isArray((_g = obj === null || obj === void 0 ? void 0 : obj.in) === null || _g === void 0 ? void 0 : _g.data) ? (_h = obj === null || obj === void 0 ? void 0 : obj.in) === null || _h === void 0 ? void 0 : _h.data : [(_j = obj === null || obj === void 0 ? void 0 : obj.in) === null || _j === void 0 ? void 0 : _j.data] : [];
obj.in.data.push(Object.assign({ type_id: Contain, from_id: cId }, (typeof (obj.name) === 'string' ? { string: { data: { value: obj.name } } } : {})));
}
delete obj.name;
delete obj.containerId;
}
export function convertDeepInsertToMinilinksApplyAndPatchVirtualIds(deep, objects, table, result = [], errors, patch = {}) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _p, _r, _s, _t, _u, _v, _w, _x;
const levelIds = [];
if (table === 'links') {
for (let i = 0; i < objects.length; i++) {
const o = objects[i];
let id = o.id;
if (!id) {
id = deep.minilinks.virtualCounter--;
(_b = (_a = deep.minilinks) === null || _a === void 0 ? void 0 : _a.byId[id]) === null || _b === void 0 ? void 0 : _b._id = apply;
}
levelIds.push(id);
const patchRelationIds = {};
if (o === null || o === void 0 ? void 0 : o.from) {
const { objects: objs, levelIds } = convertDeepInsertToMinilinksApplyAndPatchVirtualIds(deep, [(_c = o === null || o === void 0 ? void 0 : o.from) === null || _c === void 0 ? void 0 : _c.data], table, result, errors);
o.from.data = objs;
patchRelationIds.from_id = levelIds[0];
}
if (o === null || o === void 0 ? void 0 : o.to) {
const { objects: objs, levelIds } = convertDeepInsertToMinilinksApplyAndPatchVirtualIds(deep, [(_d = o === null || o === void 0 ? void 0 : o.to) === null || _d === void 0 ? void 0 : _d.data], table, result, errors);
o.to.data = objs;
patchRelationIds.to_id = levelIds[0];
}
if (o === null || o === void 0 ? void 0 : o.type) {
const { objects: objs, levelIds } = convertDeepInsertToMinilinksApplyAndPatchVirtualIds(deep, [(_e = o === null || o === void 0 ? void 0 : o.type) === null || _e === void 0 ? void 0 : _e.data], table, result, errors);
o.type.data = objs;
patchRelationIds.type_id = levelIds[0];
}
if (o === null || o === void 0 ? void 0 : o.out) {
const { objects: objs, levelIds } = convertDeepInsertToMinilinksApplyAndPatchVirtualIds(deep, (((_g = (_f = o === null || o === void 0 ? void 0 : o.out) === null || _f === void 0 ? void 0 : _f.data) === null || _g === void 0 ? void 0 : _g.length) ? (_h = o === null || o === void 0 ? void 0 : o.out) === null || _h === void 0 ? void 0 : _h.data : [(_j = o === null || o === void 0 ? void 0 : o.out) === null || _j === void 0 ? void 0 : _j.data]), table, result, errors, { from_id: id });
o.out.data = objs;
}
if (o === null || o === void 0 ? void 0 : o.in) {
const { objects: objs, levelIds } = convertDeepInsertToMinilinksApplyAndPatchVirtualIds(deep, (((_l = (_k = o === null || o === void 0 ? void 0 : o.in) === null || _k === void 0 ? void 0 : _k.data) === null || _l === void 0 ? void 0 : _l.length) ? (_m = o === null || o === void 0 ? void 0 : o.in) === null || _m === void 0 ? void 0 : _m.data : [(_p = o === null || o === void 0 ? void 0 : o.in) === null || _p === void 0 ? void 0 : _p.data]), table, result, errors, { to_id: id });
o.in.data = objs;
}
if (o === null || o === void 0 ? void 0 : o.types) {
const { objects: objs, levelIds } = convertDeepInsertToMinilinksApplyAndPatchVirtualIds(deep, (((_s = (_r = o === null || o === void 0 ? void 0 : o.types) === null || _r === void 0 ? void 0 : _r.data) === null || _s === void 0 ? void 0 : _s.length) ? (_t = o === null || o === void 0 ? void 0 : o.types) === null || _t === void 0 ? void 0 : _t.data : [(_u = o === null || o === void 0 ? void 0 : o.types) === null || _u === void 0 ? void 0 : _u.data]), table, result, errors, { type_id: id });
o.types.data = objs;
}
if (typeof (o.from_id) === 'number' || typeof (o.from_id) === 'string') {
if (o.from_id < 0) {
if (deep.minilinks.virtual[o.from_id])
o.from_id = deep.minilinks.virtual[o.from_id];
else
errors.push(`.from_id=${o.from_id} can't be devertualized, not exists in minilinks.virtual[${o.from_id}]`);
}
}
if (typeof (o.to_id) === 'number' || typeof (o.to_id) === 'string') {
if (o.to_id < 0) {
if (deep.minilinks.virtual[o.to_id])
o.to_id = deep.minilinks.virtual[o.to_id];
else
errors.push(`.to_id=${o.to_id} can't be devertualized, not exists in minilinks.virtual[${o.to_id}]`);
}
}
if (typeof (o.type_id) === 'number' || typeof (o.type_id) === 'string') {
if (o.type_id < 0) {
if (deep.minilinks.virtual[o.type_id])
o.type_id = deep.minilinks.virtual[o.type_id];
else
errors.push(`.type_id=${o.type_id} can't be devertualized, not exists in minilinks.virtual[${o.type_id}]`);
}
}
result.push(Object.assign(Object.assign({ id: id, from_id: o.from_id, to_id: o.to_id, type_id: o.type_id, value: ((_v = o.string) === null || _v === void 0 ? void 0 : _v.data) || ((_w = o.number) === null || _w === void 0 ? void 0 : _w.data) || ((_x = o.object) === null || _x === void 0 ? void 0 : _x.data) }, patch), patchRelationIds));
}
}
return { objects: objects.length == 1 ? objects[0] : objects, levelIds };
}
export function convertDeepUpdateToMinilinksApply(ml, _exp, _set, table, toUpdate = []) {
if (table === 'links') {
try {
const founded = ml.query(_exp);
for (let f of founded) {
toUpdate.push(Object.assign({ id: f.id, from_id: f.from_id, to_id: f.to_id, type_id: f.type_id, value: f.value }, _set));
}
}
catch (e) { }
}
else if (table === 'strings' || table === 'numbers' || table === 'objects') {
const key = table.slice(0, -1);
const founded = ml.query({ [key]: _exp });
for (let f of founded) {
toUpdate.push({
id: f.id, from_id: f.from_id, to_id: f.to_id, type_id: f.type_id,
value: Object.assign(Object.assign({}, f === null || f === void 0 ? void 0 : f.value), { value: _set.value }),
});
}
}
}
export function convertDeepDeleteToMinilinksApply(ml, _exp, table, toDelete = [], toUpdate = []) {
if (table === 'links') {
try {
const founded = ml.query(_exp);
toDelete.push(...founded.map(l => l.id));
}
catch (e) { }
}
else if (table === 'strings' || table === 'numbers' || table === 'objects') {
const key = table.slice(0, -1);
const founded = ml.query({ [key]: _exp });
toUpdate.push(...founded.map(o => ({
id: o.id, from_id: o.from_id, to_id: o.to_id, type_id: o.type_id,
})));
}
}
export class DeepClient {
_silent(options = {}) {
return typeof (options.silent) === 'boolean' ? options.silent : this.silent;
}
constructor(options) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
this.useDeep = useDeep;
this.DeepProvider = DeepProvider;
this.DeepContext = DeepContext;
this.DeepClient = DeepClient;
this.gql = gql;
this.namespace = (options === null || options === void 0 ? void 0 : options.namespace) || random();
this.emitter = new EventEmitter();
this.local = typeof (options === null || options === void 0 ? void 0 : options.local) === 'boolean' ? options === null || options === void 0 ? void 0 : options.local : true;
this.remote = typeof (options === null || options === void 0 ? void 0 : options.remote) === 'boolean' ? options === null || options === void 0 ? void 0 : options.remote : true;
if ((options === null || options === void 0 ? void 0 : options.needConnection) != false) {
this.deep = options === null || options === void 0 ? void 0 : options.deep;
this.apolloClient = options === null || options === void 0 ? void 0 : options.apolloClient;
this.token = options === null || options === void 0 ? void 0 : options.token;
this.secret = options === null || options === void 0 ? void 0 : options.secret;
this.ssl = (options === null || options === void 0 ? void 0 : options.ssl) || false;
this.ws = options === null || options === void 0 ? void 0 : options.ws;
this.client = this.apolloClient;
this.table = (options === null || options === void 0 ? void 0 : options.table) || 'links';
if ((this.deep && !this.apolloClient) || (!!options.path)) {
const token = this.token || ((_a = this === null || this === void 0 ? void 0 : this.deep) === null || _a === void 0 ? void 0 : _a.token);
const secret = this.secret || ((_b = this === null || this === void 0 ? void 0 : this.deep) === null || _b === void 0 ? void 0 : _b.secret);
const ssl = this.ssl || ((_c = this === null || this === void 0 ? void 0 : this.deep) === null || _c === void 0 ? void 0 : _c.ssl);
const ws = this.ws || ((_d = this === null || this === void 0 ? void 0 : this.deep) === null || _d === void 0 ? void 0 : _d.ws);
this.apolloClient = generateApolloClient({
path: (options.path || ((_f = (_e = this.deep) === null || _e === void 0 ? void 0 : _e.apolloClient) === null || _f === void 0 ? void 0 : _f.path) || '').replace(/(^\w+:|^)\/\//, ''),
ssl: ssl || ((_h = (_g = this.deep) === null || _g === void 0 ? void 0 : _g.apolloClient) === null || _h === void 0 ? void 0 : _h.ssl),
token: token,
secret: secret,
ws: ws,
});
}
if (!this.apolloClient)
throw new Error('apolloClient is invalid or not provided');
if (this.token) {
const decoded = parseJwt(this.token);
const linkId = decoded === null || decoded === void 0 ? void 0 : decoded.userId;
if (!linkId) {
throw new Error(`Unable to parse linkId from jwt token.`);
}
if (options.linkId && options.linkId !== linkId) {
throw new Error(`linkId (${linkId}) parsed from jwt token is not the same as linkId passed via options (${options.linkId}).`);
}
this.linkId = linkId;
}
else {
this.linkId = options.linkId;
}
}
this.unvertualizeId = (id) => {
return this.minilinks.virtual.hasOwnProperty(id) ? this.minilinks.virtual[id] : id;
};
this.linksSelectReturning = options.selectReturning || _serialize.links.returning;
this.selectReturning = options.selectReturning || this.linksSelectReturning;
this.selectorsSelectReturning = options.selectorsSelectReturning || _serialize.selector.returning;
this.canSelectReturning = options.canSelectReturning || _serialize.can.returning;
this.treeSelectReturning = options.treeSelectReturning || _serialize.tree.returning;
this.valuesSelectReturning = options.valuesSelectReturning || _serialize.value.returning;
this.filesSelectReturning = options.filesSelectReturning || _serialize.files.returning;
this.handlersSelectReturning = options.handlersSelectReturning || _serialize.handlers.returning;
this.insertReturning = options.insertReturning || 'id';
this.updateReturning = options.updateReturning || 'id';
this.deleteReturning = options.deleteReturning || 'id';
this.defaultSelectName = options.defaultSelectName || 'SELECT';
this.defaultInsertName = options.defaultInsertName || 'INSERT';
this.defaultUpdateName = options.defaultUpdateName || 'UPDATE';
this.defaultDeleteName = options.defaultDeleteName || 'DELETE';
this.silent = options.silent || false;
this.unsafe = options.unsafe || {};
this.handleAuth = (options === null || options === void 0 ? void 0 : options.handleAuth) || ((_j = options === null || options === void 0 ? void 0 : options.deep) === null || _j === void 0 ? void 0 : _j.handleAuth);
this.handleOperation = (options === null || options === void 0 ? void 0 : options.handleOperation) || ((_k = options === null || options === void 0 ? void 0 : options.deep) === null || _k === void 0 ? void 0 : _k.handleOperation);
this.minilinks = options.minilinks || new MinilinkCollection();
this.ml = this.minilinks;
if (!this.ml.deep)
this.ml.deep = this;
this._generateHooks(this);
}
_generateHooks(deep) {
this.useDeepId = (start, ...path) => _useDeepId(deep, start, ...path);
this.useId = this.useDeepId;
this.useDeepSubscription = (query, options) => useDeepSubscription(query, Object.assign(Object.assign({}, (options || {})), { deep: deep }));
this.useSubscription = useDeepSubscription;
this.useDeepQuery = (query, options) => useDeepQuery(query, Object.assign(Object.assign({}, (options || {})), { deep: deep }));
this.useQuery = useDeepQuery;
this.useLink = useLink;
this.useLinks = useLinks;
this.useMinilinksQuery = (query, options) => useMinilinksQuery(deep.minilinks, query, options);
this.useMinilinksSubscription = (query, options) => useMinilinksSubscription(deep.minilinks, query, options);
this.useMinilinksId = (start, ...path) => useMinilinksId(deep.minilinks, start, ...path);
this.useMinilinksApply = (data, name) => useMinilinksApply(deep.minilinks, name, data);
this.useLocalQuery = this.useMinilinksQuery;
this.useLocalSubscription = this.useMinilinksSubscription;
this.useLocalId = this.useMinilinksId;
this.useLocalApply = this.useMinilinksApply;
this.useSearch = useSearch;
this.useCan = useCan;
this.Subscription = Subscription;
this.Query = Query;
}
stringify(any) {
if (typeof (any) === 'object' && typeof (any === null || any === void 0 ? void 0 : any.message) === 'string') {
return serializeError(any);
}
else if (typeof (any) === 'string') {
let json;
try {
json = JSON5.parse(any);
}
catch (e) { }
return json ? JSON.stringify(json, null, 2) : any.toString();
}
else if (typeof (any) === 'object') {
return JSON.stringify(any, null, 2);
}
return any;
}
serializeQuery(exp, env) { return serializeQuery(exp, env, this.unvertualizeId); }
serializeWhere(exp, env) { return serializeWhere(exp, env, this.unvertualizeId, exp); }
_generateQuery(exp, options) {
var _a;
const query = serializeQuery(exp, (options === null || options === void 0 ? void 0 : options.table) || 'links', this.unvertualizeId);
const table = (options === null || options === void 0 ? void 0 : options.table) || this.table;
const returning = (options === null || options === void 0 ? void 0 : options.returning) || ((_a = _serialize === null || _serialize === void 0 ? void 0 : _serialize[table]) === null || _a === void 0 ? void 0 : _a.returning) || 'id';
const tableNamePostfix = options === null || options === void 0 ? void 0 : options.tableNamePostfix;
const aggregate = options === null || options === void 0 ? void 0 : options.aggregate;
const variables = options === null || options === void 0 ? void 0 : options.variables;
const name = (options === null || options === void 0 ? void 0 : options.name) || this.defaultSelectName;
const queryData = generateQueryData({
tableName: table,
tableNamePostfix: tableNamePostfix || aggregate ? '_aggregate' : '',
returning: aggregate ? `aggregate { ${aggregate} }` : returning,
variables: Object.assign(Object.assign({}, variables), query),
});
return {
query: generateQuery({
operation: (options === null || options === void 0 ? void 0 : options.subscription) ? 'subscription' : 'query',
queries: [
queryData,
],
name: name,
}),
queryData,
};
}
_generateResult(exp, options, data) {
return data;
}
one(exp) {
var _a, _b;
return __awaiter(this, void 0, void 0, function* () {
return (_b = (_a = (yield this.select(exp))) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b[0];
});
}
select(exp, options) {
var _a, _b, _c, _d, _e, _f;
return __awaiter(this, void 0, void 0, function* () {
if (!exp)
return { error: { message: '!exp' }, data: undefined, loading: false, networkStatus: undefined };
const aggregate = options === null || options === void 0 ? void 0 : options.aggregate;
const name = random();
this.emitter.emit('select.before', { deep: this, name, query: exp, options, remote: true, local: false });
const queryData = this._generateQuery(exp, options);
try {
const q = yield this.apolloClient.query({ query: queryData.query.query, variables: (_a = queryData === null || queryData === void 0 ? void 0 : queryData.query) === null || _a === void 0 ? void 0 : _a.variables });
const results = Object.assign(Object.assign({}, q), { data: aggregate ? (_e = (_d = (_c = (_b = (q)) === null || _b === void 0 ? void 0 : _b.data) === null || _c === void 0 ? void 0 : _c.q0) === null || _d === void 0 ? void 0 : _d.aggregate) === null || _e === void 0 ? void 0 : _e[aggregate] : yield this._generateResult(exp, options, (_f = q === null || q === void 0 ? void 0 : q.data) === null || _f === void 0 ? void 0 : _f.q0), return: exp === null || exp === void 0 ? void 0 : exp.return, query: exp });
if (options === null || options === void 0 ? void 0 : options.apply) {
results.originalData = results.data;
const { data: localData, plainLinks } = this.minilinks.apply(results.data, options.apply);
results.data = localData;
results.plainLinks = plainLinks;
this.emitter.emit('select', { deep: this, name, query: exp, options, remoteQuery: queryData, remoteData: results.data, localData: results.data, plainLinks, remote: true, local: false, error: results.error });
}
else {
this.emitter.emit('select', { deep: this, name, query: exp, options, remoteQuery: queryData, remoteData: results.data, remote: true, local: false, error: results.error });
}
return results;
}
catch (e) {
this.emitter.emit('select', { deep: this, name, query: exp, options, remoteQuery: queryData, error: e, remote: true, local: false });
throw new Error(`DeepClient Select Error: ${e.message}`, { cause: e });
}
});
}
;
subscribe(exp, options) {
var _a;
if (!exp)
return new Observable((observer) => observer.error('!exp'));
const aggregate = options === null || options === void 0 ? void 0 : options.aggregate;
const queryData = this._generateQuery(exp, Object.assign(Object.assign({}, options), { subscription: true }));
const name = random();
this.emitter.emit('subscribe.before', { deep: this, name, query: exp, options, remote: true, local: false });
try {
const apolloObservable = this.apolloClient.subscribe({ query: queryData.query.query, variables: (_a = queryData === null || queryData === void 0 ? void 0 : queryData.query) === null || _a === void 0 ? void 0 : _a.variables });
const observable = new Observable((observer) => {
observer.name = name;
const subscription = apolloObservable.subscribe({
next: (data) => __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c, _d;
const results = {
data: (aggregate ? (_c = (_b = (_a = data === null || data === void 0 ? void 0 : data.data) === null || _a === void 0 ? void 0 : _a.q0) === null || _b === void 0 ? void 0 : _b.aggregate) === null || _c === void 0 ? void 0 : _c[aggregate] : (yield this._generateResult(exp, options, (_d = data === null || data === void 0 ? void 0 : data.data) === null || _d === void 0 ? void 0 : _d.q0))),
return: exp === null || exp === void 0 ? void 0 : exp.return,
query: exp,
};
if (options === null || options === void 0 ? void 0 : options.apply) {
results.originalData = results.data;
const { data: localData, plainLinks } = this.minilinks.apply(results.data, options.apply);
results.data = localData;
results.plainLinks = plainLinks;
this.emitter.emit('subscribe', { deep: this, name, query: exp, options, remoteQuery: queryData, remoteData: results.data, localData: results.data, plainLinks, remote: true, local: false, error: results.error });
}
else {
this.emitter.emit('subscribe', { deep: this, name, query: exp, options, remoteQuery: queryData, remoteData: results.data, remote: true, local: false, error: results.error });
}
observer.next(results);
}),
error: (error) => {
this.emitter.emit('subscribe', { deep: this, name, query: exp, options, remoteQuery: queryData, error, remote: true, local: false });
observer.error(error);
},
});
return () => subscription.unsubscribe();
});
return observable;
}
catch (e) {
throw new Error(`DeepClient Subscription Error: ${e.message}`, { cause: e });
}
}
;
insert(objects, options) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _p, _r, _s, _t, _u, _v;
return __awaiter(this, void 0, void 0, function* () {
const o = Object.assign({ local: this.local, remote: this.remote }, options);
const { local, remote } = o;
const _name = random();
this.emitter.emit('insert.before', { deep: this, name: _name, value: objects, options, remote, local });
const table = (options === null || options === void 0 ? void 0 : options.table) || this.table;
const returning = (options === null || options === void 0 ? void 0 : options.returning) || this.insertReturning;
const variables = options === null || options === void 0 ? void 0 : options.variables;
const name = (options === null || options === void 0 ? void 0 : options.name) || this.defaultInsertName;
let q = {};
const containerId = options === null || options === void 0 ? void 0 : options.containerId;
let _objects = Object.prototype.toString.call(objects) === '[object Array]' ? objects : [objects];
checkAndFillShorts(_objects, table, containerId, _ids['@deep-foundation/core']['Contain']);
this.handleOperation && this.handleOperation('insert', null, _objects, o);
let file;
if ((_a = _objects === null || _objects === void 0 ? void 0 : _objects[0]) === null || _a === void 0 ? void 0 : _a.file) {
if ((_objects === null || _objects === void 0 ? void 0 : _objects.length) != 1)
throw new Error('Cannot insert multiple files at once');
if (table != 'links')
throw new Error('Cannot insert file if table is not links');
file = (_b = _objects === null || _objects === void 0 ? void 0 : _objects[0]) === null || _b === void 0 ? void 0 : _b.file;
(_c = _objects === null || _objects === void 0 ? void 0 : _objects[0]) === null || _c === void 0 ? true : delete _c.file;
if (typeof (file) !== 'string' && !(file instanceof Blob))
throw new Error('File must be a string or Blob');
}
const toApply = [];
if (this.minilinks && local !== false) {
const errors = [];
const { objects: __objects } = convertDeepInsertToMinilinksApplyAndPatchVirtualIds(this, _objects, table, toApply, errors);
_objects = __objects;
if (errors.length)
console.log('convertDeepInsertToMinilinksApplyAndPatchVirtualIds', 'errors', errors);
this.minilinks.add(toApply);
}
let mutate;
if (remote !== false) {
try {
mutate = generateSerial({
actions: [insertMutation(table, Object.assign(Object.assign({}, variables), { objects: _objects }), { tableName: table, operation: 'insert', returning })],
name: name,
});
q = yield this.apolloClient.mutate(mutate);
}
catch (e) {
const sqlError = (_g = (_f = (_e = (_d = e === null || e === void 0 ? void 0 : e.graphQLErrors) === null || _d === void 0 ? void 0 : _d[0]) === null || _e === void 0 ? void 0 : _e.extensions) === null || _f === void 0 ? void 0 : _f.internal) === null || _g === void 0 ? void 0 : _g.error;
if (sqlError === null || sqlError === void 0 ? void 0 : sqlError.message)
e.message = sqlError.message;
if (!this._silent(options))
throw new Error(`DeepClient Insert Error: ${e.message}`, { cause: e });
this.emitter.emit('insert', { deep: this, name: _name, value: objects, options, remoteQuery: mutate, file, error: e, remote, local });
return Object.assign(Object.assign({}, q), { data: (_k = (_j = (_h = (q)) === null || _h === void 0 ? void 0 : _h.data) === null || _j === void 0 ? void 0 : _j.m0) === null || _k === void 0 ? void 0 : _k.returning, error: e });
}
if (file) {
const id = (_s = (_r = (_p = (_m = (_l = (q)) === null || _l === void 0 ? void 0 : _l.data) === null || _m === void 0 ? void 0 : _m.m0) === null || _p === void 0 ? void 0 : _p.returning) === null || _r === void 0 ? void 0 : _r[0]) === null || _s === void 0 ? void 0 : _s.id;
if (!id)
throw new Error('Cannot insert file without link');
yield upload(id, file, this);
}
;
}
else {
this.emitter.emit('insert', { deep: this, name: _name, value: objects, options, remoteQuery: mutate, file, remote, local });
return Object.assign(Object.assign({}, q), { data: toApply.map(l => l.id), loading: false });
}
this.emitter.emit('insert', { deep: this, name: _name, value: objects, options, remoteQuery: mutate, remote, local, error: q.error });
return Object.assign(Object.assign({}, q), { data: (_v = (_u = (_t = (q)) === null || _t === void 0 ? void 0 : _t.data) === null || _u === void 0 ? void 0 : _u.m0) === null || _v === void 0 ? void 0 : _v.returning });
});
}
;
update(exp, value, options) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
return __awaiter(this, void 0, void 0, function* () {
const _exp = typeof (exp) === 'number' ? { id: exp } : exp;
if (_exp === null)
return this.insert([value], options);
if (value === null)
return this.delete(_exp, options);
const table = (options === null || options === void 0 ? void 0 : options.table) || this.table;
const _name = random();
if (isEqual(_exp, {}))
throw new Error('exp {} is wrong');
const keys = Object.keys(_exp);
for (let k in keys) {
const key = keys[k];
_exp[addIdsToRelationsIfSimple(_exp, key, table)] = _exp[key];
}
const o = Object.assign({ local: this.local, remote: this.remote }, options);
this.handleOperation && this.handleOperation('update', _exp, value, o);
const { local, remote } = o;
this.emitter.emit('update.before', { deep: this, name: _name, query: _exp, value, options, remote, local });
const query = serializeQuery(_exp, (options === null || options === void 0 ? void 0 : options.table) === this.table || !(options === null || options === void 0 ? void 0 : options.table) ? 'links' : 'value', this.unvertualizeId);
const toUpdate = [];
if (this.minilinks && local !== false) {
convertDeepUpdateToMinilinksApply(this.minilinks, _exp, value, table, toUpdate);
this.minilinks.update(toUpdate);
}
const returning = (options === null || options === void 0 ? void 0 : options.returning) || this.updateReturning;
const variables = options === null || options === void 0 ? void 0 : options.variables;
const name = (options === null || options === void 0 ? void 0 : options.name) || this.defaultUpdateName;
let q;
let m