@xata.io/client 0.13.0 → 0.13.3
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 +34 -0
- package/Usage.md +380 -0
- package/dist/index.cjs +64 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +31 -14
- package/dist/index.mjs +64 -20
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -3
package/dist/index.d.ts
CHANGED
@@ -6,6 +6,9 @@ declare type FetchImpl = (url: string, init?: {
|
|
6
6
|
ok: boolean;
|
7
7
|
status: number;
|
8
8
|
json(): Promise<any>;
|
9
|
+
headers?: {
|
10
|
+
get(name: string): string | null;
|
11
|
+
};
|
9
12
|
}>;
|
10
13
|
declare type WorkspaceApiUrlBuilder = (path: string, pathParams: Record<string, string>) => string;
|
11
14
|
declare type FetcherExtraProps = {
|
@@ -2798,7 +2801,7 @@ declare class DatabaseApi {
|
|
2798
2801
|
getGitBranchesMapping(workspace: WorkspaceID, dbName: DBName): Promise<ListGitBranchesResponse>;
|
2799
2802
|
addGitBranchesEntry(workspace: WorkspaceID, dbName: DBName, body: AddGitBranchesEntryRequestBody): Promise<AddGitBranchesEntryResponse>;
|
2800
2803
|
removeGitBranchesEntry(workspace: WorkspaceID, dbName: DBName, gitBranch: string): Promise<void>;
|
2801
|
-
resolveBranch(workspace: WorkspaceID, dbName: DBName, gitBranch
|
2804
|
+
resolveBranch(workspace: WorkspaceID, dbName: DBName, gitBranch?: string, fallbackBranch?: string): Promise<ResolveBranchResponse>;
|
2802
2805
|
}
|
2803
2806
|
declare class BranchApi {
|
2804
2807
|
private extraProps;
|
@@ -2867,25 +2870,24 @@ declare type SelectableColumn<O, RecursivePath extends any[] = []> = '*' | 'id'
|
|
2867
2870
|
declare type SelectedPick<O extends XataRecord, Key extends SelectableColumn<O>[]> = XataRecord & UnionToIntersection<Values<{
|
2868
2871
|
[K in Key[number]]: NestedValueAtColumn<O, K> & XataRecord;
|
2869
2872
|
}>>;
|
2870
|
-
declare type ValueAtColumn<O, P extends SelectableColumn<O>> = P extends '*' ? Values<O> : P extends 'id' ? string : P extends keyof O ? O[P] : P extends `${infer K}.${infer V}` ? K extends keyof O ? Values<
|
2871
|
-
V: ValueAtColumn<
|
2872
|
-
} : never : O[K]> : never : never;
|
2873
|
+
declare type ValueAtColumn<O, P extends SelectableColumn<O>> = P extends '*' ? Values<O> : P extends 'id' ? string : P extends keyof O ? O[P] : P extends `${infer K}.${infer V}` ? K extends keyof O ? Values<NonNullable<O[K]> extends infer Item ? Item extends Record<string, any> ? V extends SelectableColumn<Item> ? {
|
2874
|
+
V: ValueAtColumn<Item, V>;
|
2875
|
+
} : never : O[K] : never> : never : never;
|
2873
2876
|
declare type MAX_RECURSION = 5;
|
2874
2877
|
declare type NestedColumns<O, RecursivePath extends any[]> = RecursivePath['length'] extends MAX_RECURSION ? never : If<IsObject<O>, Values<{
|
2875
|
-
[K in DataProps<O>]:
|
2876
|
-
If<IsObject<
|
2877
|
-
K
|
2878
|
+
[K in DataProps<O>]: NonNullable<O[K]> extends infer Item ? If<IsArray<Item>, K, // If the property is an array, we stop recursion. We don't support object arrays yet
|
2879
|
+
If<IsObject<Item>, Item extends XataRecord ? SelectableColumn<Item, [...RecursivePath, Item]> extends infer Column ? Column extends string ? K | `${K}.${Column}` : never : never : Item extends Date ? K : `${K}.${StringKeys<Item> | '*'}`, // This allows usage of objects that are not links
|
2880
|
+
K>> : never;
|
2878
2881
|
}>, never>;
|
2879
2882
|
declare type DataProps<O> = Exclude<StringKeys<O>, StringKeys<XataRecord>>;
|
2880
2883
|
declare type NestedValueAtColumn<O, Key extends SelectableColumn<O>> = Key extends `${infer N}.${infer M}` ? N extends DataProps<O> ? {
|
2881
|
-
[K in N]: M extends SelectableColumn<
|
2884
|
+
[K in N]: M extends SelectableColumn<NonNullable<O[K]>> ? NonNullable<O[K]> extends XataRecord ? ForwardNullable<O[K], NestedValueAtColumn<NonNullable<O[K]>, M> & XataRecord> : ForwardNullable<O[K], NestedValueAtColumn<NonNullable<O[K]>, M>> : unknown;
|
2882
2885
|
} : unknown : Key extends DataProps<O> ? {
|
2883
|
-
[K in Key]:
|
2886
|
+
[K in Key]: NonNullable<O[K]> extends XataRecord ? ForwardNullable<O[K], SelectedPick<NonNullable<O[K]>, ['*']>> : O[K];
|
2884
2887
|
} : Key extends '*' ? {
|
2885
|
-
[K in StringKeys<O>]:
|
2888
|
+
[K in StringKeys<O>]: NonNullable<O[K]> extends XataRecord ? ForwardNullable<O[K], Link<NonNullable<O[K]>>> : O[K];
|
2886
2889
|
} : unknown;
|
2887
|
-
declare type
|
2888
|
-
declare type ForwardNullable<T, R> = T extends RemoveNullable<T> ? R : R | null;
|
2890
|
+
declare type ForwardNullable<T, R> = T extends NonNullable<T> ? R : R | null;
|
2889
2891
|
|
2890
2892
|
/**
|
2891
2893
|
* Represents an identifiable record from the database.
|
@@ -2950,9 +2952,9 @@ declare function isXataRecord(x: any): x is XataRecord & Record<string, unknown>
|
|
2950
2952
|
declare type EditableData<O extends BaseData> = {
|
2951
2953
|
[K in keyof O]: O[K] extends XataRecord ? {
|
2952
2954
|
id: string;
|
2953
|
-
} : NonNullable<O[K]> extends XataRecord ? {
|
2955
|
+
} | string : NonNullable<O[K]> extends XataRecord ? {
|
2954
2956
|
id: string;
|
2955
|
-
} | null | undefined : O[K];
|
2957
|
+
} | string | null | undefined : O[K];
|
2956
2958
|
};
|
2957
2959
|
|
2958
2960
|
/**
|
@@ -3380,6 +3382,7 @@ declare function isCursorPaginationOptions(options: Record<string, unknown> | un
|
|
3380
3382
|
declare class RecordArray<Result extends XataRecord> extends Array<Result> {
|
3381
3383
|
#private;
|
3382
3384
|
constructor(page: Paginable<any, Result>, overrideRecords?: Result[]);
|
3385
|
+
static parseConstructorParams(...args: any[]): any[];
|
3383
3386
|
/**
|
3384
3387
|
* Retrieve next page of records
|
3385
3388
|
*
|
@@ -3440,6 +3443,18 @@ declare abstract class Repository<Data extends BaseData, Record extends XataReco
|
|
3440
3443
|
* @returns The persisted records for the given ids (if a record could not be found it is not returned).
|
3441
3444
|
*/
|
3442
3445
|
abstract read(ids: string[]): Promise<Array<Readonly<SelectedPick<Record, ['*']>>>>;
|
3446
|
+
/**
|
3447
|
+
* Queries a single record from the table by the id in the object.
|
3448
|
+
* @param object Object containing the id of the record.
|
3449
|
+
* @returns The persisted record for the given id or null if the record could not be found.
|
3450
|
+
*/
|
3451
|
+
abstract read(object: Identifiable): Promise<Readonly<SelectedPick<Record, ['*']> | null>>;
|
3452
|
+
/**
|
3453
|
+
* Queries multiple records from the table by the ids in the objects.
|
3454
|
+
* @param objects Array of objects containing the ids of the records.
|
3455
|
+
* @returns The persisted records for the given ids (if a record could not be found it is not returned).
|
3456
|
+
*/
|
3457
|
+
abstract read(objects: Identifiable[]): Promise<Array<Readonly<SelectedPick<Record, ['*']>>>>;
|
3443
3458
|
/**
|
3444
3459
|
* Partially update a single record.
|
3445
3460
|
* @param object An object with its id and the columns to be updated.
|
@@ -3531,6 +3546,8 @@ declare class RestRepository<Data extends BaseData, Record extends XataRecord =
|
|
3531
3546
|
create(objects: EditableData<Data>[]): Promise<SelectedPick<Record, ['*']>[]>;
|
3532
3547
|
read(recordId: string): Promise<SelectedPick<Record, ['*']> | null>;
|
3533
3548
|
read(recordIds: string[]): Promise<Array<Readonly<SelectedPick<Record, ['*']>>>>;
|
3549
|
+
read(object: Identifiable): Promise<SelectedPick<Record, ['*']> | null>;
|
3550
|
+
read(objects: Identifiable[]): Promise<Array<Readonly<SelectedPick<Record, ['*']>>>>;
|
3534
3551
|
update(object: Partial<EditableData<Data>> & Identifiable): Promise<SelectedPick<Record, ['*']>>;
|
3535
3552
|
update(recordId: string, object: Partial<EditableData<Data>>): Promise<SelectedPick<Record, ['*']>>;
|
3536
3553
|
update(objects: Array<Partial<EditableData<Data>> & Identifiable>): Promise<SelectedPick<Record, ['*']>[]>;
|
package/dist/index.mjs
CHANGED
@@ -17,7 +17,8 @@ function toBase64(value) {
|
|
17
17
|
try {
|
18
18
|
return btoa(value);
|
19
19
|
} catch (err) {
|
20
|
-
|
20
|
+
const buf = Buffer;
|
21
|
+
return buf.from(value).toString("base64");
|
21
22
|
}
|
22
23
|
}
|
23
24
|
|
@@ -73,21 +74,28 @@ function getFetchImplementation(userFetch) {
|
|
73
74
|
return fetchImpl;
|
74
75
|
}
|
75
76
|
|
77
|
+
const VERSION = "0.13.3";
|
78
|
+
|
76
79
|
class ErrorWithCause extends Error {
|
77
80
|
constructor(message, options) {
|
78
81
|
super(message, options);
|
79
82
|
}
|
80
83
|
}
|
81
84
|
class FetcherError extends ErrorWithCause {
|
82
|
-
constructor(status, data) {
|
85
|
+
constructor(status, data, requestId) {
|
83
86
|
super(getMessage(data));
|
84
87
|
this.status = status;
|
85
88
|
this.errors = isBulkError(data) ? data.errors : void 0;
|
89
|
+
this.requestId = requestId;
|
86
90
|
if (data instanceof Error) {
|
87
91
|
this.stack = data.stack;
|
88
92
|
this.cause = data.cause;
|
89
93
|
}
|
90
94
|
}
|
95
|
+
toString() {
|
96
|
+
const error = super.toString();
|
97
|
+
return `[${this.status}] (${this.requestId ?? "Unknown"}): ${error}`;
|
98
|
+
}
|
91
99
|
}
|
92
100
|
function isBulkError(error) {
|
93
101
|
return isObject(error) && Array.isArray(error.errors);
|
@@ -110,7 +118,12 @@ function getMessage(data) {
|
|
110
118
|
}
|
111
119
|
|
112
120
|
const resolveUrl = (url, queryParams = {}, pathParams = {}) => {
|
113
|
-
const
|
121
|
+
const cleanQueryParams = Object.entries(queryParams).reduce((acc, [key, value]) => {
|
122
|
+
if (value === void 0 || value === null)
|
123
|
+
return acc;
|
124
|
+
return { ...acc, [key]: value };
|
125
|
+
}, {});
|
126
|
+
const query = new URLSearchParams(cleanQueryParams).toString();
|
114
127
|
const queryString = query.length > 0 ? `?${query}` : "";
|
115
128
|
return url.replace(/\{\w*\}/g, (key) => pathParams[key.slice(1, -1)]) + queryString;
|
116
129
|
};
|
@@ -150,6 +163,7 @@ async function fetch$1({
|
|
150
163
|
body: body ? JSON.stringify(body) : void 0,
|
151
164
|
headers: {
|
152
165
|
"Content-Type": "application/json",
|
166
|
+
"User-Agent": `Xata client-ts/${VERSION}`,
|
153
167
|
...headers,
|
154
168
|
...hostHeader(fullUrl),
|
155
169
|
Authorization: `Bearer ${apiKey}`
|
@@ -158,14 +172,15 @@ async function fetch$1({
|
|
158
172
|
if (response.status === 204) {
|
159
173
|
return {};
|
160
174
|
}
|
175
|
+
const requestId = response.headers?.get("x-request-id") ?? void 0;
|
161
176
|
try {
|
162
177
|
const jsonResponse = await response.json();
|
163
178
|
if (response.ok) {
|
164
179
|
return jsonResponse;
|
165
180
|
}
|
166
|
-
throw new FetcherError(response.status, jsonResponse);
|
181
|
+
throw new FetcherError(response.status, jsonResponse, requestId);
|
167
182
|
} catch (error) {
|
168
|
-
throw new FetcherError(response.status, error);
|
183
|
+
throw new FetcherError(response.status, error, requestId);
|
169
184
|
}
|
170
185
|
}
|
171
186
|
|
@@ -689,10 +704,10 @@ class DatabaseApi {
|
|
689
704
|
...this.extraProps
|
690
705
|
});
|
691
706
|
}
|
692
|
-
resolveBranch(workspace, dbName, gitBranch) {
|
707
|
+
resolveBranch(workspace, dbName, gitBranch, fallbackBranch) {
|
693
708
|
return operationsByTag.database.resolveBranch({
|
694
709
|
pathParams: { workspace, dbName },
|
695
|
-
queryParams: { gitBranch },
|
710
|
+
queryParams: { gitBranch, fallbackBranch },
|
696
711
|
...this.extraProps
|
697
712
|
});
|
698
713
|
}
|
@@ -976,10 +991,20 @@ function isCursorPaginationOptions(options) {
|
|
976
991
|
}
|
977
992
|
const _RecordArray = class extends Array {
|
978
993
|
constructor(page, overrideRecords) {
|
979
|
-
super(...overrideRecords
|
994
|
+
super(..._RecordArray.parseConstructorParams(page, overrideRecords));
|
980
995
|
__privateAdd$6(this, _page, void 0);
|
981
996
|
__privateSet$5(this, _page, page);
|
982
997
|
}
|
998
|
+
static parseConstructorParams(...args) {
|
999
|
+
if (args.length === 1 && typeof args[0] === "number") {
|
1000
|
+
return new Array(args[0]);
|
1001
|
+
}
|
1002
|
+
if (args.length <= 2 && isObject(args[0]?.meta) && Array.isArray(args[1] ?? [])) {
|
1003
|
+
const result = args[1] ?? args[0].records ?? [];
|
1004
|
+
return new Array(...result);
|
1005
|
+
}
|
1006
|
+
return new Array(...args);
|
1007
|
+
}
|
983
1008
|
async nextPage(size, offset) {
|
984
1009
|
const newPage = await __privateGet$6(this, _page).nextPage(size, offset);
|
985
1010
|
return new _RecordArray(newPage);
|
@@ -1250,9 +1275,29 @@ class RestRepository extends Query {
|
|
1250
1275
|
if (Array.isArray(a)) {
|
1251
1276
|
if (a.length === 0)
|
1252
1277
|
return [];
|
1253
|
-
const
|
1254
|
-
|
1255
|
-
|
1278
|
+
const [itemsWithoutIds, itemsWithIds, order] = a.reduce(([accWithoutIds, accWithIds, accOrder], item) => {
|
1279
|
+
const condition = isString(item.id);
|
1280
|
+
accOrder.push(condition);
|
1281
|
+
if (condition) {
|
1282
|
+
accWithIds.push(item);
|
1283
|
+
} else {
|
1284
|
+
accWithoutIds.push(item);
|
1285
|
+
}
|
1286
|
+
return [accWithoutIds, accWithIds, accOrder];
|
1287
|
+
}, [[], [], []]);
|
1288
|
+
const recordsWithoutId = await __privateMethod$2(this, _bulkInsertTableRecords, bulkInsertTableRecords_fn).call(this, itemsWithoutIds);
|
1289
|
+
await Promise.all(recordsWithoutId.map((record) => __privateMethod$2(this, _setCacheRecord, setCacheRecord_fn).call(this, record)));
|
1290
|
+
if (itemsWithIds.length > 100) {
|
1291
|
+
console.warn("Bulk create operation with id is not optimized in the Xata API yet, this request might be slow");
|
1292
|
+
}
|
1293
|
+
const recordsWithId = await Promise.all(itemsWithIds.map((object) => this.create(object)));
|
1294
|
+
return order.map((condition) => {
|
1295
|
+
if (condition) {
|
1296
|
+
return recordsWithId.shift();
|
1297
|
+
} else {
|
1298
|
+
return recordsWithoutId.shift();
|
1299
|
+
}
|
1300
|
+
}).filter((record) => !!record);
|
1256
1301
|
}
|
1257
1302
|
if (isString(a) && isObject(b)) {
|
1258
1303
|
if (a === "")
|
@@ -1279,16 +1324,18 @@ class RestRepository extends Query {
|
|
1279
1324
|
if (Array.isArray(a)) {
|
1280
1325
|
if (a.length === 0)
|
1281
1326
|
return [];
|
1282
|
-
|
1327
|
+
const ids = a.map((item) => isString(item) ? item : item.id).filter((id2) => isString(id2));
|
1328
|
+
return this.getAll({ filter: { id: { $any: ids } } });
|
1283
1329
|
}
|
1284
|
-
|
1285
|
-
|
1330
|
+
const id = isString(a) ? a : a.id;
|
1331
|
+
if (isString(id)) {
|
1332
|
+
const cacheRecord = await __privateMethod$2(this, _getCacheRecord, getCacheRecord_fn).call(this, id);
|
1286
1333
|
if (cacheRecord)
|
1287
1334
|
return cacheRecord;
|
1288
1335
|
const fetchProps = await __privateGet$4(this, _getFetchProps).call(this);
|
1289
1336
|
try {
|
1290
1337
|
const response = await getRecord({
|
1291
|
-
pathParams: { workspace: "{workspaceId}", dbBranchName: "{dbBranch}", tableName: __privateGet$4(this, _table), recordId:
|
1338
|
+
pathParams: { workspace: "{workspaceId}", dbBranchName: "{dbBranch}", tableName: __privateGet$4(this, _table), recordId: id },
|
1292
1339
|
...fetchProps
|
1293
1340
|
});
|
1294
1341
|
const schema = await __privateMethod$2(this, _getSchema$1, getSchema_fn$1).call(this);
|
@@ -1460,7 +1507,7 @@ bulkInsertTableRecords_fn = async function(objects) {
|
|
1460
1507
|
body: { records },
|
1461
1508
|
...fetchProps
|
1462
1509
|
});
|
1463
|
-
const finalObjects = await this.
|
1510
|
+
const finalObjects = await this.read(response.recordIDs);
|
1464
1511
|
if (finalObjects.length !== objects.length) {
|
1465
1512
|
throw new Error("The server failed to save some records");
|
1466
1513
|
}
|
@@ -1864,10 +1911,7 @@ async function getDatabaseBranch(branch, options) {
|
|
1864
1911
|
apiUrl: databaseURL,
|
1865
1912
|
fetchImpl: getFetchImplementation(options?.fetchImpl),
|
1866
1913
|
workspacesApiUrl: `${protocol}//${host}`,
|
1867
|
-
pathParams: {
|
1868
|
-
dbBranchName,
|
1869
|
-
workspace
|
1870
|
-
}
|
1914
|
+
pathParams: { dbBranchName, workspace }
|
1871
1915
|
});
|
1872
1916
|
} catch (err) {
|
1873
1917
|
if (isObject(err) && err.status === 404)
|