@xata.io/client 0.1.2 → 0.1.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/dist/index.d.ts +5 -14
- package/dist/index.js +40 -28
- package/dist/index.test.js +1 -1
- package/package.json +1 -1
- package/src/index.test.ts +1 -1
- package/src/index.ts +47 -35
package/dist/index.d.ts
CHANGED
@@ -57,11 +57,11 @@ declare type QueryOrConstraint<T, R> = Query<T, R> | Constraint<T>;
|
|
57
57
|
export declare class Query<T, R = T> {
|
58
58
|
table: string;
|
59
59
|
repository: Repository<T>;
|
60
|
-
readonly
|
61
|
-
readonly
|
62
|
-
readonly
|
63
|
-
readonly
|
64
|
-
readonly
|
60
|
+
readonly $any?: QueryOrConstraint<T, R>[];
|
61
|
+
readonly $all?: QueryOrConstraint<T, R>[];
|
62
|
+
readonly $not?: QueryOrConstraint<T, R>[];
|
63
|
+
readonly $none?: QueryOrConstraint<T, R>[];
|
64
|
+
readonly $sort?: Record<string, SortDirection>;
|
65
65
|
constructor(repository: Repository<T> | null, table: string, data: Partial<Query<T, R>>, parent?: Query<T, R>);
|
66
66
|
any(...queries: Query<T, R>[]): Query<T, R>;
|
67
67
|
all(...queries: Query<T, R>[]): Query<T, R>;
|
@@ -74,15 +74,6 @@ export declare class Query<T, R = T> {
|
|
74
74
|
getOne(options?: BulkQueryOptions<T>): Promise<R | null>;
|
75
75
|
deleteAll(): Promise<number>;
|
76
76
|
include(columns: Include<T>): this;
|
77
|
-
toJSON(): {
|
78
|
-
_filter: {
|
79
|
-
_any: QueryOrConstraint<T, R>[] | undefined;
|
80
|
-
_all: QueryOrConstraint<T, R>[] | undefined;
|
81
|
-
_not: QueryOrConstraint<T, R>[] | undefined;
|
82
|
-
_none: QueryOrConstraint<T, R>[] | undefined;
|
83
|
-
} | undefined;
|
84
|
-
_sort: Record<string, SortDirection> | undefined;
|
85
|
-
};
|
86
77
|
}
|
87
78
|
export declare abstract class Repository<T> extends Query<T, Selectable<T>> {
|
88
79
|
select<K extends keyof Selectable<T>>(...columns: K[]): Query<T, Select<T, K>>;
|
package/dist/index.js
CHANGED
@@ -34,7 +34,12 @@ const pattern = (value) => ({ $pattern: value });
|
|
34
34
|
exports.pattern = pattern;
|
35
35
|
const isNot = (value) => ({ $isNot: value });
|
36
36
|
exports.isNot = isNot;
|
37
|
-
const contains = (value) =>
|
37
|
+
const contains = (value) => {
|
38
|
+
// if (Array.isArray(value)) {
|
39
|
+
// return { $all: value.map(item => ({ $contains: item as string })) }
|
40
|
+
// }
|
41
|
+
return { $contains: value };
|
42
|
+
};
|
38
43
|
exports.contains = contains;
|
39
44
|
// TODO: these can only be applied to columns of type "multiple"
|
40
45
|
const includes = (value) => ({ $includes: value });
|
@@ -56,11 +61,11 @@ class Query {
|
|
56
61
|
this.table = table;
|
57
62
|
// For some reason Object.assign(this, parent) didn't work in this case
|
58
63
|
// so doing all this manually:
|
59
|
-
this
|
60
|
-
this
|
61
|
-
this
|
62
|
-
this
|
63
|
-
this
|
64
|
+
this.$any = parent === null || parent === void 0 ? void 0 : parent.$any;
|
65
|
+
this.$all = parent === null || parent === void 0 ? void 0 : parent.$all;
|
66
|
+
this.$not = parent === null || parent === void 0 ? void 0 : parent.$not;
|
67
|
+
this.$none = parent === null || parent === void 0 ? void 0 : parent.$none;
|
68
|
+
this.$sort = parent === null || parent === void 0 ? void 0 : parent.$sort;
|
64
69
|
Object.assign(this, data);
|
65
70
|
// These bindings are used to support deconstructing
|
66
71
|
// const { any, not, filter, sort } = xata.users.query()
|
@@ -70,25 +75,27 @@ class Query {
|
|
70
75
|
this.filter = this.filter.bind(this);
|
71
76
|
this.sort = this.sort.bind(this);
|
72
77
|
this.none = this.none.bind(this);
|
78
|
+
Object.defineProperty(this, 'table', { enumerable: false });
|
79
|
+
Object.defineProperty(this, 'repository', { enumerable: false });
|
73
80
|
}
|
74
81
|
any(...queries) {
|
75
82
|
return new Query(this.repository, this.table, {
|
76
|
-
|
83
|
+
$any: (this.$any || []).concat(queries)
|
77
84
|
}, this);
|
78
85
|
}
|
79
86
|
all(...queries) {
|
80
87
|
return new Query(this.repository, this.table, {
|
81
|
-
|
88
|
+
$all: (this.$all || []).concat(queries)
|
82
89
|
}, this);
|
83
90
|
}
|
84
91
|
not(...queries) {
|
85
92
|
return new Query(this.repository, this.table, {
|
86
|
-
|
93
|
+
$not: (this.$not || []).concat(queries)
|
87
94
|
}, this);
|
88
95
|
}
|
89
96
|
none(...queries) {
|
90
97
|
return new Query(this.repository, this.table, {
|
91
|
-
|
98
|
+
$none: (this.$none || []).concat(queries)
|
92
99
|
}, this);
|
93
100
|
}
|
94
101
|
filter(a, b) {
|
@@ -99,21 +106,21 @@ class Query {
|
|
99
106
|
queries.push({ [column]: constraint });
|
100
107
|
}
|
101
108
|
return new Query(this.repository, this.table, {
|
102
|
-
|
109
|
+
$all: (this.$all || []).concat(queries)
|
103
110
|
}, this);
|
104
111
|
}
|
105
112
|
else {
|
106
113
|
const column = a;
|
107
114
|
const value = b;
|
108
115
|
return new Query(this.repository, this.table, {
|
109
|
-
|
116
|
+
$all: (this.$all || []).concat({ [column]: value })
|
110
117
|
}, this);
|
111
118
|
}
|
112
119
|
}
|
113
120
|
sort(column, direction) {
|
114
|
-
const sort = Object.assign(Object.assign({}, this
|
121
|
+
const sort = Object.assign(Object.assign({}, this.$sort), { [column]: direction });
|
115
122
|
const q = new Query(this.repository, this.table, {
|
116
|
-
|
123
|
+
$sort: sort
|
117
124
|
}, this);
|
118
125
|
return q;
|
119
126
|
}
|
@@ -142,18 +149,6 @@ class Query {
|
|
142
149
|
// TODO
|
143
150
|
return this;
|
144
151
|
}
|
145
|
-
toJSON() {
|
146
|
-
const _filter = {
|
147
|
-
_any: this._any,
|
148
|
-
_all: this._all,
|
149
|
-
_not: this._not,
|
150
|
-
_none: this._none
|
151
|
-
};
|
152
|
-
return {
|
153
|
-
_filter: Object.values(_filter).some(Boolean) ? _filter : undefined,
|
154
|
-
_sort: this._sort
|
155
|
-
};
|
156
|
-
}
|
157
152
|
}
|
158
153
|
exports.Query = Query;
|
159
154
|
class Repository extends Query {
|
@@ -228,7 +223,14 @@ class RestRepository extends Repository {
|
|
228
223
|
}
|
229
224
|
create(object) {
|
230
225
|
return __awaiter(this, void 0, void 0, function* () {
|
231
|
-
const
|
226
|
+
const body = Object.assign({}, object);
|
227
|
+
for (const key of Object.keys(body)) {
|
228
|
+
const value = body[key];
|
229
|
+
if (value && typeof value === 'object' && typeof value._id === 'string') {
|
230
|
+
body[key] = value._id;
|
231
|
+
}
|
232
|
+
}
|
233
|
+
const obj = yield this.request('POST', `/tables/${this.table}/data`, body);
|
232
234
|
return this.client.initObject(this.table, obj);
|
233
235
|
});
|
234
236
|
}
|
@@ -258,7 +260,17 @@ class RestRepository extends Repository {
|
|
258
260
|
}
|
259
261
|
query(query) {
|
260
262
|
return __awaiter(this, void 0, void 0, function* () {
|
261
|
-
const
|
263
|
+
const filter = {
|
264
|
+
$any: query.$any,
|
265
|
+
$all: query.$all,
|
266
|
+
$not: query.$not,
|
267
|
+
$none: query.$none
|
268
|
+
};
|
269
|
+
const body = {
|
270
|
+
filter: Object.values(filter).some(Boolean) ? filter : undefined,
|
271
|
+
sort: query.$sort
|
272
|
+
};
|
273
|
+
const result = yield this.request('POST', `/tables/${this.table}/query`, body);
|
262
274
|
return result.records.map((record) => this.client.initObject(this.table, record));
|
263
275
|
});
|
264
276
|
}
|
package/dist/index.test.js
CHANGED
@@ -119,7 +119,7 @@ describe('query', () => {
|
|
119
119
|
expectRequest(expected, () => users.getMany(), { records: [] });
|
120
120
|
}));
|
121
121
|
test('query with one filter', () => __awaiter(void 0, void 0, void 0, function* () {
|
122
|
-
const expected = { method: 'POST', path: '/tables/users/query', body: {
|
122
|
+
const expected = { method: 'POST', path: '/tables/users/query', body: { filter: { $all: [{ name: 'foo' }] } } };
|
123
123
|
expectRequest(expected, () => users.filter('name', 'foo').getMany(), { records: [] });
|
124
124
|
}));
|
125
125
|
});
|
package/package.json
CHANGED
package/src/index.test.ts
CHANGED
@@ -138,7 +138,7 @@ describe('query', () => {
|
|
138
138
|
});
|
139
139
|
|
140
140
|
test('query with one filter', async () => {
|
141
|
-
const expected = { method: 'POST', path: '/tables/users/query', body: {
|
141
|
+
const expected = { method: 'POST', path: '/tables/users/query', body: { filter: { $all: [{ name: 'foo' }] } } };
|
142
142
|
expectRequest(expected, () => users.filter('name', 'foo').getMany(), { records: [] });
|
143
143
|
});
|
144
144
|
});
|
package/src/index.ts
CHANGED
@@ -52,7 +52,7 @@ type Operator =
|
|
52
52
|
|
53
53
|
// TODO: restrict constraints depending on type?
|
54
54
|
// E.g. startsWith cannot be used with numbers
|
55
|
-
type Constraint<T> = Partial<Record<Operator, T>>;
|
55
|
+
type Constraint<T> = Partial<Record<Operator, T>>; // | {$all: Record<'$contains', string>[]};
|
56
56
|
|
57
57
|
type ComparableType = number | Date;
|
58
58
|
|
@@ -68,7 +68,12 @@ export const startsWith = (value: string): Constraint<string> => ({ $startsWith:
|
|
68
68
|
export const endsWith = (value: string): Constraint<string> => ({ $endsWith: value });
|
69
69
|
export const pattern = (value: string): Constraint<string> => ({ $pattern: value });
|
70
70
|
export const isNot = <T>(value: T): Constraint<T> => ({ $isNot: value });
|
71
|
-
export const contains = <T>(value: T): Constraint<T> =>
|
71
|
+
export const contains = <T>(value: T): Constraint<T> => {
|
72
|
+
// if (Array.isArray(value)) {
|
73
|
+
// return { $all: value.map(item => ({ $contains: item as string })) }
|
74
|
+
// }
|
75
|
+
return { $contains: value };
|
76
|
+
};
|
72
77
|
|
73
78
|
// TODO: these can only be applied to columns of type "multiple"
|
74
79
|
export const includes = (value: string): Constraint<string> => ({ $includes: value });
|
@@ -96,11 +101,11 @@ export class Query<T, R = T> {
|
|
96
101
|
table: string;
|
97
102
|
repository: Repository<T>;
|
98
103
|
|
99
|
-
readonly
|
100
|
-
readonly
|
101
|
-
readonly
|
102
|
-
readonly
|
103
|
-
readonly
|
104
|
+
readonly $any?: QueryOrConstraint<T, R>[];
|
105
|
+
readonly $all?: QueryOrConstraint<T, R>[];
|
106
|
+
readonly $not?: QueryOrConstraint<T, R>[];
|
107
|
+
readonly $none?: QueryOrConstraint<T, R>[];
|
108
|
+
readonly $sort?: Record<string, SortDirection>;
|
104
109
|
|
105
110
|
constructor(repository: Repository<T> | null, table: string, data: Partial<Query<T, R>>, parent?: Query<T, R>) {
|
106
111
|
if (repository) {
|
@@ -112,11 +117,11 @@ export class Query<T, R = T> {
|
|
112
117
|
|
113
118
|
// For some reason Object.assign(this, parent) didn't work in this case
|
114
119
|
// so doing all this manually:
|
115
|
-
this
|
116
|
-
this
|
117
|
-
this
|
118
|
-
this
|
119
|
-
this
|
120
|
+
this.$any = parent?.$any;
|
121
|
+
this.$all = parent?.$all;
|
122
|
+
this.$not = parent?.$not;
|
123
|
+
this.$none = parent?.$none;
|
124
|
+
this.$sort = parent?.$sort;
|
120
125
|
|
121
126
|
Object.assign(this, data);
|
122
127
|
// These bindings are used to support deconstructing
|
@@ -127,6 +132,9 @@ export class Query<T, R = T> {
|
|
127
132
|
this.filter = this.filter.bind(this);
|
128
133
|
this.sort = this.sort.bind(this);
|
129
134
|
this.none = this.none.bind(this);
|
135
|
+
|
136
|
+
Object.defineProperty(this, 'table', { enumerable: false });
|
137
|
+
Object.defineProperty(this, 'repository', { enumerable: false });
|
130
138
|
}
|
131
139
|
|
132
140
|
any(...queries: Query<T, R>[]): Query<T, R> {
|
@@ -134,7 +142,7 @@ export class Query<T, R = T> {
|
|
134
142
|
this.repository,
|
135
143
|
this.table,
|
136
144
|
{
|
137
|
-
|
145
|
+
$any: (this.$any || []).concat(queries)
|
138
146
|
},
|
139
147
|
this
|
140
148
|
);
|
@@ -145,7 +153,7 @@ export class Query<T, R = T> {
|
|
145
153
|
this.repository,
|
146
154
|
this.table,
|
147
155
|
{
|
148
|
-
|
156
|
+
$all: (this.$all || []).concat(queries)
|
149
157
|
},
|
150
158
|
this
|
151
159
|
);
|
@@ -156,7 +164,7 @@ export class Query<T, R = T> {
|
|
156
164
|
this.repository,
|
157
165
|
this.table,
|
158
166
|
{
|
159
|
-
|
167
|
+
$not: (this.$not || []).concat(queries)
|
160
168
|
},
|
161
169
|
this
|
162
170
|
);
|
@@ -167,7 +175,7 @@ export class Query<T, R = T> {
|
|
167
175
|
this.repository,
|
168
176
|
this.table,
|
169
177
|
{
|
170
|
-
|
178
|
+
$none: (this.$none || []).concat(queries)
|
171
179
|
},
|
172
180
|
this
|
173
181
|
);
|
@@ -186,7 +194,7 @@ export class Query<T, R = T> {
|
|
186
194
|
this.repository,
|
187
195
|
this.table,
|
188
196
|
{
|
189
|
-
|
197
|
+
$all: (this.$all || []).concat(queries)
|
190
198
|
},
|
191
199
|
this
|
192
200
|
);
|
@@ -197,7 +205,7 @@ export class Query<T, R = T> {
|
|
197
205
|
this.repository,
|
198
206
|
this.table,
|
199
207
|
{
|
200
|
-
|
208
|
+
$all: (this.$all || []).concat({ [column]: value })
|
201
209
|
},
|
202
210
|
this
|
203
211
|
);
|
@@ -205,12 +213,12 @@ export class Query<T, R = T> {
|
|
205
213
|
}
|
206
214
|
|
207
215
|
sort<F extends keyof T>(column: F, direction: SortDirection): Query<T, R> {
|
208
|
-
const sort = { ...this
|
216
|
+
const sort = { ...this.$sort, [column]: direction };
|
209
217
|
const q = new Query<T, R>(
|
210
218
|
this.repository,
|
211
219
|
this.table,
|
212
220
|
{
|
213
|
-
|
221
|
+
$sort: sort
|
214
222
|
},
|
215
223
|
this
|
216
224
|
);
|
@@ -240,19 +248,6 @@ export class Query<T, R = T> {
|
|
240
248
|
// TODO
|
241
249
|
return this;
|
242
250
|
}
|
243
|
-
|
244
|
-
toJSON() {
|
245
|
-
const _filter = {
|
246
|
-
_any: this._any,
|
247
|
-
_all: this._all,
|
248
|
-
_not: this._not,
|
249
|
-
_none: this._none
|
250
|
-
};
|
251
|
-
return {
|
252
|
-
_filter: Object.values(_filter).some(Boolean) ? _filter : undefined,
|
253
|
-
_sort: this._sort
|
254
|
-
};
|
255
|
-
}
|
256
251
|
}
|
257
252
|
|
258
253
|
export abstract class Repository<T> extends Query<T, Selectable<T>> {
|
@@ -337,7 +332,14 @@ export class RestRepository<T> extends Repository<T> {
|
|
337
332
|
}
|
338
333
|
|
339
334
|
async create(object: T): Promise<T> {
|
340
|
-
const
|
335
|
+
const body = { ...object } as Record<string, unknown>;
|
336
|
+
for (const key of Object.keys(body)) {
|
337
|
+
const value = body[key];
|
338
|
+
if (value && typeof value === 'object' && typeof (value as Record<string, unknown>)._id === 'string') {
|
339
|
+
body[key] = (value as XataRecord)._id;
|
340
|
+
}
|
341
|
+
}
|
342
|
+
const obj = await this.request('POST', `/tables/${this.table}/data`, body);
|
341
343
|
return this.client.initObject(this.table, obj);
|
342
344
|
}
|
343
345
|
|
@@ -361,7 +363,17 @@ export class RestRepository<T> extends Repository<T> {
|
|
361
363
|
}
|
362
364
|
|
363
365
|
async query<R>(query: Query<T, R>): Promise<R[]> {
|
364
|
-
const
|
366
|
+
const filter = {
|
367
|
+
$any: query.$any,
|
368
|
+
$all: query.$all,
|
369
|
+
$not: query.$not,
|
370
|
+
$none: query.$none
|
371
|
+
};
|
372
|
+
const body = {
|
373
|
+
filter: Object.values(filter).some(Boolean) ? filter : undefined,
|
374
|
+
sort: query.$sort
|
375
|
+
};
|
376
|
+
const result = await this.request('POST', `/tables/${this.table}/query`, body);
|
365
377
|
return result.records.map((record: object) => this.client.initObject(this.table, record));
|
366
378
|
}
|
367
379
|
}
|