Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@xata.io/client

Package Overview
Dependencies
Maintainers
4
Versions
4351
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@xata.io/client - npm Package Compare versions

Comparing version 0.0.0-alpha.43b811f to 0.0.0-alpha.4c6e3c2

dist/util/errors.d.ts

108

dist/index.d.ts

@@ -11,6 +11,6 @@ export interface XataRecord {

export declare type Queries<T> = {
[key in keyof T as T[key] extends Query<infer A, infer B> ? key : never]: T[key];
[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<infer A, infer B> ? never : key]: T[key];
[key in keyof T as T[key] extends Query<any> ? never : key]: T[key];
};

@@ -24,3 +24,9 @@ export declare type OmitLinks<T> = {

export declare type Selectable<T> = Omit<OmitQueries<OmitMethods<T>>, 'id' | 'xata'>;
export declare type Select<T, K extends keyof T> = Pick<T, K> & Queries<T> & XataRecord;
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> = {

@@ -30,2 +36,7 @@ [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';

@@ -60,11 +71,49 @@ declare type Constraint<T> = {

};
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> = {
filter?: FilterConstraints<T>;
sort?: {
column: keyof T;
direction?: SortDirection;
} | keyof T;
page?: PaginationOptions;
columns?: Array<keyof Selectable<T>>;
sort?: SortFilter<T> | SortFilter<T>[];
};
declare type QueryOrConstraint<T, R> = Query<T, R> | Constraint<T>;
export declare class Query<T, R = 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;

@@ -77,2 +126,6 @@ repository: Repository<T>;

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>);

@@ -86,32 +139,41 @@ any(...queries: Query<T, R>[]): Query<T, R>;

sort<F extends keyof T>(column: F, direction: SortDirection): Query<T, R>;
getMany(options?: BulkQueryOptions<T>): Promise<R[]>;
getOne(options?: BulkQueryOptions<T>): Promise<R | null>;
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>;
include(columns: Include<T>): this;
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 Query<T, Selectable<T>> {
select<K extends keyof Selectable<T>>(...columns: K[]): Query<T, Select<T, K>>;
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 delete(id: string): void;
abstract query<R>(query: Query<T, R>): Promise<R[]>;
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>>;
}
export declare class RestRepository<T> extends Repository<T> {
export declare class RestRepository<T extends XataRecord> extends Repository<T> {
client: BaseClient<any>;
fetch: any;
constructor(client: BaseClient<any>, table: string);
request(method: string, path: string, body?: unknown): Promise<any>;
select<K extends keyof T>(...columns: K[]): Query<T, Select<T, K>>;
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>;
createMany(objects: T[]): Promise<T[]>;
read(id: string): Promise<T | null>;
update(id: string, object: Partial<T>): Promise<T>;
delete(id: string): Promise<void>;
query<R>(query: Query<T, R>): Promise<R[]>;
_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>>;
}
interface RepositoryFactory {
createRepository<T>(client: BaseClient<any>, table: string): Repository<T>;
createRepository<T extends XataRecord>(client: BaseClient<any>, table: string): Repository<T>;
}
export declare class RestRespositoryFactory implements RepositoryFactory {
createRepository<T>(client: BaseClient<any>, table: string): Repository<T>;
createRepository<T extends XataRecord>(client: BaseClient<any>, table: string): Repository<T>;
}

@@ -124,3 +186,3 @@ declare type BranchStrategyValue = string | undefined | null;

fetch?: unknown;
databaseURL: string;
databaseURL?: string;
branch: BranchStrategyOption;

@@ -127,0 +189,0 @@ apiKey: string;

@@ -18,4 +18,17 @@ "use strict";

};
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]); }
};
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 });

@@ -58,4 +71,40 @@ exports.gt = gt;

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;
}
}
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) {

@@ -133,32 +182,83 @@ this.repository = repository;

}
// TODO: pagination. Maybe implement different methods for different type of paginations
// and one to simply get the first records returned by the query with no pagination.
getMany(options) {
getPaginated(options = {}) {
return __awaiter(this, void 0, void 0, function* () {
// TODO: use options
return this.repository.query(this);
return this.repository._runQuery(this, options);
});
}
getOne(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* () {
// TODO: use options
const arr = yield this.getMany(); // TODO, limit to 1
return arr[0] || null;
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* () {
// Return number of affected rows
// TODO: Return number of affected rows
return 0;
});
}
include(columns) {
// TODO
return this;
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, {});
select(columns) {
return new Query(this.repository, this.table, { columns });
}

@@ -171,21 +271,12 @@ }

this.client = client;
const { fetch } = client.options;
if (fetch) {
const doWeHaveFetch = typeof fetch !== 'undefined';
const isInjectedFetchProblematic = !this.client.options.fetch;
if (doWeHaveFetch) {
this.fetch = fetch;
}
else if (typeof window === 'object') {
this.fetch = window.fetch;
else if (isInjectedFetchProblematic) {
throw new Error(errors_1.errors.falsyFetchImplementation);
}
else if (typeof require === 'function') {
try {
this.fetch = require('node-fetch');
}
catch (err) {
try {
this.fetch = require('cross-fetch');
}
catch (err) {
throw new Error('No fetch implementation found. Please provide one in the constructor');
}
}
else {
this.fetch = this.client.options.fetch;
}

@@ -226,27 +317,45 @@ Object.defineProperty(this, 'client', { enumerable: false });

if (resp.status === 204)
return;
return undefined;
return resp.json();
});
}
select(...columns) {
return new Query(this.repository, this.table, {});
select(columns) {
return new Query(this.repository, this.table, { columns });
}
create(object) {
return __awaiter(this, void 0, void 0, function* () {
const body = Object.assign({}, object);
for (const key of Object.keys(body)) {
const value = body[key];
if (value && typeof value === 'object' && typeof value.id === 'string') {
body[key] = value.id;
}
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 obj = yield this.request('POST', `/tables/${this.table}/data`, body);
return this.client.initObject(this.table, obj);
const finalObject = yield this.read(response.id);
if (!finalObject) {
throw new Error('The server failed to save the record');
}
return finalObject;
});
}
createMany(objects) {
return __awaiter(this, void 0, void 0, function* () {
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");
}
// TODO: Use filer.$any() to get all the records
const finalObjects = yield Promise.all(response.recordIDs.map((id) => this.read(id)));
if (finalObjects.some((object) => !object)) {
throw new Error('The server failed to save the record');
}
return finalObjects;
});
}
read(id) {
return __awaiter(this, void 0, void 0, function* () {
try {
const obj = yield this.request('GET', `/tables/${this.table}/data/${id}`);
return this.client.initObject(this.table, obj);
const response = yield this.request('GET', `/tables/${this.table}/data/${id}`);
if (!response)
return null;
return this.client.initObject(this.table, response);
}

@@ -262,4 +371,8 @@ catch (err) {

return __awaiter(this, void 0, void 0, function* () {
const obj = yield this.request('PUT', `/tables/${this.table}/data/${id}`, object);
return this.client.initObject(this.table, obj);
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);
});

@@ -272,3 +385,4 @@ }

}
query(query) {
_runQuery(query, options) {
var _a, _b;
return __awaiter(this, void 0, void 0, function* () {

@@ -283,6 +397,14 @@ const filter = {

filter: Object.values(filter).some(Boolean) ? filter : undefined,
sort: query.$sort
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
};
const result = yield this.request('POST', `/tables/${this.table}/query`, body);
return result.records.map((record) => this.client.initObject(this.table, record));
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));
// TODO: We should properly type this any
return new Page(query, meta, records);
});

@@ -346,3 +468,3 @@ }

getBranch() {
var e_1, _a;
var e_2, _a;
return __awaiter(this, void 0, void 0, function* () {

@@ -366,3 +488,3 @@ if (this.branch)

}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {

@@ -372,3 +494,3 @@ try {

}
finally { if (e_1) throw e_1.error; }
finally { if (e_2) throw e_2.error; }
}

@@ -390,1 +512,29 @@ throw new Error('Unable to resolve branch value');

};
// TODO: We can find a better implementation for links
const transformObjectLinks = (object) => {
return Object.entries(object).reduce((acc, [key, value]) => {
if (value && typeof value === 'object' && typeof value.id === 'string') {
return Object.assign(Object.assign({}, acc), { [key]: value.id });
}
return Object.assign(Object.assign({}, acc), { [key]: value });
}, {});
};
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;
}
{
"name": "@xata.io/client",
"version": "0.0.0-alpha.43b811f",
"version": "0.0.0-alpha.4c6e3c2",
"description": "Xata.io SDK for TypeScript and JavaScript",

@@ -9,3 +9,3 @@ "main": "./dist/index.js",

"test": "echo \"Error: no test specified\" && exit 1",
"build": "tsc",
"build": "tsc -p tsconfig.build.json",
"prepack": "npm run build"

@@ -24,3 +24,3 @@ },

"homepage": "https://github.com/xataio/client-ts/blob/main/client/README.md",
"gitHead": "43b811f0a04f172371c2cf6f8cf671b38243ab2c"
"gitHead": "4c6e3c22f2aa0ddb17411b612458ca84921d9df9"
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc