@elysiajs/eden 0.3.0-exp-230223.1133 → 0.3.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,111 @@
1
+ import { E as p } from "./utils-0d2b8b1a.mjs";
2
+ const E = (n, e, t) => {
3
+ if (n.endsWith("/") || (n += "/"), e === "index" && (e = ""), !t || !Object.keys(t).length)
4
+ return `${n}${e}`;
5
+ let s = "";
6
+ for (const [i, r] of Object.entries(t))
7
+ s += `${i}=${r}&`;
8
+ return `${n}${e}?${s.slice(0, -1)}`;
9
+ };
10
+ class N {
11
+ constructor(e) {
12
+ this.ws = new WebSocket(e), this.url = e;
13
+ }
14
+ send(e) {
15
+ return Array.isArray(e) ? (e.forEach((t) => this.send(t)), this) : (this.ws.send(
16
+ typeof e == "object" ? JSON.stringify(e) : e.toString()
17
+ ), this);
18
+ }
19
+ on(e, t, s) {
20
+ return this.addEventListener(e, t, s);
21
+ }
22
+ off(e, t, s) {
23
+ return this.ws.removeEventListener(e, t, s), this;
24
+ }
25
+ addEventListener(e, t, s) {
26
+ return this.ws.addEventListener(
27
+ e,
28
+ (i) => {
29
+ if (e === "message") {
30
+ let r = i.data.toString();
31
+ const o = r.charCodeAt(0);
32
+ if (o === 47 || o === 123)
33
+ try {
34
+ r = JSON.parse(r);
35
+ } catch {
36
+ }
37
+ else
38
+ Number.isNaN(+r) ? r === "true" ? r = !0 : r === "fase" && (r = !1) : r = +r;
39
+ t({
40
+ ...i,
41
+ data: r
42
+ });
43
+ } else
44
+ t(i);
45
+ },
46
+ s
47
+ ), this;
48
+ }
49
+ removeEventListener(e, t, s) {
50
+ return this.off(e, t, s), this;
51
+ }
52
+ close() {
53
+ return this.ws.close(), this;
54
+ }
55
+ }
56
+ const b = (n, e = "", t) => new Proxy(() => {
57
+ }, {
58
+ get(s, i, r) {
59
+ return b(n, `${e}/${i.toString()}`);
60
+ },
61
+ apply(s, i, [
62
+ { $query: r, $fetch: o, $body: w, ...h } = {
63
+ $fetch: void 0,
64
+ $query: void 0,
65
+ $body: void 0
66
+ }
67
+ ] = [{}]) {
68
+ const d = e.lastIndexOf("/"), y = e.slice(d + 1), a = E(n, e.slice(0, d), r);
69
+ if (y === "subscribe")
70
+ return new N(
71
+ a.replace(
72
+ /^([^]+):\/\//,
73
+ a.startsWith("https://") ? "wss://" : "ws://"
74
+ )
75
+ );
76
+ const f = w ?? (Object.keys(h).length ? h : void 0), g = typeof f == "object";
77
+ return fetch(a, {
78
+ method: y,
79
+ body: g ? JSON.stringify(f) : f,
80
+ // ...config.fetch,
81
+ ...o,
82
+ headers: f ? {
83
+ "content-type": g ? "application/json" : "text/plain",
84
+ // ...config.fetch?.headers,
85
+ ...o == null ? void 0 : o.headers
86
+ } : void 0
87
+ }).then(async (c) => {
88
+ var v;
89
+ let l;
90
+ switch ((v = c.headers.get("Content-Type")) == null ? void 0 : v.split(";")[0]) {
91
+ case "application/json":
92
+ l = c.json();
93
+ break;
94
+ default:
95
+ l = c.text().then((u) => Number.isNaN(+u) ? u === "true" ? !0 : u === "false" ? !1 : u : +u);
96
+ }
97
+ return c.status > 300 ? new p(c.status, await l) : l;
98
+ });
99
+ }
100
+ }), x = (n, e = {}) => new Proxy(
101
+ {},
102
+ {
103
+ get(t, s) {
104
+ return b(n, s);
105
+ }
106
+ }
107
+ );
108
+ export {
109
+ N as EdenWS,
110
+ x as edenTreaty
111
+ };
package/dist/types.d.ts CHANGED
@@ -1,89 +1,25 @@
1
- /// <reference types="bun-types" />
2
- import type { Elysia, SCHEMA, TypedRoute, IsPathParameter, EXPOSED } from 'elysia';
3
- import type { EdenWS } from '.';
4
- import { type EdenFetchError } from './utils';
5
- declare type IsAny<T> = unknown extends T ? [T] extends [object] ? true : false : false;
6
- declare type Promisify<T extends (...args: any[]) => any> = T extends (...args: infer Args) => infer Return ? Return extends Promise<any> ? T : (...args: Args) => Promise<Return> : never;
7
- declare type Asynctify<T> = T extends infer Fn extends (...args: any) => any ? Promisify<Fn> : T extends Record<string, any> ? {
8
- [K in keyof T]: EdenFn<T[K]>;
9
- } : never;
10
- declare type EdenFn<T> = T extends {
11
- [EXPOSED]: any;
12
- value: infer Value;
13
- } ? Asynctify<Value> : Asynctify<T>;
14
- declare type CreateEdenFn<Exposed extends Record<string, any>> = EdenFn<Exposed> & {
15
- $set(config: EdenConfig): void;
16
- $clone(config?: EdenConfig): CreateEdenFn<Exposed>;
17
- };
18
- export declare type Eden<App extends Elysia<any>> = App['store'] extends {
19
- [key in typeof SCHEMA]: any;
20
- } ? IsAny<Elysia> extends true ? 'Please install Elysia before using Eden' : UnionToIntersection<CreateEden<App['store'][typeof SCHEMA]>> & {
21
- $fn: CreateEdenFn<App['store'][typeof EXPOSED]>;
22
- } : never;
23
- export interface EdenCall {
24
- [x: string]: any;
25
- $fetch?: RequestInit;
26
- $query?: Record<string, string | boolean | number>;
27
- }
28
- export declare type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
29
- declare type Prettify<T> = {
30
- [K in keyof T]: T[K];
31
- } & {};
32
- declare type TypedRouteToParams<Route extends TypedRoute> = (Route['body'] extends NonNullable<Route['body']> ? Route['body'] extends Record<any, any> ? Route['body'] : {
33
- $body: Route['body'];
34
- } : {}) & (Route['query'] extends NonNullable<Route['query']> ? unknown extends Route['query'] ? {} : {
35
- $query: Route['query'];
36
- } : {});
37
- export declare type CreateEden<Server extends Record<string, Record<string, TypedRoute>>, Path extends string = keyof Server extends string ? keyof Server : never, Full extends string = ''> = Path extends `/${infer Start}` ? CreateEden<Server, Start, Path> : Path extends `${infer A}/${infer B}` ? IsPathParameter<A> extends never ? {
38
- [key in A]: CreateEden<Server, B, Full>;
39
- } : Record<string, CreateEden<Server, B, Full>> & Record<`$${A}`, `Expected path parameters ':${A}', replace this with any string`> : // Iterate until last string then catch method
40
- {
41
- [key in Path extends '' ? 'index' : Path extends `:${infer params}` ? string : Path | CamelCase<Path>]: Full extends keyof Server ? {
42
- [key in keyof Server[Full] extends string ? Lowercase<keyof Server[Full]> : keyof Server[Full]]: [
43
- Server[Full][key extends string ? Uppercase<key> : key]
44
- ] extends [infer Route extends TypedRoute] ? undefined extends Route['body'] ? (params?: {
45
- $query?: EdenCall['$query'];
46
- $fetch?: EdenCall['$fetch'];
47
- }) => Promise<Route['response'] extends {
48
- 200: infer ReturnedType;
49
- } ? ReturnedType | MapError<Route['response']> : unknown> : (params: Prettify<TypedRouteToParams<Route> & {
50
- $query?: EdenCall['$query'];
51
- $fetch?: EdenCall['$fetch'];
52
- }>) => Promise<Route['response'] extends {
53
- 200: infer ReturnedType;
54
- } ? ReturnedType | MapError<Route['response']> : unknown> : key extends 'subscribe' ? [
55
- Server[Full][key],
56
- Server[Full][key]['query']
57
- ] extends [
58
- infer Route extends TypedRoute,
59
- infer Query extends TypedRoute['query']
60
- ] ? unknown extends NonNullable<Query> ? (params?: {
61
- $query?: EdenCall['$query'];
62
- }) => EdenWS<Route> : Query extends NonNullable<Query> ? (params: {
63
- $query: Query;
64
- }) => EdenWS<Route> : (params?: {
65
- $query?: EdenCall['$query'];
66
- }) => EdenWS<Route> : never : never;
67
- } : never;
68
- } & (Path extends `:${infer params}` ? Record<`$${params}`, `Expected path parameters ':${params}', replace this with any string`> : {});
69
- declare type CamelCase<S extends string> = S extends `${infer P1}-${infer P2}${infer P3}` ? `${Lowercase<P1>}${Uppercase<P2>}${CamelCase<P3>}` : Lowercase<S>;
70
- export interface EdenWSOnMessage<Data = unknown> extends MessageEvent {
71
- data: Data;
72
- rawData: MessageEvent['data'];
73
- }
74
- export declare type EdenWSEvent<K extends keyof WebSocketEventMap, Data = unknown> = K extends 'message' ? EdenWSOnMessage<Data> : WebSocketEventMap[K];
75
- export interface EdenConfig {
76
- fn?: string;
77
- fetch?: Omit<RequestInit, 'body'>;
78
- }
79
- declare type Enumerate<N extends number, Acc extends number[] = []> = Acc['length'] extends N ? Acc[number] : Enumerate<N, [...Acc, Acc['length']]>;
80
- declare type Range<F extends number, T extends number> = Exclude<Enumerate<T>, Enumerate<F>>;
81
- declare type ErrorRange = Range<300, 599>;
82
- declare type MapError<T extends Record<number, unknown>> = [
1
+ import type { EdenFetchError } from './utils';
2
+ type Range<F extends number, T extends number> = Exclude<Enumerate<T>, Enumerate<F>>;
3
+ type Enumerate<N extends number, Acc extends number[] = []> = Acc['length'] extends N ? Acc[number] : Enumerate<N, [...Acc, Acc['length']]>;
4
+ type ErrorRange = Range<300, 599>;
5
+ export type MapError<T extends Record<number, unknown>> = [
83
6
  {
84
7
  [K in keyof T]-?: K extends ErrorRange ? K : never;
85
8
  }[keyof T]
86
9
  ] extends [infer A extends number] ? {
87
10
  [K in A]: EdenFetchError<K, T[K]>;
88
11
  }[A] : false;
12
+ export type UnionToIntersect<U> = (U extends unknown ? (arg: U) => 0 : never) extends (arg: infer I) => 0 ? I : never;
13
+ export type IsAny<T> = 0 extends 1 & T ? true : false;
14
+ export type IsNever<T> = [T] extends [never] ? true : false;
15
+ export type IsUnknown<T> = IsAny<T> extends true ? false : unknown extends T ? true : false;
16
+ export type AnyTypedRoute = {
17
+ body: unknown;
18
+ headers: Record<string, any> | undefined;
19
+ query: Record<string, any> | undefined;
20
+ params: Record<string, any> | undefined;
21
+ response: Record<string, unknown> & {
22
+ '200': unknown;
23
+ };
24
+ };
89
25
  export {};
@@ -0,0 +1,8 @@
1
+ class e extends Error {
2
+ constructor(r, s) {
3
+ super(), this.status = r, this.value = s;
4
+ }
5
+ }
6
+ export {
7
+ e as E
8
+ };
@@ -0,0 +1 @@
1
+ "use strict";class t extends Error{constructor(r,s){super(),this.status=r,this.value=s}}exports.EdenFetchError=t;
package/dist/utils.d.ts CHANGED
@@ -1,19 +1,5 @@
1
- import type { EdenCall, EdenConfig } from './types';
2
1
  export declare class EdenFetchError<Status extends number = number, Value = unknown> extends Error {
3
2
  status: Status;
4
3
  value: Value;
5
4
  constructor(status: Status, value: Value);
6
5
  }
7
- export declare const composePath: (domain: string, path: string, query: EdenCall['$query'] | undefined) => string;
8
- export declare class Signal {
9
- private url;
10
- private config;
11
- private pendings;
12
- private operation;
13
- private isFetching;
14
- private sJson;
15
- constructor(url: string, config: EdenConfig);
16
- setConfig(config: EdenConfig): void;
17
- clone(config?: EdenConfig): Signal;
18
- run(procedure: string[], params: any): Promise<any>;
19
- }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elysiajs/eden",
3
- "version": "0.3.0-exp-230223.1133",
3
+ "version": "0.3.0-rc.0",
4
4
  "description": "Fully type-safe Elysia client",
5
5
  "author": {
6
6
  "name": "saltyAom",
@@ -14,6 +14,24 @@
14
14
  "import": "./dist/index.mjs",
15
15
  "node": "./dist/index.js",
16
16
  "default": "./dist/index.js"
17
+ },
18
+ "./treaty": {
19
+ "require": "./dist/treaty.js",
20
+ "import": "./dist/treaty.mjs",
21
+ "node": "./dist/treaty.js",
22
+ "default": "./dist/treaty.js"
23
+ },
24
+ "./fetch": {
25
+ "require": "./dist/fetch.js",
26
+ "import": "./dist/fetch.mjs",
27
+ "node": "./dist/fetch.js",
28
+ "default": "./dist/fetch.js"
29
+ },
30
+ "./fn": {
31
+ "require": "./dist/fn.js",
32
+ "import": "./dist/fn.mjs",
33
+ "node": "./dist/fn.js",
34
+ "default": "./dist/fn.js"
17
35
  }
18
36
  },
19
37
  "types": "./src/index.ts",
@@ -36,16 +54,21 @@
36
54
  "release": "npm run build && npm run test && npm publish --access public"
37
55
  },
38
56
  "peerDependencies": {
39
- "elysia": ">= 0.3.0-exp-230222.2123"
57
+ "@sinclair/typebox": ">= 0.25.21",
58
+ "elysia": ">= 0.3.0-rc.1"
59
+ },
60
+ "peerDependenciesMeta": {
61
+ "@sinclair/typebox": {
62
+ "optional": true
63
+ }
40
64
  },
41
65
  "devDependencies": {
42
66
  "@elysiajs/cors": "^0.1.0",
43
- "@elysiajs/websocket": "^0.2.6",
44
67
  "@sinclair/typebox": "^0.25.21",
45
68
  "@types/node": "^18.11.7",
46
- "bun-types": "^0.5.0",
69
+ "bun-types": "^0.5.7",
70
+ "elysia": "0.3.0-rc.2",
47
71
  "eslint": "^8.26.0",
48
- "elysia": "../elysia",
49
72
  "rimraf": "^3.0.2",
50
73
  "typescript": "^4.8.4",
51
74
  "vite": "^4.0.1",
@@ -54,4 +77,4 @@
54
77
  "dependencies": {
55
78
  "superjson": "^1.12.2"
56
79
  }
57
- }
80
+ }
@@ -0,0 +1,55 @@
1
+ import type { Elysia } from 'elysia'
2
+
3
+ import { EdenFetchError } from '../utils'
4
+ import type { EdenFetch } from './types'
5
+ export type { EdenFetch } from './types'
6
+
7
+ export const edenFetch =
8
+ <App extends Elysia<any>>(
9
+ server: string,
10
+ config?: EdenFetch.Config
11
+ ): EdenFetch.Create<App> =>
12
+ // @ts-ignore
13
+ async (endpoint: string, { params, body, ...options } = {}) => {
14
+ if (params)
15
+ Object.entries(params).forEach(([key, value]) => {
16
+ endpoint = endpoint.replace(`:${key}`, value)
17
+ })
18
+
19
+ const contentType = options.headers?.['Content-Type']
20
+
21
+ if (!contentType || contentType === 'application/json')
22
+ body = JSON.stringify(body)
23
+
24
+ // @ts-ignore
25
+ return fetch(server + endpoint, {
26
+ ...options,
27
+ headers: {
28
+ 'content-type': 'application/json',
29
+ ...options.headers
30
+ },
31
+ body
32
+ }).then(async (res) => {
33
+ let data: Promise<unknown>
34
+
35
+ switch (res.headers.get('Content-Type')?.split(';')[0]) {
36
+ case 'application/json':
37
+ data = res.json()
38
+ break
39
+
40
+ default:
41
+ data = res.text().then((data) => {
42
+ if (!Number.isNaN(+data)) return +data
43
+ if (data === 'true') return true
44
+ if (data === 'false') return false
45
+
46
+ return data
47
+ })
48
+ }
49
+
50
+ if (res.status > 300)
51
+ return new EdenFetchError(res.status, await data)
52
+
53
+ return data
54
+ })
55
+ }
@@ -0,0 +1,53 @@
1
+ import type { Elysia, SCHEMA } from 'elysia'
2
+ import type { EdenFetchError } from '../utils'
3
+ import type { MapError, IsUnknown, IsNever, AnyTypedRoute } from '../types'
4
+
5
+ export namespace EdenFetch {
6
+ export type Create<App extends Elysia<any>> = App['meta'] extends Record<
7
+ typeof SCHEMA,
8
+ infer Schema extends Record<string, any>
9
+ >
10
+ ? EdenFetch.Fn<Schema>
11
+ : 'Please install Elysia before using Eden'
12
+
13
+ export interface Config {}
14
+
15
+ export type Fn<Schema extends Record<string, any>> = <
16
+ Endpoint extends keyof Schema,
17
+ Method extends Extract<keyof Schema[Endpoint], string>,
18
+ Route extends Schema[Endpoint][Method]
19
+ >(
20
+ endpoint: Endpoint,
21
+ options: Omit<RequestInit, 'body' | 'method' | 'headers'> &
22
+ ('get' extends Method
23
+ ? {
24
+ method?: Uppercase<Method>
25
+ }
26
+ : {
27
+ method: Uppercase<Method>
28
+ }) &
29
+ (IsNever<keyof Route['params']> extends true
30
+ ? {
31
+ params?: Record<never, string>
32
+ }
33
+ : {
34
+ params: Route['params']
35
+ }) &
36
+ (undefined extends Route['headers']
37
+ ? {
38
+ headers?: Record<string, string>
39
+ }
40
+ : {
41
+ headers: Route['headers']
42
+ }) &
43
+ (IsUnknown<Route['body']> extends false
44
+ ? { body: Route['body'] }
45
+ : { body?: unknown })
46
+ ) =>
47
+ | Promise<Route['response']['200']>
48
+ | (MapError<Route['response']> extends infer Errors
49
+ ? IsNever<Errors> extends true
50
+ ? EdenFetchError<number, string>
51
+ : Errors
52
+ : never)
53
+ }
@@ -0,0 +1,53 @@
1
+ import type { Elysia } from 'elysia'
2
+
3
+ import { Signal } from './utils'
4
+
5
+ import type { EdenFn } from './types'
6
+ export type { EdenFn } from './types'
7
+
8
+ const createProxy = (
9
+ domain: string,
10
+ procedures: string[],
11
+ signal: Signal
12
+ ): Record<string, unknown> =>
13
+ new Proxy((..._: any[]) => {}, {
14
+ get(target, key, value) {
15
+ return createProxy(domain, [...procedures, key as string], signal)
16
+ },
17
+ apply(target, _, params) {
18
+ const param = params[0]
19
+ const procedure = procedures[0]
20
+
21
+ if (procedures.length === 1) {
22
+ if (
23
+ procedure in Object.prototype ||
24
+ procedure in Promise.prototype
25
+ )
26
+ return target(...params)
27
+
28
+ switch (procedure) {
29
+ case 'toJSON':
30
+ return target(...params)
31
+
32
+ case '$set':
33
+ return signal.setConfig(param)
34
+
35
+ case '$clone':
36
+ return createProxy(domain, [], signal.clone(param))
37
+ }
38
+ }
39
+
40
+ return signal.run(procedures, params).then((result) => {
41
+ if (result instanceof Error) throw result
42
+
43
+ return result
44
+ })
45
+ }
46
+ }) as any
47
+
48
+ export const edenFn = <App extends Elysia<any>>(
49
+ domain: string,
50
+ config?: EdenFn.Config
51
+ ): EdenFn.Create<App> =>
52
+ // @ts-ignore
53
+ createProxy(domain, [], new Signal(domain, config))
@@ -0,0 +1,45 @@
1
+ import type { Elysia, EXPOSED } from 'elysia'
2
+
3
+ export namespace EdenFn {
4
+ export type Create<App extends Elysia<any>> = App['meta'] extends Record<
5
+ typeof EXPOSED,
6
+ infer Schema extends Record<string, any>
7
+ >
8
+ ? EdenFn.Compose<Schema>
9
+ : 'Please install Elysia before using Eden'
10
+
11
+ export interface Config {}
12
+
13
+ export type Compose<Exposed extends Record<string, any>> = Fn<Exposed> & {
14
+ $set(config: Config): void
15
+ $clone(config?: Config): Compose<Exposed>
16
+ }
17
+
18
+ export type Fn<T> = T extends {
19
+ [EXPOSED]: any
20
+ value: infer Value
21
+ }
22
+ ? Asynctify<Value>
23
+ : Asynctify<T>
24
+
25
+ export interface Config {
26
+ fn?: string
27
+ fetch?: Omit<RequestInit, 'body'>
28
+ }
29
+ }
30
+
31
+ type Promisify<T extends (...args: any[]) => any> = T extends (
32
+ ...args: infer Args
33
+ ) => infer Return
34
+ ? Return extends Promise<any>
35
+ ? T
36
+ : (...args: Args) => Promise<Return>
37
+ : never
38
+
39
+ type Asynctify<T> = T extends infer Fn extends (...args: any) => any
40
+ ? Promisify<Fn>
41
+ : T extends Record<string, any>
42
+ ? {
43
+ [K in keyof T]: EdenFn.Fn<T[K]>
44
+ }
45
+ : never
@@ -0,0 +1,86 @@
1
+ import type { serialize, deserialize } from 'superjson'
2
+ import type { EdenFn } from './types'
3
+
4
+ export class Signal {
5
+ private url: string
6
+ private config: EdenFn.Config
7
+
8
+ private pendings: Array<{ n: string[] } | { n: string[]; p: any }> = []
9
+ private operation: Promise<any[]> | null = null
10
+ private isFetching = false
11
+
12
+ private sJson: Promise<{
13
+ serialize: typeof serialize
14
+ deserialize: typeof deserialize
15
+ }>
16
+
17
+ constructor(url: string, config: EdenFn.Config = {}) {
18
+ this.url = url
19
+ this.config = config
20
+
21
+ this.sJson = import('superjson').then((superJson) => {
22
+ return {
23
+ serialize: superJson.serialize,
24
+ deserialize: superJson.deserialize
25
+ }
26
+ })
27
+ }
28
+
29
+ setConfig(config: EdenFn.Config) {
30
+ this.config = config
31
+ }
32
+
33
+ clone(config?: EdenFn.Config) {
34
+ return new Signal(this.url, config ?? this.config)
35
+ }
36
+
37
+ async run(procedure: string[], params: any) {
38
+ const current = +this.pendings.length
39
+ this.pendings.push(
40
+ params !== undefined
41
+ ? { n: procedure, p: params }
42
+ : { n: procedure }
43
+ )
44
+
45
+ if (this.isFetching) return this.operation?.then((x) => x[current])
46
+ this.isFetching = true
47
+
48
+ this.operation = new Promise((resolve) => {
49
+ setTimeout(async () => {
50
+ const requests = [...this.pendings]
51
+ this.pendings = []
52
+
53
+ const { serialize, deserialize } = await this.sJson
54
+
55
+ const results = await fetch(
56
+ `${this.url}${this.config.fn ?? '/~fn'}`,
57
+ {
58
+ method: 'POST',
59
+ ...this.config.fetch,
60
+ headers: {
61
+ 'content-type': 'elysia/fn',
62
+ ...this.config.fetch?.headers
63
+ },
64
+ body: JSON.stringify(serialize(requests))
65
+ }
66
+ )
67
+
68
+ if (results.status === 200)
69
+ resolve(results.json().then((x) => deserialize(x as any)))
70
+ else
71
+ resolve(
72
+ Array(requests.length).fill(
73
+ new Error(await results.text())
74
+ )
75
+ )
76
+ }, 33)
77
+ })
78
+
79
+ const result = await this.operation.then((results) => results[current])
80
+
81
+ this.operation = null
82
+ this.isFetching = false
83
+
84
+ return result
85
+ }
86
+ }