UNPKG

@deep-foundation/deeplinks

Version:

[![npm](https://img.shields.io/npm/v/@deep-foundation/deeplinks.svg)](https://www.npmjs.com/package/@deep-foundation/deeplinks) [![Gitpod](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/deep-fo

874 lines 103 kB
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