@xata.io/client
Advanced tools
Comparing version 0.0.0-alpha.4c6e3c2 to 0.0.0-alpha.4fa02de
@@ -0,1 +1,5 @@ | ||
import { FetchImpl } from './api/fetcher'; | ||
import { Page } from './schema/pagination'; | ||
import { Query, QueryOptions } from './schema/query'; | ||
import { Selectable, SelectableColumn, Select } from './schema/selection'; | ||
export interface XataRecord { | ||
@@ -7,162 +11,24 @@ id: string; | ||
read(): Promise<this>; | ||
update(data: Selectable<this>): Promise<this>; | ||
update(data: Partial<Selectable<this>>): Promise<this>; | ||
delete(): Promise<void>; | ||
} | ||
export declare type Queries<T> = { | ||
[key in keyof T as T[key] extends Query<any> ? key : never]: T[key]; | ||
}; | ||
export declare type OmitQueries<T> = { | ||
[key in keyof T as T[key] extends Query<any> ? never : key]: T[key]; | ||
}; | ||
export declare type OmitLinks<T> = { | ||
[key in keyof T as T[key] extends XataRecord ? never : key]: T[key]; | ||
}; | ||
export declare type OmitMethods<T> = { | ||
[key in keyof T as T[key] extends Function ? never : key]: T[key]; | ||
}; | ||
export declare type Selectable<T> = Omit<OmitQueries<OmitMethods<T>>, 'id' | 'xata'>; | ||
declare type StringKeys<O> = Extract<keyof O, string>; | ||
declare type Values<O> = O[keyof O]; | ||
export declare type SelectableColumn<O> = '*' | (O extends Array<unknown> ? never : O extends Record<string, any> ? '*' | Values<{ | ||
[K in StringKeys<O>]: O[K] extends Record<string, any> ? `${K}.${SelectableColumn<O[K]>}` : K; | ||
}> : ''); | ||
declare type UnionToIntersection<T> = (T extends any ? (x: T) => any : never) extends (x: infer R) => any ? R : never; | ||
export declare type Select<T, K extends SelectableColumn<T>> = UnionToIntersection<K extends keyof T ? Pick<T, K> : T> & Queries<T> & XataRecord; | ||
export declare type Include<T> = { | ||
[key in keyof T as T[key] extends XataRecord ? key : never]?: boolean | Array<keyof Selectable<T[key]>>; | ||
}; | ||
declare type SortDirection = 'asc' | 'desc'; | ||
declare type SortFilterExtended<T> = { | ||
column: keyof T; | ||
direction?: SortDirection; | ||
}; | ||
declare type SortFilter<T> = SortFilterExtended<T> | keyof T; | ||
declare type Operator = '$gt' | '$lt' | '$ge' | '$le' | '$exists' | '$notExists' | '$endsWith' | '$startsWith' | '$pattern' | '$is' | '$isNot' | '$contains' | '$includes' | '$includesSubstring' | '$includesPattern' | '$includesAll'; | ||
declare type Constraint<T> = { | ||
[key in Operator]?: T; | ||
}; | ||
declare type DeepConstraint<T> = T extends Record<string, any> ? { | ||
[key in keyof T]?: T[key] | DeepConstraint<T[key]>; | ||
} : Constraint<T>; | ||
declare type ComparableType = number | Date; | ||
export declare const gt: <T extends ComparableType>(value: T) => Constraint<T>; | ||
export declare const ge: <T extends ComparableType>(value: T) => Constraint<T>; | ||
export declare const gte: <T extends ComparableType>(value: T) => Constraint<T>; | ||
export declare const lt: <T extends ComparableType>(value: T) => Constraint<T>; | ||
export declare const lte: <T extends ComparableType>(value: T) => Constraint<T>; | ||
export declare const le: <T extends ComparableType>(value: T) => Constraint<T>; | ||
export declare const exists: (column: string) => Constraint<string>; | ||
export declare const notExists: (column: string) => Constraint<string>; | ||
export declare const startsWith: (value: string) => Constraint<string>; | ||
export declare const endsWith: (value: string) => Constraint<string>; | ||
export declare const pattern: (value: string) => Constraint<string>; | ||
export declare const is: <T>(value: T) => Constraint<T>; | ||
export declare const isNot: <T>(value: T) => Constraint<T>; | ||
export declare const contains: <T>(value: T) => Constraint<T>; | ||
export declare const includes: (value: string) => Constraint<string>; | ||
export declare const includesSubstring: (value: string) => Constraint<string>; | ||
export declare const includesPattern: (value: string) => Constraint<string>; | ||
export declare const includesAll: (value: string) => Constraint<string>; | ||
declare type FilterConstraints<T> = { | ||
[key in keyof T]?: T[key] extends Record<string, any> ? FilterConstraints<T[key]> : T[key] | DeepConstraint<T[key]>; | ||
}; | ||
declare type CursorNavigationOptions = { | ||
first?: string; | ||
} | { | ||
last?: string; | ||
} | { | ||
after?: string; | ||
before?: string; | ||
}; | ||
declare type OffsetNavigationOptions = { | ||
size?: number; | ||
offset?: number; | ||
}; | ||
declare type PaginationOptions = CursorNavigationOptions & OffsetNavigationOptions; | ||
declare type BulkQueryOptions<T> = { | ||
page?: PaginationOptions; | ||
columns?: Array<keyof Selectable<T>>; | ||
sort?: SortFilter<T> | SortFilter<T>[]; | ||
}; | ||
declare type QueryOrConstraint<T extends XataRecord, R extends XataRecord> = Query<T, R> | Constraint<T>; | ||
declare type QueryMeta = { | ||
page: { | ||
cursor: string; | ||
more: boolean; | ||
}; | ||
}; | ||
interface BasePage<T extends XataRecord, R extends XataRecord> { | ||
query: Query<T, R>; | ||
meta: QueryMeta; | ||
records: R[]; | ||
nextPage(size?: number, offset?: number): Promise<Page<T, R>>; | ||
previousPage(size?: number, offset?: number): Promise<Page<T, R>>; | ||
firstPage(size?: number, offset?: number): Promise<Page<T, R>>; | ||
lastPage(size?: number, offset?: number): Promise<Page<T, R>>; | ||
hasNextPage(): boolean; | ||
} | ||
declare class Page<T extends XataRecord, R extends XataRecord> implements BasePage<T, R> { | ||
readonly query: Query<T, R>; | ||
readonly meta: QueryMeta; | ||
readonly records: R[]; | ||
constructor(query: Query<T, R>, meta: QueryMeta, records?: R[]); | ||
nextPage(size?: number, offset?: number): Promise<Page<T, R>>; | ||
previousPage(size?: number, offset?: number): Promise<Page<T, R>>; | ||
firstPage(size?: number, offset?: number): Promise<Page<T, R>>; | ||
lastPage(size?: number, offset?: number): Promise<Page<T, R>>; | ||
hasNextPage(): boolean; | ||
} | ||
export declare class Query<T extends XataRecord, R extends XataRecord = T> implements BasePage<T, R> { | ||
table: string; | ||
repository: Repository<T>; | ||
readonly $any?: QueryOrConstraint<T, R>[]; | ||
readonly $all?: QueryOrConstraint<T, R>[]; | ||
readonly $not?: QueryOrConstraint<T, R>[]; | ||
readonly $none?: QueryOrConstraint<T, R>[]; | ||
readonly $sort?: Record<string, SortDirection>; | ||
readonly columns: SelectableColumn<T>[]; | ||
readonly query: Query<T, R>; | ||
readonly meta: QueryMeta; | ||
readonly records: R[]; | ||
constructor(repository: Repository<T> | null, table: string, data: Partial<Query<T, R>>, parent?: Query<T, R>); | ||
any(...queries: Query<T, R>[]): Query<T, R>; | ||
all(...queries: Query<T, R>[]): Query<T, R>; | ||
not(...queries: Query<T, R>[]): Query<T, R>; | ||
none(...queries: Query<T, R>[]): Query<T, R>; | ||
filter(constraints: FilterConstraints<T>): Query<T, R>; | ||
filter<F extends keyof T>(column: F, value: FilterConstraints<T[F]> | DeepConstraint<T[F]>): Query<T, R>; | ||
sort<F extends keyof T>(column: F, direction: SortDirection): Query<T, R>; | ||
getPaginated<Options extends BulkQueryOptions<T>>(options?: Options): Promise<Page<T, typeof options['columns'] extends SelectableColumn<T>[] ? Select<T, typeof options['columns'][number]> : R>>; | ||
[Symbol.asyncIterator](): AsyncIterableIterator<R>; | ||
getIterator(chunk: number, options?: Omit<BulkQueryOptions<T>, 'page'>): AsyncGenerator<R[]>; | ||
getMany<Options extends BulkQueryOptions<T>>(options?: Options): Promise<(typeof options['columns'] extends SelectableColumn<T>[] ? Select<T, typeof options['columns'][number]> : R)[]>; | ||
getOne<Options extends Omit<BulkQueryOptions<T>, 'page'>>(options?: Options): Promise<(typeof options['columns'] extends SelectableColumn<T>[] ? Select<T, typeof options['columns'][number]> : R) | null>; | ||
deleteAll(): Promise<number>; | ||
nextPage(size?: number, offset?: number): Promise<Page<T, R>>; | ||
previousPage(size?: number, offset?: number): Promise<Page<T, R>>; | ||
firstPage(size?: number, offset?: number): Promise<Page<T, R>>; | ||
lastPage(size?: number, offset?: number): Promise<Page<T, R>>; | ||
hasNextPage(): boolean; | ||
} | ||
export declare abstract class Repository<T extends XataRecord> extends Query<T> { | ||
select<K extends SelectableColumn<T>>(columns: K[]): Query<T, Select<T, K>>; | ||
abstract create(object: Selectable<T>): Promise<T>; | ||
abstract createMany(objects: Selectable<T>[]): Promise<T[]>; | ||
abstract read(id: string): Promise<T | null>; | ||
abstract update(id: string, object: Partial<T>): Promise<T>; | ||
abstract update(id: string, object: Partial<Selectable<T>>): Promise<T>; | ||
abstract upsert(id: string, object: Selectable<T>): Promise<T>; | ||
abstract delete(id: string): void; | ||
abstract _runQuery<R extends XataRecord, Options extends BulkQueryOptions<T>>(query: Query<T, R>, options: Options): Promise<Page<T, typeof options['columns'] extends SelectableColumn<T>[] ? Select<T, typeof options['columns'][number]> : R>>; | ||
abstract query<R extends XataRecord, Options extends QueryOptions<T>>(query: Query<T, R>, options: Options): Promise<Page<T, typeof options['columns'] extends SelectableColumn<T>[] ? Select<T, typeof options['columns'][number]> : R>>; | ||
} | ||
export declare class RestRepository<T extends XataRecord> extends Repository<T> { | ||
client: BaseClient<any>; | ||
fetch: any; | ||
#private; | ||
constructor(client: BaseClient<any>, table: string); | ||
request<T>(method: string, path: string, body?: unknown): Promise<T | undefined>; | ||
select<K extends SelectableColumn<T>>(columns: K[]): Query<T, Select<T, K>>; | ||
create(object: T): Promise<T>; | ||
create(object: Selectable<T>): Promise<T>; | ||
createMany(objects: T[]): Promise<T[]>; | ||
read(id: string): Promise<T | null>; | ||
update(id: string, object: Partial<T>): Promise<T>; | ||
delete(id: string): Promise<void>; | ||
_runQuery<R extends XataRecord, Options extends BulkQueryOptions<T>>(query: Query<T, R>, options: Options): Promise<Page<T, typeof options['columns'] extends SelectableColumn<T>[] ? Select<T, typeof options['columns'][number]> : R>>; | ||
read(recordId: string): Promise<T | null>; | ||
update(recordId: string, object: Partial<Selectable<T>>): Promise<T>; | ||
upsert(recordId: string, object: Selectable<T>): Promise<T>; | ||
delete(recordId: string): Promise<void>; | ||
query<R extends XataRecord, Options extends QueryOptions<T>>(query: Query<T, R>, options: Options): Promise<Page<T, typeof options['columns'] extends SelectableColumn<T>[] ? Select<T, typeof options['columns'][number]> : R>>; | ||
} | ||
@@ -180,3 +46,3 @@ interface RepositoryFactory { | ||
export declare type XataClientOptions = { | ||
fetch?: unknown; | ||
fetch?: FetchImpl; | ||
databaseURL?: string; | ||
@@ -188,5 +54,4 @@ branch: BranchStrategyOption; | ||
export declare class BaseClient<D extends Record<string, Repository<any>>> { | ||
#private; | ||
options: XataClientOptions; | ||
private links; | ||
private branch; | ||
db: D; | ||
@@ -202,2 +67,3 @@ constructor(options: XataClientOptions, links: Links); | ||
export declare type Links = Record<string, Array<string[]>>; | ||
export {}; | ||
export * from './api'; | ||
export * from './schema'; |
"use strict"; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
var desc = Object.getOwnPropertyDescriptor(m, k); | ||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
desc = { enumerable: true, get: function() { return m[k]; } }; | ||
} | ||
Object.defineProperty(o, k2, desc); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __exportStar = (this && this.__exportStar) || function(m, exports) { | ||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); | ||
}; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
@@ -11,2 +25,13 @@ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
}; | ||
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { | ||
if (kind === "m") throw new TypeError("Private method is not writable"); | ||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); | ||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); | ||
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; | ||
}; | ||
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { | ||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); | ||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); | ||
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); | ||
}; | ||
var __asyncValues = (this && this.__asyncValues) || function (o) { | ||
@@ -19,247 +44,11 @@ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); | ||
}; | ||
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); } | ||
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { | ||
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); | ||
var g = generator.apply(thisArg, _arguments || []), i, q = []; | ||
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; | ||
function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } | ||
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } | ||
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } | ||
function fulfill(value) { resume("next", value); } | ||
function reject(value) { resume("throw", value); } | ||
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } | ||
}; | ||
var _RestRepository_instances, _RestRepository_client, _RestRepository_fetch, _RestRepository_table, _RestRepository_getFetchProps, _BaseClient_links, _BaseClient_branch; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.XataError = exports.BaseClient = exports.RestRespositoryFactory = exports.RestRepository = exports.Repository = exports.Query = exports.includesAll = exports.includesPattern = exports.includesSubstring = exports.includes = exports.contains = exports.isNot = exports.is = exports.pattern = exports.endsWith = exports.startsWith = exports.notExists = exports.exists = exports.le = exports.lte = exports.lt = exports.gte = exports.ge = exports.gt = void 0; | ||
const errors_1 = require("./util/errors"); | ||
const gt = (value) => ({ $gt: value }); | ||
exports.gt = gt; | ||
const ge = (value) => ({ $ge: value }); | ||
exports.ge = ge; | ||
const gte = (value) => ({ $ge: value }); | ||
exports.gte = gte; | ||
const lt = (value) => ({ $lt: value }); | ||
exports.lt = lt; | ||
const lte = (value) => ({ $le: value }); | ||
exports.lte = lte; | ||
const le = (value) => ({ $le: value }); | ||
exports.le = le; | ||
const exists = (column) => ({ $exists: column }); | ||
exports.exists = exists; | ||
const notExists = (column) => ({ $notExists: column }); | ||
exports.notExists = notExists; | ||
const startsWith = (value) => ({ $startsWith: value }); | ||
exports.startsWith = startsWith; | ||
const endsWith = (value) => ({ $endsWith: value }); | ||
exports.endsWith = endsWith; | ||
const pattern = (value) => ({ $pattern: value }); | ||
exports.pattern = pattern; | ||
const is = (value) => ({ $is: value }); | ||
exports.is = is; | ||
const isNot = (value) => ({ $isNot: value }); | ||
exports.isNot = isNot; | ||
const contains = (value) => ({ $contains: value }); | ||
exports.contains = contains; | ||
// TODO: these can only be applied to columns of type "multiple" | ||
const includes = (value) => ({ $includes: value }); | ||
exports.includes = includes; | ||
const includesSubstring = (value) => ({ $includesSubstring: value }); | ||
exports.includesSubstring = includesSubstring; | ||
const includesPattern = (value) => ({ $includesPattern: value }); | ||
exports.includesPattern = includesPattern; | ||
const includesAll = (value) => ({ $includesAll: value }); | ||
exports.includesAll = includesAll; | ||
class Page { | ||
constructor(query, meta, records = []) { | ||
this.query = query; | ||
this.meta = meta; | ||
this.records = records; | ||
} | ||
nextPage(size, offset) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return this.query.getPaginated({ page: { size, offset, after: this.meta.page.cursor } }); | ||
}); | ||
} | ||
previousPage(size, offset) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return this.query.getPaginated({ page: { size, offset, before: this.meta.page.cursor } }); | ||
}); | ||
} | ||
firstPage(size, offset) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return this.query.getPaginated({ page: { size, offset, first: this.meta.page.cursor } }); | ||
}); | ||
} | ||
lastPage(size, offset) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return this.query.getPaginated({ page: { size, offset, last: this.meta.page.cursor } }); | ||
}); | ||
} | ||
// TODO: We need to add something on the backend if we want a hasPreviousPage | ||
hasNextPage() { | ||
return this.meta.page.more; | ||
} | ||
exports.XataError = exports.BaseClient = exports.RestRespositoryFactory = exports.RestRepository = exports.Repository = void 0; | ||
const api_1 = require("./api"); | ||
const filters_1 = require("./schema/filters"); | ||
const pagination_1 = require("./schema/pagination"); | ||
const query_1 = require("./schema/query"); | ||
class Repository extends query_1.Query { | ||
} | ||
class Query { | ||
constructor(repository, table, data, parent) { | ||
this.columns = ['*']; | ||
// Cursor pagination | ||
this.query = this; | ||
this.meta = { page: { cursor: 'start', more: true } }; | ||
this.records = []; | ||
if (repository) { | ||
this.repository = repository; | ||
} | ||
else { | ||
this.repository = this; | ||
} | ||
this.table = table; | ||
// For some reason Object.assign(this, parent) didn't work in this case | ||
// so doing all this manually: | ||
this.$any = parent === null || parent === void 0 ? void 0 : parent.$any; | ||
this.$all = parent === null || parent === void 0 ? void 0 : parent.$all; | ||
this.$not = parent === null || parent === void 0 ? void 0 : parent.$not; | ||
this.$none = parent === null || parent === void 0 ? void 0 : parent.$none; | ||
this.$sort = parent === null || parent === void 0 ? void 0 : parent.$sort; | ||
Object.assign(this, data); | ||
// These bindings are used to support deconstructing | ||
// const { any, not, filter, sort } = xata.users.query() | ||
this.any = this.any.bind(this); | ||
this.all = this.all.bind(this); | ||
this.not = this.not.bind(this); | ||
this.filter = this.filter.bind(this); | ||
this.sort = this.sort.bind(this); | ||
this.none = this.none.bind(this); | ||
Object.defineProperty(this, 'table', { enumerable: false }); | ||
Object.defineProperty(this, 'repository', { enumerable: false }); | ||
} | ||
any(...queries) { | ||
return new Query(this.repository, this.table, { | ||
$any: (this.$any || []).concat(queries) | ||
}, this); | ||
} | ||
all(...queries) { | ||
return new Query(this.repository, this.table, { | ||
$all: (this.$all || []).concat(queries) | ||
}, this); | ||
} | ||
not(...queries) { | ||
return new Query(this.repository, this.table, { | ||
$not: (this.$not || []).concat(queries) | ||
}, this); | ||
} | ||
none(...queries) { | ||
return new Query(this.repository, this.table, { | ||
$none: (this.$none || []).concat(queries) | ||
}, this); | ||
} | ||
filter(a, b) { | ||
if (arguments.length === 1) { | ||
const constraints = a; | ||
const queries = []; | ||
for (const [column, constraint] of Object.entries(constraints)) { | ||
queries.push({ [column]: constraint }); | ||
} | ||
return new Query(this.repository, this.table, { | ||
$all: (this.$all || []).concat(queries) | ||
}, this); | ||
} | ||
else { | ||
const column = a; | ||
const value = b; | ||
return new Query(this.repository, this.table, { | ||
$all: (this.$all || []).concat({ [column]: value }) | ||
}, this); | ||
} | ||
} | ||
sort(column, direction) { | ||
const sort = Object.assign(Object.assign({}, this.$sort), { [column]: direction }); | ||
const q = new Query(this.repository, this.table, { | ||
$sort: sort | ||
}, this); | ||
return q; | ||
} | ||
getPaginated(options = {}) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return this.repository._runQuery(this, options); | ||
}); | ||
} | ||
[Symbol.asyncIterator]() { | ||
return __asyncGenerator(this, arguments, function* _a() { | ||
var e_1, _b; | ||
try { | ||
for (var _c = __asyncValues(this.getIterator(1)), _d; _d = yield __await(_c.next()), !_d.done;) { | ||
const [record] = _d.value; | ||
yield yield __await(record); | ||
} | ||
} | ||
catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
finally { | ||
try { | ||
if (_d && !_d.done && (_b = _c.return)) yield __await(_b.call(_c)); | ||
} | ||
finally { if (e_1) throw e_1.error; } | ||
} | ||
}); | ||
} | ||
getIterator(chunk, options = {}) { | ||
return __asyncGenerator(this, arguments, function* getIterator_1() { | ||
let offset = 0; | ||
let end = false; | ||
while (!end) { | ||
const { records, meta } = yield __await(this.getPaginated(Object.assign(Object.assign({}, options), { page: { size: chunk, offset } }))); | ||
yield yield __await(records); | ||
offset += chunk; | ||
end = !meta.page.more; | ||
} | ||
}); | ||
} | ||
getMany(options = {}) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const { records } = yield this.getPaginated(options); | ||
return records; | ||
}); | ||
} | ||
getOne(options = {}) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const records = yield this.getMany(Object.assign(Object.assign({}, options), { page: { size: 1 } })); | ||
return records[0] || null; | ||
}); | ||
} | ||
deleteAll() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
// TODO: Return number of affected rows | ||
return 0; | ||
}); | ||
} | ||
nextPage(size, offset) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return this.firstPage(size, offset); | ||
}); | ||
} | ||
previousPage(size, offset) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return this.firstPage(size, offset); | ||
}); | ||
} | ||
firstPage(size, offset) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return this.getPaginated({ page: { size, offset } }); | ||
}); | ||
} | ||
lastPage(size, offset) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return this.getPaginated({ page: { size, offset, before: 'end' } }); | ||
}); | ||
} | ||
hasNextPage() { | ||
return this.meta.page.more; | ||
} | ||
} | ||
exports.Query = Query; | ||
class Repository extends Query { | ||
select(columns) { | ||
return new Query(this.repository, this.table, { columns }); | ||
} | ||
} | ||
exports.Repository = Repository; | ||
@@ -269,62 +58,31 @@ class RestRepository extends Repository { | ||
super(null, table, {}); | ||
this.client = client; | ||
const doWeHaveFetch = typeof fetch !== 'undefined'; | ||
const isInjectedFetchProblematic = !this.client.options.fetch; | ||
if (doWeHaveFetch) { | ||
this.fetch = fetch; | ||
_RestRepository_instances.add(this); | ||
_RestRepository_client.set(this, void 0); | ||
_RestRepository_fetch.set(this, void 0); | ||
_RestRepository_table.set(this, void 0); | ||
__classPrivateFieldSet(this, _RestRepository_client, client, "f"); | ||
__classPrivateFieldSet(this, _RestRepository_table, table, "f"); | ||
// TODO: Remove when integrating with API client | ||
const fetchImpl = typeof fetch !== 'undefined' ? fetch : __classPrivateFieldGet(this, _RestRepository_client, "f").options.fetch; | ||
if (!fetchImpl) { | ||
throw new Error(`The \`fetch\` option passed to the Xata client is resolving to a falsy value and may not be correctly imported.`); | ||
} | ||
else if (isInjectedFetchProblematic) { | ||
throw new Error(errors_1.errors.falsyFetchImplementation); | ||
} | ||
else { | ||
this.fetch = this.client.options.fetch; | ||
} | ||
Object.defineProperty(this, 'client', { enumerable: false }); | ||
Object.defineProperty(this, 'fetch', { enumerable: false }); | ||
Object.defineProperty(this, 'hostname', { enumerable: false }); | ||
__classPrivateFieldSet(this, _RestRepository_fetch, fetchImpl, "f"); | ||
} | ||
request(method, path, body) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const { databaseURL, apiKey } = this.client.options; | ||
const branch = yield this.client.getBranch(); | ||
const resp = yield this.fetch(`${databaseURL}:${branch}${path}`, { | ||
method, | ||
headers: { | ||
Accept: '*/*', | ||
'Content-Type': 'application/json', | ||
Authorization: `Bearer ${apiKey}` | ||
}, | ||
body: JSON.stringify(body) | ||
}); | ||
if (!resp.ok) { | ||
try { | ||
const json = yield resp.json(); | ||
const message = json.message; | ||
if (typeof message === 'string') { | ||
throw new XataError(message, resp.status); | ||
} | ||
} | ||
catch (err) { | ||
if (err instanceof XataError) | ||
throw err; | ||
// Ignore errors for other reasons. | ||
// For example if the response's body cannot be parsed as JSON | ||
} | ||
throw new XataError(resp.statusText, resp.status); | ||
} | ||
if (resp.status === 204) | ||
return undefined; | ||
return resp.json(); | ||
}); | ||
} | ||
select(columns) { | ||
return new Query(this.repository, this.table, { columns }); | ||
} | ||
create(object) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const fetchProps = yield __classPrivateFieldGet(this, _RestRepository_instances, "m", _RestRepository_getFetchProps).call(this); | ||
const record = transformObjectLinks(object); | ||
const response = yield this.request('POST', `/tables/${this.table}/data`, record); | ||
if (!response) { | ||
throw new Error("The server didn't return any data for the query"); | ||
} | ||
const response = object.id | ||
? yield (0, api_1.insertRecordWithID)(Object.assign({ pathParams: { | ||
workspace: '{workspaceId}', | ||
dbBranchName: '{dbBranch}', | ||
tableName: __classPrivateFieldGet(this, _RestRepository_table, "f"), | ||
recordId: object.id | ||
}, body: record }, fetchProps)) | ||
: yield (0, api_1.insertRecord)(Object.assign({ pathParams: { | ||
workspace: '{workspaceId}', | ||
dbBranchName: '{dbBranch}', | ||
tableName: __classPrivateFieldGet(this, _RestRepository_table, "f") | ||
}, body: record }, fetchProps)); | ||
const finalObject = yield this.read(response.id); | ||
@@ -339,7 +97,5 @@ if (!finalObject) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const fetchProps = yield __classPrivateFieldGet(this, _RestRepository_instances, "m", _RestRepository_getFetchProps).call(this); | ||
const records = objects.map((object) => transformObjectLinks(object)); | ||
const response = yield this.request('POST', `/tables/${this.table}/bulk`, { records }); | ||
if (!response) { | ||
throw new Error("The server didn't return any data for the query"); | ||
} | ||
const response = yield (0, api_1.bulkInsertTableRecords)(Object.assign({ pathParams: { workspace: '{workspaceId}', dbBranchName: '{dbBranch}', tableName: __classPrivateFieldGet(this, _RestRepository_table, "f") }, body: { records } }, fetchProps)); | ||
// TODO: Use filer.$any() to get all the records | ||
@@ -353,55 +109,50 @@ const finalObjects = yield Promise.all(response.recordIDs.map((id) => this.read(id))); | ||
} | ||
read(id) { | ||
read(recordId) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
try { | ||
const response = yield this.request('GET', `/tables/${this.table}/data/${id}`); | ||
if (!response) | ||
return null; | ||
return this.client.initObject(this.table, response); | ||
} | ||
catch (err) { | ||
if (err.status === 404) | ||
return null; | ||
throw err; | ||
} | ||
const fetchProps = yield __classPrivateFieldGet(this, _RestRepository_instances, "m", _RestRepository_getFetchProps).call(this); | ||
const response = yield (0, api_1.getRecord)(Object.assign({ pathParams: { workspace: '{workspaceId}', dbBranchName: '{dbBranch}', tableName: __classPrivateFieldGet(this, _RestRepository_table, "f"), recordId } }, fetchProps)); | ||
return __classPrivateFieldGet(this, _RestRepository_client, "f").initObject(__classPrivateFieldGet(this, _RestRepository_table, "f"), response); | ||
}); | ||
} | ||
update(id, object) { | ||
update(recordId, object) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const response = yield this.request('PUT', `/tables/${this.table}/data/${id}`, object); | ||
if (!response) { | ||
throw new Error("The server didn't return any data for the query"); | ||
} | ||
// TODO: Review this, not sure we are properly initializing the object | ||
return this.client.initObject(this.table, response); | ||
const fetchProps = yield __classPrivateFieldGet(this, _RestRepository_instances, "m", _RestRepository_getFetchProps).call(this); | ||
const response = yield (0, api_1.updateRecordWithID)(Object.assign({ pathParams: { workspace: '{workspaceId}', dbBranchName: '{dbBranch}', tableName: __classPrivateFieldGet(this, _RestRepository_table, "f"), recordId }, body: object }, fetchProps)); | ||
const item = yield this.read(response.id); | ||
if (!item) | ||
throw new Error('The server failed to save the record'); | ||
return item; | ||
}); | ||
} | ||
delete(id) { | ||
upsert(recordId, object) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
yield this.request('DELETE', `/tables/${this.table}/data/${id}`); | ||
const fetchProps = yield __classPrivateFieldGet(this, _RestRepository_instances, "m", _RestRepository_getFetchProps).call(this); | ||
const response = yield (0, api_1.upsertRecordWithID)(Object.assign({ pathParams: { workspace: '{workspaceId}', dbBranchName: '{dbBranch}', tableName: __classPrivateFieldGet(this, _RestRepository_table, "f"), recordId }, body: object }, fetchProps)); | ||
const item = yield this.read(response.id); | ||
if (!item) | ||
throw new Error('The server failed to save the record'); | ||
return item; | ||
}); | ||
} | ||
_runQuery(query, options) { | ||
var _a, _b; | ||
delete(recordId) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const filter = { | ||
$any: query.$any, | ||
$all: query.$all, | ||
$not: query.$not, | ||
$none: query.$none | ||
}; | ||
const fetchProps = yield __classPrivateFieldGet(this, _RestRepository_instances, "m", _RestRepository_getFetchProps).call(this); | ||
yield (0, api_1.deleteRecord)(Object.assign({ pathParams: { workspace: '{workspaceId}', dbBranchName: '{dbBranch}', tableName: __classPrivateFieldGet(this, _RestRepository_table, "f"), recordId } }, fetchProps)); | ||
}); | ||
} | ||
query(query, options) { | ||
var _a, _b, _c; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const data = query.getQueryOptions(); | ||
const body = { | ||
filter: Object.values(filter).some(Boolean) ? filter : undefined, | ||
sort: (_a = buildSortFilter(options === null || options === void 0 ? void 0 : options.sort)) !== null && _a !== void 0 ? _a : query.$sort, | ||
page: options === null || options === void 0 ? void 0 : options.page, | ||
columns: (_b = options === null || options === void 0 ? void 0 : options.columns) !== null && _b !== void 0 ? _b : query.columns | ||
filter: Object.values(data.filter).some(Boolean) ? data.filter : undefined, | ||
sort: (_a = (0, filters_1.buildSortFilter)(options === null || options === void 0 ? void 0 : options.sort)) !== null && _a !== void 0 ? _a : data.sort, | ||
page: (_b = options === null || options === void 0 ? void 0 : options.page) !== null && _b !== void 0 ? _b : data.page, | ||
columns: (_c = options === null || options === void 0 ? void 0 : options.columns) !== null && _c !== void 0 ? _c : data.columns | ||
}; | ||
const response = yield this.request('POST', `/tables/${this.table}/query`, body); | ||
if (!response) { | ||
throw new Error("The server didn't return any data for the query"); | ||
} | ||
const { meta, records: objects } = response; | ||
const records = objects.map((record) => this.client.initObject(this.table, record)); | ||
const fetchProps = yield __classPrivateFieldGet(this, _RestRepository_instances, "m", _RestRepository_getFetchProps).call(this); | ||
const { meta, records: objects } = yield (0, api_1.queryTable)(Object.assign({ pathParams: { workspace: '{workspaceId}', dbBranchName: '{dbBranch}', tableName: __classPrivateFieldGet(this, _RestRepository_table, "f") }, body }, fetchProps)); | ||
const records = objects.map((record) => __classPrivateFieldGet(this, _RestRepository_client, "f").initObject(__classPrivateFieldGet(this, _RestRepository_table, "f"), record)); | ||
// TODO: We should properly type this any | ||
return new Page(query, meta, records); | ||
return new pagination_1.Page(query, meta, records); | ||
}); | ||
@@ -411,2 +162,20 @@ } | ||
exports.RestRepository = RestRepository; | ||
_RestRepository_client = new WeakMap(), _RestRepository_fetch = new WeakMap(), _RestRepository_table = new WeakMap(), _RestRepository_instances = new WeakSet(), _RestRepository_getFetchProps = function _RestRepository_getFetchProps() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const branch = yield __classPrivateFieldGet(this, _RestRepository_client, "f").getBranch(); | ||
return { | ||
fetchImpl: __classPrivateFieldGet(this, _RestRepository_fetch, "f"), | ||
apiKey: __classPrivateFieldGet(this, _RestRepository_client, "f").options.apiKey, | ||
apiUrl: '', | ||
// Instead of using workspace and dbBranch, we inject a probably CNAME'd URL | ||
workspacesApiUrl: (path, params) => { | ||
var _a, _b; | ||
const baseUrl = (_a = __classPrivateFieldGet(this, _RestRepository_client, "f").options.databaseURL) !== null && _a !== void 0 ? _a : ''; | ||
const hasBranch = (_b = params.dbBranchName) !== null && _b !== void 0 ? _b : params.branch; | ||
const newPath = path.replace(/^\/db\/[^/]+/, hasBranch ? `:${branch}` : ''); | ||
return baseUrl + newPath; | ||
} | ||
}; | ||
}); | ||
}; | ||
class RestRespositoryFactory { | ||
@@ -420,2 +189,4 @@ createRepository(client, table) { | ||
constructor(options, links) { | ||
_BaseClient_links.set(this, void 0); | ||
_BaseClient_branch.set(this, void 0); | ||
if (!options.databaseURL || !options.apiKey || !options.branch) { | ||
@@ -425,3 +196,3 @@ throw new Error('Options databaseURL, apiKey and branch are required'); | ||
this.options = options; | ||
this.links = links; | ||
__classPrivateFieldSet(this, _BaseClient_links, links, "f"); | ||
} | ||
@@ -431,3 +202,3 @@ initObject(table, object) { | ||
Object.assign(o, object); | ||
const tableLinks = this.links[table] || []; | ||
const tableLinks = __classPrivateFieldGet(this, _BaseClient_links, "f")[table] || []; | ||
for (const link of tableLinks) { | ||
@@ -469,6 +240,6 @@ const [field, linkTable] = link; | ||
getBranch() { | ||
var e_2, _a; | ||
var e_1, _a; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (this.branch) | ||
return this.branch; | ||
if (__classPrivateFieldGet(this, _BaseClient_branch, "f")) | ||
return __classPrivateFieldGet(this, _BaseClient_branch, "f"); | ||
const { branch: param } = this.options; | ||
@@ -484,3 +255,3 @@ const strategies = Array.isArray(param) ? [...param] : [param]; | ||
if (branch) { | ||
this.branch = branch; | ||
__classPrivateFieldSet(this, _BaseClient_branch, branch, "f"); | ||
return branch; | ||
@@ -490,3 +261,3 @@ } | ||
} | ||
catch (e_2_1) { e_2 = { error: e_2_1 }; } | ||
catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
finally { | ||
@@ -496,3 +267,3 @@ try { | ||
} | ||
finally { if (e_2) throw e_2.error; } | ||
finally { if (e_1) throw e_1.error; } | ||
} | ||
@@ -504,2 +275,3 @@ throw new Error('Unable to resolve branch value'); | ||
exports.BaseClient = BaseClient; | ||
_BaseClient_links = new WeakMap(), _BaseClient_branch = new WeakMap(); | ||
class XataError extends Error { | ||
@@ -524,20 +296,3 @@ constructor(message, status) { | ||
}; | ||
function buildSortFilter(filter) { | ||
if (!filter) | ||
return undefined; | ||
const filters = Array.isArray(filter) ? filter : [filter]; | ||
return filters.reduce((acc, item) => { | ||
if (typeof item === 'string') { | ||
return Object.assign(Object.assign({}, acc), { [item]: 'asc' }); | ||
} | ||
else if (isObjectSortFilter(item)) { | ||
return Object.assign(Object.assign({}, acc), { [item.column]: item.direction }); | ||
} | ||
else { | ||
return acc; | ||
} | ||
}, {}); | ||
} | ||
function isObjectSortFilter(filter) { | ||
return typeof filter === 'object' && filter.column !== undefined; | ||
} | ||
__exportStar(require("./api"), exports); | ||
__exportStar(require("./schema"), exports); |
{ | ||
"name": "@xata.io/client", | ||
"version": "0.0.0-alpha.4c6e3c2", | ||
"version": "0.0.0-alpha.4fa02de", | ||
"description": "Xata.io SDK for TypeScript and JavaScript", | ||
@@ -23,3 +23,3 @@ "main": "./dist/index.js", | ||
"homepage": "https://github.com/xataio/client-ts/blob/main/client/README.md", | ||
"gitHead": "4c6e3c22f2aa0ddb17411b612458ca84921d9df9" | ||
"gitHead": "4fa02de0f4bbd25545f5fd47022739222ee69256" | ||
} |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
173844
37
4117
6