@xata.io/client 0.2.2 → 0.3.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.
- package/CHANGELOG.md +13 -0
- package/dist/api/client.d.ts +95 -0
- package/dist/api/client.js +235 -0
- package/dist/api/components.d.ts +1440 -0
- package/dist/api/components.js +1001 -0
- package/dist/api/fetcher.d.ts +25 -0
- package/dist/api/fetcher.js +78 -0
- package/dist/api/index.d.ts +7 -0
- package/dist/api/index.js +21 -0
- package/dist/api/parameters.d.ts +16 -0
- package/dist/api/parameters.js +2 -0
- package/dist/api/providers.d.ts +8 -0
- package/dist/api/providers.js +29 -0
- package/dist/api/responses.d.ts +44 -0
- package/dist/api/responses.js +2 -0
- package/dist/api/schemas.d.ts +311 -0
- package/dist/api/schemas.js +2 -0
- package/dist/index.d.ts +2 -133
- package/dist/index.js +16 -368
- package/dist/schema/filters.d.ts +20 -0
- package/dist/schema/filters.js +24 -0
- package/dist/schema/index.d.ts +5 -0
- package/dist/schema/index.js +25 -0
- package/dist/schema/operators.d.ts +72 -0
- package/dist/schema/operators.js +91 -0
- package/dist/schema/pagination.d.ts +79 -0
- package/dist/schema/pagination.js +90 -0
- package/dist/schema/query.d.ts +114 -0
- package/dist/schema/query.js +227 -0
- package/dist/schema/record.d.ts +36 -0
- package/dist/schema/record.js +2 -0
- package/dist/schema/repository.d.ts +109 -0
- package/dist/schema/repository.js +273 -0
- package/dist/schema/selection.d.ts +13 -0
- package/dist/schema/selection.js +2 -0
- package/dist/util/lang.d.ts +2 -0
- package/dist/util/lang.js +10 -0
- package/dist/util/types.d.ts +3 -0
- package/dist/util/types.js +2 -0
- package/package.json +3 -3
- package/dist/index.test.d.ts +0 -1
- package/dist/index.test.js +0 -304
- package/src/index.test.ts +0 -392
- package/src/index.ts +0 -506
package/src/index.ts
DELETED
@@ -1,506 +0,0 @@
|
|
1
|
-
export interface XataRecord {
|
2
|
-
id: string;
|
3
|
-
xata: {
|
4
|
-
version: number;
|
5
|
-
};
|
6
|
-
read(): Promise<this>;
|
7
|
-
update(data: Selectable<this>): Promise<this>;
|
8
|
-
delete(): Promise<void>;
|
9
|
-
}
|
10
|
-
|
11
|
-
export type Queries<T> = {
|
12
|
-
[key in keyof T as T[key] extends Query<infer A, infer B> ? key : never]: T[key];
|
13
|
-
};
|
14
|
-
|
15
|
-
export type OmitQueries<T> = {
|
16
|
-
[key in keyof T as T[key] extends Query<infer A, infer B> ? never : key]: T[key];
|
17
|
-
};
|
18
|
-
|
19
|
-
export type OmitLinks<T> = {
|
20
|
-
[key in keyof T as T[key] extends XataRecord ? never : key]: T[key];
|
21
|
-
};
|
22
|
-
|
23
|
-
export type OmitMethods<T> = {
|
24
|
-
// eslint-disable-next-line @typescript-eslint/ban-types
|
25
|
-
[key in keyof T as T[key] extends Function ? never : key]: T[key];
|
26
|
-
};
|
27
|
-
|
28
|
-
export type Selectable<T> = Omit<OmitQueries<OmitMethods<T>>, 'id' | 'xata'>;
|
29
|
-
|
30
|
-
export type Select<T, K extends keyof T> = Pick<T, K> & Queries<T> & XataRecord;
|
31
|
-
|
32
|
-
export type Include<T> = {
|
33
|
-
[key in keyof T as T[key] extends XataRecord ? key : never]?: boolean | Array<keyof Selectable<T[key]>>;
|
34
|
-
};
|
35
|
-
|
36
|
-
type SortDirection = 'asc' | 'desc';
|
37
|
-
|
38
|
-
type Operator =
|
39
|
-
| '$gt'
|
40
|
-
| '$lt'
|
41
|
-
| '$ge'
|
42
|
-
| '$le'
|
43
|
-
| '$exists'
|
44
|
-
| '$notExists'
|
45
|
-
| '$endsWith'
|
46
|
-
| '$startsWith'
|
47
|
-
| '$pattern'
|
48
|
-
| '$is'
|
49
|
-
| '$isNot'
|
50
|
-
| '$contains'
|
51
|
-
| '$includes'
|
52
|
-
| '$includesSubstring'
|
53
|
-
| '$includesPattern'
|
54
|
-
| '$includesAll';
|
55
|
-
|
56
|
-
// TODO: restrict constraints depending on type?
|
57
|
-
// E.g. startsWith cannot be used with numbers
|
58
|
-
type Constraint<T> = { [key in Operator]?: T };
|
59
|
-
|
60
|
-
type DeepConstraint<T> = T extends Record<string, any>
|
61
|
-
? {
|
62
|
-
[key in keyof T]?: T[key] | DeepConstraint<T[key]>;
|
63
|
-
}
|
64
|
-
: Constraint<T>;
|
65
|
-
|
66
|
-
type ComparableType = number | Date;
|
67
|
-
|
68
|
-
export const gt = <T extends ComparableType>(value: T): Constraint<T> => ({ $gt: value });
|
69
|
-
export const ge = <T extends ComparableType>(value: T): Constraint<T> => ({ $ge: value });
|
70
|
-
export const gte = <T extends ComparableType>(value: T): Constraint<T> => ({ $ge: value });
|
71
|
-
export const lt = <T extends ComparableType>(value: T): Constraint<T> => ({ $lt: value });
|
72
|
-
export const lte = <T extends ComparableType>(value: T): Constraint<T> => ({ $le: value });
|
73
|
-
export const le = <T extends ComparableType>(value: T): Constraint<T> => ({ $le: value });
|
74
|
-
export const exists = (column: string): Constraint<string> => ({ $exists: column });
|
75
|
-
export const notExists = (column: string): Constraint<string> => ({ $notExists: column });
|
76
|
-
export const startsWith = (value: string): Constraint<string> => ({ $startsWith: value });
|
77
|
-
export const endsWith = (value: string): Constraint<string> => ({ $endsWith: value });
|
78
|
-
export const pattern = (value: string): Constraint<string> => ({ $pattern: value });
|
79
|
-
export const is = <T>(value: T): Constraint<T> => ({ $is: value });
|
80
|
-
export const isNot = <T>(value: T): Constraint<T> => ({ $isNot: value });
|
81
|
-
export const contains = <T>(value: T): Constraint<T> => ({ $contains: value });
|
82
|
-
|
83
|
-
// TODO: these can only be applied to columns of type "multiple"
|
84
|
-
export const includes = (value: string): Constraint<string> => ({ $includes: value });
|
85
|
-
export const includesSubstring = (value: string): Constraint<string> => ({ $includesSubstring: value });
|
86
|
-
export const includesPattern = (value: string): Constraint<string> => ({ $includesPattern: value });
|
87
|
-
export const includesAll = (value: string): Constraint<string> => ({ $includesAll: value });
|
88
|
-
|
89
|
-
type FilterConstraints<T> = {
|
90
|
-
[key in keyof T]?: T[key] extends Record<string, any> ? FilterConstraints<T[key]> : T[key] | DeepConstraint<T[key]>;
|
91
|
-
};
|
92
|
-
|
93
|
-
type BulkQueryOptions<T> = {
|
94
|
-
filter?: FilterConstraints<T>;
|
95
|
-
sort?:
|
96
|
-
| {
|
97
|
-
column: keyof T;
|
98
|
-
direction?: SortDirection;
|
99
|
-
}
|
100
|
-
| keyof T;
|
101
|
-
};
|
102
|
-
|
103
|
-
type QueryOrConstraint<T, R> = Query<T, R> | Constraint<T>;
|
104
|
-
|
105
|
-
export class Query<T, R = T> {
|
106
|
-
table: string;
|
107
|
-
repository: Repository<T>;
|
108
|
-
|
109
|
-
readonly $any?: QueryOrConstraint<T, R>[];
|
110
|
-
readonly $all?: QueryOrConstraint<T, R>[];
|
111
|
-
readonly $not?: QueryOrConstraint<T, R>[];
|
112
|
-
readonly $none?: QueryOrConstraint<T, R>[];
|
113
|
-
readonly $sort?: Record<string, SortDirection>;
|
114
|
-
|
115
|
-
constructor(repository: Repository<T> | null, table: string, data: Partial<Query<T, R>>, parent?: Query<T, R>) {
|
116
|
-
if (repository) {
|
117
|
-
this.repository = repository;
|
118
|
-
} else {
|
119
|
-
this.repository = this as any;
|
120
|
-
}
|
121
|
-
this.table = table;
|
122
|
-
|
123
|
-
// For some reason Object.assign(this, parent) didn't work in this case
|
124
|
-
// so doing all this manually:
|
125
|
-
this.$any = parent?.$any;
|
126
|
-
this.$all = parent?.$all;
|
127
|
-
this.$not = parent?.$not;
|
128
|
-
this.$none = parent?.$none;
|
129
|
-
this.$sort = parent?.$sort;
|
130
|
-
|
131
|
-
Object.assign(this, data);
|
132
|
-
// These bindings are used to support deconstructing
|
133
|
-
// const { any, not, filter, sort } = xata.users.query()
|
134
|
-
this.any = this.any.bind(this);
|
135
|
-
this.all = this.all.bind(this);
|
136
|
-
this.not = this.not.bind(this);
|
137
|
-
this.filter = this.filter.bind(this);
|
138
|
-
this.sort = this.sort.bind(this);
|
139
|
-
this.none = this.none.bind(this);
|
140
|
-
|
141
|
-
Object.defineProperty(this, 'table', { enumerable: false });
|
142
|
-
Object.defineProperty(this, 'repository', { enumerable: false });
|
143
|
-
}
|
144
|
-
|
145
|
-
any(...queries: Query<T, R>[]): Query<T, R> {
|
146
|
-
return new Query<T, R>(
|
147
|
-
this.repository,
|
148
|
-
this.table,
|
149
|
-
{
|
150
|
-
$any: (this.$any || []).concat(queries)
|
151
|
-
},
|
152
|
-
this
|
153
|
-
);
|
154
|
-
}
|
155
|
-
|
156
|
-
all(...queries: Query<T, R>[]): Query<T, R> {
|
157
|
-
return new Query<T, R>(
|
158
|
-
this.repository,
|
159
|
-
this.table,
|
160
|
-
{
|
161
|
-
$all: (this.$all || []).concat(queries)
|
162
|
-
},
|
163
|
-
this
|
164
|
-
);
|
165
|
-
}
|
166
|
-
|
167
|
-
not(...queries: Query<T, R>[]): Query<T, R> {
|
168
|
-
return new Query<T, R>(
|
169
|
-
this.repository,
|
170
|
-
this.table,
|
171
|
-
{
|
172
|
-
$not: (this.$not || []).concat(queries)
|
173
|
-
},
|
174
|
-
this
|
175
|
-
);
|
176
|
-
}
|
177
|
-
|
178
|
-
none(...queries: Query<T, R>[]): Query<T, R> {
|
179
|
-
return new Query<T, R>(
|
180
|
-
this.repository,
|
181
|
-
this.table,
|
182
|
-
{
|
183
|
-
$none: (this.$none || []).concat(queries)
|
184
|
-
},
|
185
|
-
this
|
186
|
-
);
|
187
|
-
}
|
188
|
-
|
189
|
-
filter(constraints: FilterConstraints<T>): Query<T, R>;
|
190
|
-
filter<F extends keyof T>(column: F, value: FilterConstraints<T[F]> | DeepConstraint<T[F]>): Query<T, R>;
|
191
|
-
filter(a: any, b?: any): Query<T, R> {
|
192
|
-
if (arguments.length === 1) {
|
193
|
-
const constraints = a as FilterConstraints<T>;
|
194
|
-
const queries: QueryOrConstraint<T, R>[] = [];
|
195
|
-
for (const [column, constraint] of Object.entries(constraints)) {
|
196
|
-
queries.push({ [column]: constraint });
|
197
|
-
}
|
198
|
-
return new Query<T, R>(
|
199
|
-
this.repository,
|
200
|
-
this.table,
|
201
|
-
{
|
202
|
-
$all: (this.$all || []).concat(queries)
|
203
|
-
},
|
204
|
-
this
|
205
|
-
);
|
206
|
-
} else {
|
207
|
-
const column = a as keyof T;
|
208
|
-
const value = b as Partial<T[keyof T]> | Constraint<T[keyof T]>;
|
209
|
-
return new Query<T, R>(
|
210
|
-
this.repository,
|
211
|
-
this.table,
|
212
|
-
{
|
213
|
-
$all: (this.$all || []).concat({ [column]: value })
|
214
|
-
},
|
215
|
-
this
|
216
|
-
);
|
217
|
-
}
|
218
|
-
}
|
219
|
-
|
220
|
-
sort<F extends keyof T>(column: F, direction: SortDirection): Query<T, R> {
|
221
|
-
const sort = { ...this.$sort, [column]: direction };
|
222
|
-
const q = new Query<T, R>(
|
223
|
-
this.repository,
|
224
|
-
this.table,
|
225
|
-
{
|
226
|
-
$sort: sort
|
227
|
-
},
|
228
|
-
this
|
229
|
-
);
|
230
|
-
|
231
|
-
return q;
|
232
|
-
}
|
233
|
-
|
234
|
-
// TODO: pagination. Maybe implement different methods for different type of paginations
|
235
|
-
// and one to simply get the first records returned by the query with no pagination.
|
236
|
-
async getMany(options?: BulkQueryOptions<T>): Promise<R[]> {
|
237
|
-
// TODO: use options
|
238
|
-
return this.repository.query(this);
|
239
|
-
}
|
240
|
-
|
241
|
-
async getOne(options?: BulkQueryOptions<T>): Promise<R | null> {
|
242
|
-
// TODO: use options
|
243
|
-
const arr = await this.getMany(); // TODO, limit to 1
|
244
|
-
return arr[0] || null;
|
245
|
-
}
|
246
|
-
|
247
|
-
async deleteAll(): Promise<number> {
|
248
|
-
// Return number of affected rows
|
249
|
-
return 0;
|
250
|
-
}
|
251
|
-
|
252
|
-
include(columns: Include<T>) {
|
253
|
-
// TODO
|
254
|
-
return this;
|
255
|
-
}
|
256
|
-
}
|
257
|
-
|
258
|
-
export abstract class Repository<T> extends Query<T, Selectable<T>> {
|
259
|
-
select<K extends keyof Selectable<T>>(...columns: K[]) {
|
260
|
-
return new Query<T, Select<T, K>>(this.repository, this.table, {});
|
261
|
-
}
|
262
|
-
|
263
|
-
abstract create(object: Selectable<T>): Promise<T>;
|
264
|
-
|
265
|
-
abstract read(id: string): Promise<T | null>;
|
266
|
-
|
267
|
-
abstract update(id: string, object: Partial<T>): Promise<T>;
|
268
|
-
|
269
|
-
abstract delete(id: string): void;
|
270
|
-
|
271
|
-
// Used by the Query object internally
|
272
|
-
abstract query<R>(query: Query<T, R>): Promise<R[]>;
|
273
|
-
}
|
274
|
-
|
275
|
-
export class RestRepository<T> extends Repository<T> {
|
276
|
-
client: BaseClient<any>;
|
277
|
-
fetch: any;
|
278
|
-
|
279
|
-
constructor(client: BaseClient<any>, table: string) {
|
280
|
-
super(null, table, {});
|
281
|
-
this.client = client;
|
282
|
-
|
283
|
-
const { fetch } = client.options;
|
284
|
-
|
285
|
-
if (fetch) {
|
286
|
-
this.fetch = fetch;
|
287
|
-
} else if (typeof window === 'object') {
|
288
|
-
this.fetch = window.fetch;
|
289
|
-
} else if (typeof require === 'function') {
|
290
|
-
try {
|
291
|
-
this.fetch = require('node-fetch');
|
292
|
-
} catch (err) {
|
293
|
-
try {
|
294
|
-
this.fetch = require('cross-fetch');
|
295
|
-
} catch (err) {
|
296
|
-
throw new Error('No fetch implementation found. Please provide one in the constructor');
|
297
|
-
}
|
298
|
-
}
|
299
|
-
}
|
300
|
-
|
301
|
-
Object.defineProperty(this, 'client', { enumerable: false });
|
302
|
-
Object.defineProperty(this, 'fetch', { enumerable: false });
|
303
|
-
Object.defineProperty(this, 'hostname', { enumerable: false });
|
304
|
-
}
|
305
|
-
|
306
|
-
async request(method: string, path: string, body?: unknown) {
|
307
|
-
const { databaseURL, apiKey } = this.client.options;
|
308
|
-
const branch = await this.client.getBranch();
|
309
|
-
|
310
|
-
const resp: Response = await this.fetch(`${databaseURL}:${branch}${path}`, {
|
311
|
-
method,
|
312
|
-
headers: {
|
313
|
-
Accept: '*/*',
|
314
|
-
'Content-Type': 'application/json',
|
315
|
-
Authorization: `Bearer ${apiKey}`
|
316
|
-
},
|
317
|
-
body: JSON.stringify(body)
|
318
|
-
});
|
319
|
-
if (!resp.ok) {
|
320
|
-
try {
|
321
|
-
const json = await resp.json();
|
322
|
-
const message = json.message;
|
323
|
-
if (typeof message === 'string') {
|
324
|
-
throw new XataError(message, resp.status);
|
325
|
-
}
|
326
|
-
} catch (err) {
|
327
|
-
if (err instanceof XataError) throw err;
|
328
|
-
// Ignore errors for other reasons.
|
329
|
-
// For example if the response's body cannot be parsed as JSON
|
330
|
-
}
|
331
|
-
throw new XataError(resp.statusText, resp.status);
|
332
|
-
}
|
333
|
-
if (resp.status === 204) return;
|
334
|
-
return resp.json();
|
335
|
-
}
|
336
|
-
|
337
|
-
select<K extends keyof T>(...columns: K[]) {
|
338
|
-
return new Query<T, Select<T, K>>(this.repository, this.table, {});
|
339
|
-
}
|
340
|
-
|
341
|
-
async create(object: T): Promise<T> {
|
342
|
-
const body = { ...object } as Record<string, unknown>;
|
343
|
-
for (const key of Object.keys(body)) {
|
344
|
-
const value = body[key];
|
345
|
-
if (value && typeof value === 'object' && typeof (value as Record<string, unknown>).id === 'string') {
|
346
|
-
body[key] = (value as XataRecord).id;
|
347
|
-
}
|
348
|
-
}
|
349
|
-
const obj = await this.request('POST', `/tables/${this.table}/data`, body);
|
350
|
-
return this.client.initObject(this.table, obj);
|
351
|
-
}
|
352
|
-
|
353
|
-
async read(id: string): Promise<T | null> {
|
354
|
-
try {
|
355
|
-
const obj = await this.request('GET', `/tables/${this.table}/data/${id}`);
|
356
|
-
return this.client.initObject(this.table, obj);
|
357
|
-
} catch (err) {
|
358
|
-
if ((err as XataError).status === 404) return null;
|
359
|
-
throw err;
|
360
|
-
}
|
361
|
-
}
|
362
|
-
|
363
|
-
async update(id: string, object: Partial<T>): Promise<T> {
|
364
|
-
const obj = await this.request('PUT', `/tables/${this.table}/data/${id}`, object);
|
365
|
-
return this.client.initObject(this.table, obj);
|
366
|
-
}
|
367
|
-
|
368
|
-
async delete(id: string) {
|
369
|
-
await this.request('DELETE', `/tables/${this.table}/data/${id}`);
|
370
|
-
}
|
371
|
-
|
372
|
-
async query<R>(query: Query<T, R>): Promise<R[]> {
|
373
|
-
const filter = {
|
374
|
-
$any: query.$any,
|
375
|
-
$all: query.$all,
|
376
|
-
$not: query.$not,
|
377
|
-
$none: query.$none
|
378
|
-
};
|
379
|
-
const body = {
|
380
|
-
filter: Object.values(filter).some(Boolean) ? filter : undefined,
|
381
|
-
sort: query.$sort
|
382
|
-
};
|
383
|
-
const result = await this.request('POST', `/tables/${this.table}/query`, body);
|
384
|
-
return result.records.map((record: object) => this.client.initObject(this.table, record));
|
385
|
-
}
|
386
|
-
}
|
387
|
-
|
388
|
-
interface RepositoryFactory {
|
389
|
-
createRepository<T>(client: BaseClient<any>, table: string): Repository<T>;
|
390
|
-
}
|
391
|
-
|
392
|
-
export class RestRespositoryFactory implements RepositoryFactory {
|
393
|
-
createRepository<T>(client: BaseClient<any>, table: string): Repository<T> {
|
394
|
-
return new RestRepository<T>(client, table);
|
395
|
-
}
|
396
|
-
}
|
397
|
-
|
398
|
-
type BranchStrategyValue = string | undefined | null;
|
399
|
-
type BranchStrategyBuilder = () => BranchStrategyValue | Promise<BranchStrategyValue>;
|
400
|
-
type BranchStrategy = BranchStrategyValue | BranchStrategyBuilder;
|
401
|
-
type BranchStrategyOption = NonNullable<BranchStrategy | BranchStrategy[]>;
|
402
|
-
|
403
|
-
export type XataClientOptions = {
|
404
|
-
fetch?: unknown;
|
405
|
-
databaseURL: string;
|
406
|
-
branch: BranchStrategyOption;
|
407
|
-
apiKey: string;
|
408
|
-
repositoryFactory?: RepositoryFactory;
|
409
|
-
};
|
410
|
-
|
411
|
-
export class BaseClient<D extends Record<string, Repository<any>>> {
|
412
|
-
options: XataClientOptions;
|
413
|
-
private links: Links;
|
414
|
-
private branch: BranchStrategyValue;
|
415
|
-
db!: D;
|
416
|
-
|
417
|
-
constructor(options: XataClientOptions, links: Links) {
|
418
|
-
if (!options.databaseURL || !options.apiKey || !options.branch) {
|
419
|
-
throw new Error('Options databaseURL, apiKey and branch are required');
|
420
|
-
}
|
421
|
-
|
422
|
-
this.options = options;
|
423
|
-
this.links = links;
|
424
|
-
}
|
425
|
-
|
426
|
-
public initObject<T>(table: string, object: object) {
|
427
|
-
const o: Record<string, unknown> = {};
|
428
|
-
Object.assign(o, object);
|
429
|
-
|
430
|
-
const tableLinks = this.links[table] || [];
|
431
|
-
for (const link of tableLinks) {
|
432
|
-
const [field, linkTable] = link;
|
433
|
-
const value = o[field];
|
434
|
-
|
435
|
-
if (value && typeof value === 'object') {
|
436
|
-
const { id } = value as any;
|
437
|
-
if (Object.keys(value).find((col) => col === 'id')) {
|
438
|
-
o[field] = this.initObject(linkTable, value);
|
439
|
-
} else if (id) {
|
440
|
-
o[field] = {
|
441
|
-
id,
|
442
|
-
get: () => {
|
443
|
-
this.db[linkTable].read(id);
|
444
|
-
}
|
445
|
-
};
|
446
|
-
}
|
447
|
-
}
|
448
|
-
}
|
449
|
-
|
450
|
-
const db = this.db;
|
451
|
-
o.read = function () {
|
452
|
-
return db[table].read(o['id'] as string);
|
453
|
-
};
|
454
|
-
o.update = function (data: any) {
|
455
|
-
return db[table].update(o['id'] as string, data);
|
456
|
-
};
|
457
|
-
o.delete = function () {
|
458
|
-
return db[table].delete(o['id'] as string);
|
459
|
-
};
|
460
|
-
|
461
|
-
for (const prop of ['read', 'update', 'delete']) {
|
462
|
-
Object.defineProperty(o, prop, { enumerable: false });
|
463
|
-
}
|
464
|
-
|
465
|
-
// TODO: links and rev links
|
466
|
-
|
467
|
-
Object.freeze(o);
|
468
|
-
return o as T;
|
469
|
-
}
|
470
|
-
|
471
|
-
public async getBranch(): Promise<string> {
|
472
|
-
if (this.branch) return this.branch;
|
473
|
-
|
474
|
-
const { branch: param } = this.options;
|
475
|
-
const strategies = Array.isArray(param) ? [...param] : [param];
|
476
|
-
|
477
|
-
const evaluateBranch = async (strategy: BranchStrategy) => {
|
478
|
-
return isBranchStrategyBuilder(strategy) ? await strategy() : strategy;
|
479
|
-
};
|
480
|
-
|
481
|
-
for await (const strategy of strategies) {
|
482
|
-
const branch = await evaluateBranch(strategy);
|
483
|
-
if (branch) {
|
484
|
-
this.branch = branch;
|
485
|
-
return branch;
|
486
|
-
}
|
487
|
-
}
|
488
|
-
|
489
|
-
throw new Error('Unable to resolve branch value');
|
490
|
-
}
|
491
|
-
}
|
492
|
-
|
493
|
-
export class XataError extends Error {
|
494
|
-
readonly status: number;
|
495
|
-
|
496
|
-
constructor(message: string, status: number) {
|
497
|
-
super(message);
|
498
|
-
this.status = status;
|
499
|
-
}
|
500
|
-
}
|
501
|
-
|
502
|
-
export type Links = Record<string, Array<string[]>>;
|
503
|
-
|
504
|
-
const isBranchStrategyBuilder = (strategy: BranchStrategy): strategy is BranchStrategyBuilder => {
|
505
|
-
return typeof strategy === 'function';
|
506
|
-
};
|