New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@cubicweb/client

Package Overview
Dependencies
Maintainers
3
Versions
31
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@cubicweb/client - npm Package Compare versions

Comparing version 3.0.0-alpha.4 to 3.0.0-alpha.5

35

lib/api/Api.d.ts

@@ -5,2 +5,4 @@ import { RawSchema } from "../schema/raw/Schema";

* Type representing an RQL request and its associated parameters.
*
* @category Api
*/

@@ -11,2 +13,4 @@ export type RQLQuery = [string, RQLParams];

* Type representing RQL parameters to send along a request.
*
* @category Api
*/

@@ -18,2 +22,4 @@ export interface RQLParams {

* Type representing a row returned in a result set.
*
* @category Api
*/

@@ -23,2 +29,4 @@ export type RqlRow = Array<string | number | boolean | null>;

* Type representing a RQL request result.
*
* @category Api
*/

@@ -28,2 +36,4 @@ export type ResultSet = Array<RqlRow>;

* Type representing the currently logged user's data
*
* @category Api
*/

@@ -37,2 +47,4 @@ export interface CurrentUser {

* Type representing the body of an error sent by CubicWeb's API.
*
* @category Api
*/

@@ -46,2 +58,4 @@ type ApiError = {

* Type representing the error data sent to clients when retrieving an API error.
*
* @category Api
*/

@@ -66,3 +80,3 @@ export type ApiErrorResponse = {

private _currentUserApiUrl;
private _transactionApiUrl;
private _binaryApiUrl;
/**

@@ -82,10 +96,2 @@ * Class used to handle requests to the CubicWeb API.

/**
* Executes the given query and waits for the response.
*
* @param query The RQL query to send
* @param params The additional parameters for the request
* @returns A promise with the request's result set
*/
execute(query: string, params: RQLParams): Promise<ResultSet>;
/**
* Retrieves the CubicWeb instance's JSON schema.

@@ -110,3 +116,12 @@ *

currentUser(): Promise<CurrentUser>;
executeTransaction(transaction: Transaction): Promise<TransactionResult>;
/**
* Get the binary for the given entity attribute
*
* @returns A promise resolving to the binary
*/
binary(eid: number, attribute: string): Promise<Blob>;
rql(transaction: Transaction): Promise<TransactionResult>;
private getTransactionParams;
private multipartTransaction;
private jsonTransaction;
private handleUserErrors;

@@ -113,0 +128,0 @@ }

@@ -40,3 +40,3 @@ "use strict";

this._currentUserApiUrl = this.getApiRoute("current-user");
this._transactionApiUrl = this.getApiRoute("transaction");
this._binaryApiUrl = this.getApiRoute("binary");
}

@@ -50,23 +50,2 @@ get apiUrl() {

/**
* Executes the given query and waits for the response.
*
* @param query The RQL query to send
* @param params The additional parameters for the request
* @returns A promise with the request's result set
*/
execute(query, params) {
return __awaiter(this, void 0, void 0, function* () {
try {
return yield nonNullFetchApi(this._rqlApiUrl, {
method: "POST",
body: JSON.stringify({ query, params }),
credentials: "include", // FIXME is it secure?
});
}
catch (e) {
this.handleUserErrors(e);
}
});
}
/**
* Retrieves the CubicWeb instance's JSON schema.

@@ -122,24 +101,28 @@ *

}
executeTransaction(transaction) {
/**
* Get the binary for the given entity attribute
*
* @returns A promise resolving to the binary
*/
binary(eid, attribute) {
return __awaiter(this, void 0, void 0, function* () {
const data = transaction.queries.map((transactionQuery) => ({
query: transactionQuery.query,
params: Object.fromEntries(Object.entries(transactionQuery.params).map(([key, value]) => [
key,
(0, Transaction_1.isTransactionQueryRef)(value)
? {
queryIndex: value.queryIndex,
row: value.row,
column: value.column,
}
: value,
])),
}));
const params = new URLSearchParams({
eid: eid.toString(),
attribute,
});
return yield nonNullFetchApi(this._binaryApiUrl + params, {
method: "GET",
credentials: "include",
});
});
}
rql(transaction) {
return __awaiter(this, void 0, void 0, function* () {
try {
const resultSets = yield nonNullFetchApi(this._transactionApiUrl, {
method: "POST",
credentials: "include",
body: JSON.stringify(data),
});
return new Transaction_1.TransactionResult(resultSets);
if (Object.keys(transaction.binaries).length > 0) {
return yield this.multipartTransaction(transaction);
}
else {
return yield this.jsonTransaction(transaction);
}
}

@@ -151,2 +134,43 @@ catch (e) {

}
getTransactionParams(transaction) {
return transaction.queries.map((transactionQuery) => ({
query: transactionQuery.query,
params: Object.fromEntries(Object.entries(transactionQuery.params).map(([key, value]) => [
key,
(0, Transaction_1.isTransactionQueryRef)(value)
? {
queryIndex: value.queryIndex,
row: value.row,
column: value.column,
}
: value,
])),
}));
}
multipartTransaction(transaction) {
return __awaiter(this, void 0, void 0, function* () {
const jsonParams = this.getTransactionParams(transaction);
const formData = new FormData();
formData.append("queries", JSON.stringify(jsonParams));
Object.entries(transaction.binaries).forEach(([key, value]) => {
formData.append(key, value);
});
const resultSets = yield nonNullFetchApi(this._rqlApiUrl, {
method: "POST",
credentials: "include",
body: formData,
});
return new Transaction_1.TransactionResult(resultSets);
});
}
jsonTransaction(transaction) {
return __awaiter(this, void 0, void 0, function* () {
const resultSets = yield nonNullFetchApi(this._rqlApiUrl, {
method: "POST",
credentials: "include",
body: JSON.stringify(this.getTransactionParams(transaction)),
});
return new Transaction_1.TransactionResult(resultSets);
});
}
handleUserErrors(error) {

@@ -204,3 +228,5 @@ if (typeof error === "object" &&

if ((init === null || init === void 0 ? void 0 : init.method) && init.method !== "GET" && init.method !== "DELETE") {
headers = Object.assign({ "Content-Type": "application/json;charset=UTF-8" }, init === null || init === void 0 ? void 0 : init.headers);
headers = Object.assign({ "Content-Type": "application/json;charset=UTF-8",
// CSRF custom header necessary for POST requests
"X-Requested-With": "XMLHttpRequest" }, init === null || init === void 0 ? void 0 : init.headers);
}

@@ -207,0 +233,0 @@ const response = yield fetch(input, Object.assign(Object.assign({}, init), { headers }));

import { Schema } from "../schema/classes/Schema";
import { RQLParams, ResultSet, CurrentUser } from "./Api";
import { Transaction, TransactionBackend, TransactionResult } from "./Transaction";
import { BinariesParam, Transaction, TransactionResult } from "./Transaction";
/**
* Class used to communicate with a CubicWeb instance's API.
*
* @category Api
*/
export default class Client {
private api;
private transactionBackend;
/**

@@ -17,5 +18,3 @@ * Class used to communicate with a CubicWeb instance's API.

*/
constructor(apiUrl: string, options?: {
transactionBackend?: TransactionBackend;
});
constructor(apiUrl: string);
get apiUrl(): string;

@@ -29,3 +28,3 @@ /**

*/
execute(query: string, params?: RQLParams): Promise<ResultSet>;
execute(query: string, params?: RQLParams, binaries?: BinariesParam): Promise<ResultSet>;
/**

@@ -56,3 +55,9 @@ * Retrieves the CubicWeb instance's JSON schema.

executeTransaction(transaction: Transaction): Promise<TransactionResult>;
/**
* Get the binary for the given entity attribute
*
* @returns A promise resolving to the binary
*/
getBinary(eid: number, attribute: string): Promise<Blob>;
}
//# sourceMappingURL=Client.d.ts.map

@@ -20,2 +20,4 @@ "use strict";

* Class used to communicate with a CubicWeb instance's API.
*
* @category Api
*/

@@ -30,11 +32,4 @@ class Client {

*/
constructor(apiUrl, options = {}) {
constructor(apiUrl) {
this.api = new Api_1.default(apiUrl);
const { transactionBackend } = options;
if (transactionBackend === undefined) {
this.transactionBackend = new Transaction_1.NativeTransactionBackend(this.api);
}
else {
this.transactionBackend = transactionBackend;
}
}

@@ -51,5 +46,9 @@ get apiUrl() {

*/
execute(query, params = {}) {
execute(query, params = {}, binaries) {
return __awaiter(this, void 0, void 0, function* () {
return yield this.api.execute(query, params);
const transaction = new Transaction_1.Transaction();
transaction.push(query, params);
transaction.setBinaries(binaries);
const result = yield this.executeTransaction(transaction);
return result.get(0);
});

@@ -96,7 +95,17 @@ }

return __awaiter(this, void 0, void 0, function* () {
return yield this.transactionBackend.execute(transaction);
return yield this.api.rql(transaction);
});
}
/**
* Get the binary for the given entity attribute
*
* @returns A promise resolving to the binary
*/
getBinary(eid, attribute) {
return __awaiter(this, void 0, void 0, function* () {
return yield this.api.binary(eid, attribute);
});
}
}
exports.default = Client;
//# sourceMappingURL=Client.js.map

@@ -1,5 +0,9 @@

import Api, { ResultSet, RQLParamValue } from "./Api";
import { ResultSet, RQLParamValue } from "./Api";
export type BinariesParam = Record<string, Blob>;
export declare class Transaction {
private _queries;
private _binaries;
push(query: string, params: Record<string, RQLParamValue | TransactionQueryRef>): TransactionQuery;
setBinaries(binaries?: BinariesParam): void;
get binaries(): BinariesParam;
get queries(): ReadonlyArray<TransactionQuery>;

@@ -10,2 +14,3 @@ }

constructor(resultSets: ReadonlyArray<ResultSet>);
get(queryIndex: number): ResultSet;
resolve(ref: TransactionQueryRef): string | number | boolean | null;

@@ -26,10 +31,2 @@ }

export declare function isTransactionQueryRef(value: RQLParamValue | TransactionQueryRef): value is TransactionQueryRef;
export interface TransactionBackend {
execute(transaction: Transaction): Promise<TransactionResult>;
}
export declare class NativeTransactionBackend implements TransactionBackend {
private _api;
constructor(_api: Api);
execute(transaction: Transaction): Promise<TransactionResult>;
}
//# sourceMappingURL=Transaction.d.ts.map
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.NativeTransactionBackend = exports.isTransactionQueryRef = exports.TransactionQuery = exports.TransactionResult = exports.Transaction = void 0;
exports.isTransactionQueryRef = exports.TransactionQuery = exports.TransactionResult = exports.Transaction = void 0;
class Transaction {
constructor() {
this._queries = [];
this._binaries = {};
}

@@ -22,2 +14,8 @@ push(query, params) {

}
setBinaries(binaries) {
this._binaries = binaries !== null && binaries !== void 0 ? binaries : {};
}
get binaries() {
return this._binaries;
}
get queries() {

@@ -32,2 +30,5 @@ return this._queries;

}
get(queryIndex) {
return this.resultSets[queryIndex];
}
resolve(ref) {

@@ -59,13 +60,2 @@ return this.resultSets[ref.queryIndex][ref.row][ref.column];

exports.isTransactionQueryRef = isTransactionQueryRef;
class NativeTransactionBackend {
constructor(_api) {
this._api = _api;
}
execute(transaction) {
return __awaiter(this, void 0, void 0, function* () {
return this._api.executeTransaction(transaction);
});
}
}
exports.NativeTransactionBackend = NativeTransactionBackend;
//# sourceMappingURL=Transaction.js.map

@@ -10,2 +10,4 @@ import { EntityRawSchemaArray } from "../raw/Entities";

* Instead, retrieve these objects from the methods in the `Schema` class.
*
* @category Schema
*/

@@ -12,0 +14,0 @@ export declare class EntitySchema<E extends EntityRawSchemaArray = EntityRawSchemaArray, R extends RelationDefinitionRawSchemaArray<E> = RelationDefinitionRawSchemaArray<E>, ERawSchema extends E[number] = E[number]> {

@@ -8,2 +8,4 @@ "use strict";

* Instead, retrieve these objects from the methods in the `Schema` class.
*
* @category Schema
*/

@@ -10,0 +12,0 @@ class EntitySchema {

@@ -11,2 +11,4 @@ import { EntityRawSchemaArray } from "../raw/Entities";

* Instead, retrieve these objects from the methods in the `Schema` class.
*
* @category Schema
*/

@@ -13,0 +15,0 @@ export declare class RelationDefinitionSchema<E extends EntityRawSchemaArray = EntityRawSchemaArray, R extends RelationDefinitionRawSchemaArray<E> = RelationDefinitionRawSchemaArray<E>, RDef extends R[number] = R[number]> {

@@ -10,2 +10,4 @@ "use strict";

* Instead, retrieve these objects from the methods in the `Schema` class.
*
* @category Schema
*/

@@ -12,0 +14,0 @@ class RelationDefinitionSchema {

@@ -13,2 +13,4 @@ import { EntityRawSchemaArray } from "../raw/Entities";

* as it is more robust to schema changes and provides utility functions.
*
* @category Schema
*/

@@ -15,0 +17,0 @@ export declare class Schema<E extends EntityRawSchemaArray = EntityRawSchemaArray, R extends RelationDefinitionRawSchemaArray<E> = RelationDefinitionRawSchemaArray<E>> {

@@ -11,2 +11,4 @@ "use strict";

* as it is more robust to schema changes and provides utility functions.
*
* @category Schema
*/

@@ -13,0 +15,0 @@ class Schema {

@@ -7,2 +7,4 @@ import { EntityRawSchemaArray } from "../raw/Entities";

* An entity role in a relation.
*
* @category Utils
*/

@@ -16,2 +18,4 @@ export type EntityRole = "subject" | "object";

* @returns A loosely typed schema
*
* @category Utils
*/

@@ -24,2 +28,4 @@ export declare const getLooseSchema: <E extends EntityRawSchemaArray = EntityRawSchemaArray, R extends RelationDefinitionRawSchemaArray<E> = RelationDefinitionRawSchemaArray<E>>(schema: Schema<E, R>) => Schema<EntityRawSchemaArray, RelationDefinitionRawSchemaArray<EntityRawSchemaArray>>;

* @returns True if the cardinality is 1 or +
*
* @category Utils
*/

@@ -32,2 +38,4 @@ export declare function isCardinalityRequired(cardinality: Cardinality): boolean;

* @returns True if the cardinality is `*` or `+`
*
* @category Utils
*/

@@ -40,2 +48,4 @@ export declare const isCardinalityMultiple: (cardinality: Cardinality) => boolean;

* @returns True if the cardinality is `?` or `*`
*
* @category Utils
*/

@@ -48,2 +58,4 @@ export declare const isCardinalityOptional: (cardinality: Cardinality) => boolean;

* @returns "object" if the given role was "subject", "subject" otherwise
*
* @category Utils
*/

@@ -60,2 +72,4 @@ export declare function getOppositeRelationRole(role: EntityRole): EntityRole;

* @returns True if the relation type starts with the reverse indicator
*
* @category Utils
*/

@@ -73,2 +87,4 @@ export declare const isRelationTypeReversed: (relationType: string) => boolean;

* @returns "subject" if the relation is not reversed, "object" otherwise
*
* @category Utils
*/

@@ -85,2 +101,4 @@ export declare const getRoleFromRelationType: (relationType: string) => EntityRole;

* @returns The relation type with the reverse indicator added or removed
*
* @category Utils
*/

@@ -97,2 +115,4 @@ export declare const getReverseRelationType: (relationType: string) => string;

* @returns The relation type with the reverse indicator added or removed
*
* @category Utils
*/

@@ -110,2 +130,4 @@ export declare const getRawRelationType: (relationType: string) => string;

* @returns A relation type with the reverse indicator if necessary
*
* @category Utils
*/

@@ -121,2 +143,4 @@ export declare const getRelationType: (relationType: string, role: EntityRole) => string;

* @returns The relation definition matching the triplet source relation target
*
* @category Utils
*/

@@ -140,2 +164,4 @@ export declare const getRelationDefinition: (entitySchema: EntitySchema, sourceType: string, relationType: string, targetType: string) => import("./RelationDefinitionSchema").RelationDefinitionSchema<EntityRawSchemaArray, RelationDefinitionRawSchemaArray<EntityRawSchemaArray>, Readonly<{

* Partial raw relation definition schema type.
*
* @category Utils
*/

@@ -148,2 +174,4 @@ export type RelationDefinitionMatcher<E extends EntityRawSchemaArray> = Partial<RelationDefinitionRawSchema<E>>;

* and TypeScript will give compile errors.
*
* @category Utils
*/

@@ -150,0 +178,0 @@ export type MatchedRelationDefinition<E extends EntityRawSchemaArray, R extends RelationDefinitionRawSchemaArray<EntityRawSchemaArray>, M extends RelationDefinitionMatcher<E>> = R[number] extends infer RDef ? (RDef extends M ? RDef : never) : never;

@@ -14,2 +14,4 @@ "use strict";

* @returns A loosely typed schema
*
* @category Utils
*/

@@ -25,2 +27,4 @@ const getLooseSchema = (schema) => {

* @returns True if the cardinality is 1 or +
*
* @category Utils
*/

@@ -36,2 +40,4 @@ function isCardinalityRequired(cardinality) {

* @returns True if the cardinality is `*` or `+`
*
* @category Utils
*/

@@ -47,2 +53,4 @@ const isCardinalityMultiple = (cardinality) => {

* @returns True if the cardinality is `?` or `*`
*
* @category Utils
*/

@@ -58,2 +66,4 @@ const isCardinalityOptional = (cardinality) => {

* @returns "object" if the given role was "subject", "subject" otherwise
*
* @category Utils
*/

@@ -73,2 +83,4 @@ function getOppositeRelationRole(role) {

* @returns True if the relation type starts with the reverse indicator
*
* @category Utils
*/

@@ -89,2 +101,4 @@ const isRelationTypeReversed = (relationType) => {

* @returns "subject" if the relation is not reversed, "object" otherwise
*
* @category Utils
*/

@@ -104,2 +118,4 @@ const getRoleFromRelationType = (relationType) => {

* @returns The relation type with the reverse indicator added or removed
*
* @category Utils
*/

@@ -124,2 +140,4 @@ const getReverseRelationType = (relationType) => {

* @returns The relation type with the reverse indicator added or removed
*
* @category Utils
*/

@@ -145,2 +163,4 @@ const getRawRelationType = (relationType) => {

* @returns A relation type with the reverse indicator if necessary
*
* @category Utils
*/

@@ -161,2 +181,4 @@ const getRelationType = (relationType, role) => {

* @returns The relation definition matching the triplet source relation target
*
* @category Utils
*/

@@ -163,0 +185,0 @@ const getRelationDefinition = (entitySchema, sourceType, relationType, targetType) => {

@@ -9,3 +9,3 @@ /**

/**
* THe type of a constraint message when one is present.
* The type of a constraint message when one is present.
*/

@@ -30,2 +30,4 @@ type ConstraintMessage = string | null;

* @property \_\_attribute\_\_ name of the attribute in the same entity
*
* @category Schema
*/

@@ -46,2 +48,4 @@ export interface Attribute {

* @property type name of the Python class used to do the comparison
*
* @category Schema
*/

@@ -58,2 +62,4 @@ export interface Today {

* @property offset delta to current date at the time of the check
*
* @category Schema
*/

@@ -66,8 +72,6 @@ export interface Now {

* All the possible operators inside a constraint.
*
* @category Schema
*/
export type ConstraintOperator = ">" | ">=" | "<" | "<=";
/**
* @property value.boundary boudary value to compare the attribut
*
*/
export type BoundaryConstraint = ConstraintBase<"BoundaryConstraint", {

@@ -102,2 +106,4 @@ boundary: Attribute | Today | Now | number | null;

* Type representing all possible constraints for attributes.
*
* @category Schema
*/

@@ -107,2 +113,4 @@ export type AttributeConstraint = Readonly<UniqueConstraint | SizeConstraint | RegexpConstraint | BoundaryConstraint | IntervalBoundConstraint | StaticVocabularyConstraint | FormatConstraint | RQLConstraint>;

* Type representing all possible constraints for relations.
*
* @category Schema
*/

@@ -109,0 +117,0 @@ export type RelationConstraint = Readonly<RQLVocabularyConstraint | RQLConstraint>;

/**
* Type representing an entity schema.
*
* @category Schema
*/

@@ -11,4 +13,6 @@ export type EntityRawSchema = {

* Type representing a list of entity schemas.
*
* @category Schema
*/
export type EntityRawSchemaArray = ReadonlyArray<EntityRawSchema>;
//# sourceMappingURL=Entities.d.ts.map

@@ -6,2 +6,4 @@ import { EntityRole } from "../classes/Utils";

* Type representing all the possible cardinalities in CubicWeb.
*
* @category Schema
*/

@@ -11,2 +13,4 @@ export type Cardinality = "*" | "1" | "?" | "+";

* Type representing a cardinality pair as used in relation definitions.
*
* @category Schema
*/

@@ -79,2 +83,4 @@ export type CardinalityPair = `${Cardinality}${Cardinality}`;

* Type representing the possible options for an attribute.
*
* @category Schema
*/

@@ -88,2 +94,4 @@ export type AttributeOptions = {

* Type representing the possible options for a relation definition.
*
* @category Schema
*/

@@ -101,2 +109,4 @@ export type RelationOptions = {

* It can infer default values type depending on the object type if the relation is final.
*
* @category Schema
*/

@@ -120,2 +130,4 @@ export type RelationDefinitionRawSchema<ESchemas extends EntityRawSchemaArray, Final extends boolean = boolean> = Readonly<{

* Type representing a list of relation definitions.
*
* @category Schema
*/

@@ -122,0 +134,0 @@ export type RelationDefinitionRawSchemaArray<ESchemas extends EntityRawSchemaArray> = ReadonlyArray<RelationDefinitionRawSchema<ESchemas, boolean>>;

@@ -8,2 +8,4 @@ import { EntityRawSchemaArray } from "./Entities";

* `cubicweb-ctl export-schema -f typescript <YOUR_INSTANCE_NAME>`
*
* @category Schema
*/

@@ -10,0 +12,0 @@ export type RawSchema<E extends EntityRawSchemaArray = EntityRawSchemaArray, R extends RelationDefinitionRawSchemaArray<E> = RelationDefinitionRawSchemaArray<E>> = {

@@ -8,2 +8,4 @@ import { EntityRawSchemaArray } from "./Entities";

* If the schema is strongly typed, the entities type would be a word (which is stricter than string).
*
* @category Schema
*/

@@ -14,2 +16,4 @@ export type IsLooseSchema<E extends EntityRawSchemaArray> = string extends E[number]["type"] ? true : false;

* Use this to create conditional types.
*
* @category Schema
*/

@@ -20,2 +24,4 @@ export type IsETypeInStrictSchema<E extends EntityRawSchemaArray, EType extends string> = EType extends E[number]["type"] ? true : false;

* This type only works for EntityRawSchemaArray with literals as "type" property.
*
* @category Schema
*/

@@ -22,0 +28,0 @@ export type EntityRawSchemaByType<E extends EntityRawSchemaArray, T extends string> = E[number] extends infer ESchema ? ESchema extends {

@@ -5,3 +5,3 @@ {

"author": "Logilab",
"version": "3.0.0-alpha.4",
"version": "3.0.0-alpha.5",
"license": "LGPL-3.0-or-later",

@@ -11,4 +11,4 @@ "main": "lib/index.js",

"scripts": {
"build": "tsc --project tsconfig.build.json",
"docs": "typedoc"
"build": "run -T tsc --project tsconfig.build.json",
"docs": "run -T typedoc"
},

@@ -28,7 +28,3 @@ "repository": {

"!**/__tests__/**"
],
"devDependencies": {
"typedoc": "^0.23.24",
"typescript": "^4.9.4"
}
]
}
# @cubicweb/client
This library is the [CubicWeb](https://cubicweb.org/) JavaScript client
used to communicate with instances running with the
This library allows any JavaScript client to communicate with a [CubicWeb](https://cubicweb.org/) instance running with the
[API cube](https://forge.extranet.logilab.fr/cubicweb/cubes/api).

@@ -11,5 +10,7 @@ It replaces the [cwclientlibjs](https://forge.extranet.logilab.fr/open-source/cwclientlibjs)

**Compatible with [API cube](https://forge.extranet.logilab.fr/cubicweb/cubes/api) version 0.11 only.**
## Installation
@cubicweb/client is avalaible from NPM:
@cubicweb/client is available from NPM:
```bash

@@ -80,16 +81,18 @@ # With NPM

// Execute a series of request in a transaction
const transaction = new Transaction()
transaction.push({
query: `INSERT Person X: X name "test"`
})
transaction.push({
query: `Any X Where X eid %(created_eid)s`,
params: {
created_eid: {
queryIndex: 0,
row: 0,
column: 0,
}
}
})
client
.transaction(async (tr) => {
const insertResult = await tr.execute(
`INSERT Person X: X name "test"`
);
const insertedEid = insertResult?.[0]?.[0];
if (insertedEid != null) {
return tr.execute(`Any X Where X eid %(created_eid)s`, {
created_eid: insertedEid,
});
} else {
throw new Error("Error inserting Person");
}
})
.executeTransaction(transaction)
.then((callbackResult) => {

@@ -208,1 +211,10 @@ console.log("Transaction was successul and the callback returned:");

```
## Contribute
All `@cubicweb` libraries are in the [cubicwebjs monorepo](https://forge.extranet.logilab.fr/cubicweb/cubicwebjs).
Please refer to the main README.
## Get Help
Contact us on [Matrix](https://matrix.to/#/#cubicweb:matrix.logilab.org) and check the roadmap on the [CubicWeb Repository](https://forge.extranet.logilab.fr/cubicweb/cubicweb).

@@ -11,2 +11,4 @@ import { ValidationError } from "../Errors";

* Type representing an RQL request and its associated parameters.
*
* @category Api
*/

@@ -18,2 +20,4 @@ export type RQLQuery = [string, RQLParams];

* Type representing RQL parameters to send along a request.
*
* @category Api
*/

@@ -26,2 +30,4 @@ export interface RQLParams {

* Type representing a row returned in a result set.
*
* @category Api
*/

@@ -32,2 +38,4 @@ export type RqlRow = Array<string | number | boolean | null>;

* Type representing a RQL request result.
*
* @category Api
*/

@@ -38,2 +46,4 @@ export type ResultSet = Array<RqlRow>;

* Type representing the currently logged user's data
*
* @category Api
*/

@@ -48,2 +58,4 @@ export interface CurrentUser {

* Type representing the body of an error sent by CubicWeb's API.
*
* @category Api
*/

@@ -58,2 +70,4 @@ type ApiError = {

* Type representing the error data sent to clients when retrieving an API error.
*
* @category Api
*/

@@ -79,3 +93,3 @@ export type ApiErrorResponse = {

private _currentUserApiUrl: string;
private _transactionApiUrl: string;
private _binaryApiUrl: string;

@@ -98,3 +112,3 @@ /**

this._currentUserApiUrl = this.getApiRoute("current-user");
this._transactionApiUrl = this.getApiRoute("transaction");
this._binaryApiUrl = this.getApiRoute("binary");
}

@@ -111,21 +125,2 @@

/**
* Executes the given query and waits for the response.
*
* @param query The RQL query to send
* @param params The additional parameters for the request
* @returns A promise with the request's result set
*/
async execute(query: string, params: RQLParams): Promise<ResultSet> {
try {
return await nonNullFetchApi<ResultSet>(this._rqlApiUrl, {
method: "POST",
body: JSON.stringify({ query, params }),
credentials: "include", // FIXME is it secure?
});
} catch (e) {
this.handleUserErrors(e);
}
}
/**
* Retrieves the CubicWeb instance's JSON schema.

@@ -177,6 +172,32 @@ *

async executeTransaction(
transaction: Transaction
): Promise<TransactionResult> {
const data = transaction.queries.map((transactionQuery) => ({
/**
* Get the binary for the given entity attribute
*
* @returns A promise resolving to the binary
*/
async binary(eid: number, attribute: string): Promise<Blob> {
const params = new URLSearchParams({
eid: eid.toString(),
attribute,
});
return await nonNullFetchApi<Blob>(this._binaryApiUrl + params, {
method: "GET",
credentials: "include",
});
}
async rql(transaction: Transaction): Promise<TransactionResult> {
try {
if (Object.keys(transaction.binaries).length > 0) {
return await this.multipartTransaction(transaction);
} else {
return await this.jsonTransaction(transaction);
}
} catch (e) {
this.handleUserErrors(e);
}
}
private getTransactionParams(transaction: Transaction) {
return transaction.queries.map((transactionQuery) => ({
query: transactionQuery.query,

@@ -196,17 +217,35 @@ params: Object.fromEntries(

}));
try {
const resultSets = await nonNullFetchApi<ReadonlyArray<ResultSet>>(
this._transactionApiUrl,
{
method: "POST",
credentials: "include",
body: JSON.stringify(data),
}
);
return new TransactionResult(resultSets);
} catch (e) {
this.handleUserErrors(e);
}
}
private async multipartTransaction(transaction: Transaction) {
const jsonParams = this.getTransactionParams(transaction);
const formData = new FormData();
formData.append("queries", JSON.stringify(jsonParams));
Object.entries(transaction.binaries).forEach(([key, value]) => {
formData.append(key, value);
});
const resultSets = await nonNullFetchApi<ReadonlyArray<ResultSet>>(
this._rqlApiUrl,
{
method: "POST",
credentials: "include",
body: formData,
}
);
return new TransactionResult(resultSets);
}
private async jsonTransaction(transaction: Transaction) {
const resultSets = await nonNullFetchApi<ReadonlyArray<ResultSet>>(
this._rqlApiUrl,
{
method: "POST",
credentials: "include",
body: JSON.stringify(this.getTransactionParams(transaction)),
}
);
return new TransactionResult(resultSets);
}
private handleUserErrors(error: unknown): never {

@@ -272,2 +311,4 @@ if (

"Content-Type": "application/json;charset=UTF-8",
// CSRF custom header necessary for POST requests
"X-Requested-With": "XMLHttpRequest",
...init?.headers,

@@ -274,0 +315,0 @@ };

import { Schema } from "../schema/classes/Schema";
import Api, { RQLParams, ResultSet, CurrentUser } from "./Api";
import {
NativeTransactionBackend,
Transaction,
TransactionBackend,
TransactionResult,
} from "./Transaction";
import { BinariesParam, Transaction, TransactionResult } from "./Transaction";
/**
* Class used to communicate with a CubicWeb instance's API.
*
* @category Api
*/
export default class Client {
private api: Api;
private transactionBackend: TransactionBackend;

@@ -24,13 +20,4 @@ /**

*/
constructor(
apiUrl: string,
options: { transactionBackend?: TransactionBackend } = {}
) {
constructor(apiUrl: string) {
this.api = new Api(apiUrl);
const { transactionBackend } = options;
if (transactionBackend === undefined) {
this.transactionBackend = new NativeTransactionBackend(this.api);
} else {
this.transactionBackend = transactionBackend;
}
}

@@ -49,4 +36,12 @@

*/
async execute(query: string, params: RQLParams = {}): Promise<ResultSet> {
return await this.api.execute(query, params);
async execute(
query: string,
params: RQLParams = {},
binaries?: BinariesParam
): Promise<ResultSet> {
const transaction = new Transaction();
transaction.push(query, params);
transaction.setBinaries(binaries);
const result = await this.executeTransaction(transaction);
return result.get(0);
}

@@ -91,4 +86,13 @@

): Promise<TransactionResult> {
return await this.transactionBackend.execute(transaction);
return await this.api.rql(transaction);
}
/**
* Get the binary for the given entity attribute
*
* @returns A promise resolving to the binary
*/
async getBinary(eid: number, attribute: string) {
return await this.api.binary(eid, attribute);
}
}

@@ -1,5 +0,8 @@

import Api, { ResultSet, RQLParamValue } from "./Api";
import { ResultSet, RQLParamValue } from "./Api";
export type BinariesParam = Record<string, Blob>;
export class Transaction {
private _queries: Array<TransactionQuery> = [];
private _binaries: BinariesParam = {};

@@ -19,2 +22,10 @@ push(

setBinaries(binaries?: BinariesParam) {
this._binaries = binaries ?? {};
}
get binaries(): BinariesParam {
return this._binaries;
}
get queries(): ReadonlyArray<TransactionQuery> {

@@ -28,2 +39,6 @@ return this._queries;

get(queryIndex: number): ResultSet {
return this.resultSets[queryIndex];
}
resolve(ref: TransactionQueryRef) {

@@ -67,12 +82,1 @@ return this.resultSets[ref.queryIndex][ref.row][ref.column];

}
export interface TransactionBackend {
execute(transaction: Transaction): Promise<TransactionResult>;
}
export class NativeTransactionBackend implements TransactionBackend {
constructor(private _api: Api) {}
async execute(transaction: Transaction): Promise<TransactionResult> {
return this._api.executeTransaction(transaction);
}
}

@@ -11,2 +11,4 @@ import { EntityRawSchemaArray } from "../raw/Entities";

* Instead, retrieve these objects from the methods in the `Schema` class.
*
* @category Schema
*/

@@ -13,0 +15,0 @@ export class EntitySchema<

@@ -16,2 +16,4 @@ import { InconsistentSchemaError } from "../../Errors";

* Instead, retrieve these objects from the methods in the `Schema` class.
*
* @category Schema
*/

@@ -18,0 +20,0 @@ export class RelationDefinitionSchema<

@@ -22,2 +22,4 @@ import { EntityRawSchemaArray } from "../raw/Entities";

* as it is more robust to schema changes and provides utility functions.
*
* @category Schema
*/

@@ -24,0 +26,0 @@ export class Schema<

@@ -17,2 +17,4 @@ import { EntityRawSchemaArray } from "../raw/Entities";

* An entity role in a relation.
*
* @category Utils
*/

@@ -27,2 +29,4 @@ export type EntityRole = "subject" | "object";

* @returns A loosely typed schema
*
* @category Utils
*/

@@ -43,2 +47,4 @@ export const getLooseSchema = <

* @returns True if the cardinality is 1 or +
*
* @category Utils
*/

@@ -54,2 +60,4 @@ export function isCardinalityRequired(cardinality: Cardinality): boolean {

* @returns True if the cardinality is `*` or `+`
*
* @category Utils
*/

@@ -65,2 +73,4 @@ export const isCardinalityMultiple = (cardinality: Cardinality): boolean => {

* @returns True if the cardinality is `?` or `*`
*
* @category Utils
*/

@@ -76,2 +86,4 @@ export const isCardinalityOptional = (cardinality: Cardinality): boolean => {

* @returns "object" if the given role was "subject", "subject" otherwise
*
* @category Utils
*/

@@ -91,2 +103,4 @@ export function getOppositeRelationRole(role: EntityRole): EntityRole {

* @returns True if the relation type starts with the reverse indicator
*
* @category Utils
*/

@@ -107,2 +121,4 @@ export const isRelationTypeReversed = (relationType: string): boolean => {

* @returns "subject" if the relation is not reversed, "object" otherwise
*
* @category Utils
*/

@@ -122,2 +138,4 @@ export const getRoleFromRelationType = (relationType: string): EntityRole => {

* @returns The relation type with the reverse indicator added or removed
*
* @category Utils
*/

@@ -141,2 +159,4 @@ export const getReverseRelationType = (relationType: string): string => {

* @returns The relation type with the reverse indicator added or removed
*
* @category Utils
*/

@@ -161,2 +181,4 @@ export const getRawRelationType = (relationType: string): string => {

* @returns A relation type with the reverse indicator if necessary
*
* @category Utils
*/

@@ -177,2 +199,4 @@ export const getRelationType = (relationType: string, role: EntityRole) => {

* @returns The relation definition matching the triplet source relation target
*
* @category Utils
*/

@@ -199,2 +223,4 @@ export const getRelationDefinition = (

* Partial raw relation definition schema type.
*
* @category Utils
*/

@@ -210,2 +236,4 @@ export type RelationDefinitionMatcher<E extends EntityRawSchemaArray> = Partial<

* and TypeScript will give compile errors.
*
* @category Utils
*/

@@ -212,0 +240,0 @@ export type MatchedRelationDefinition<

@@ -13,3 +13,3 @@ /**

/**
* THe type of a constraint message when one is present.
* The type of a constraint message when one is present.
*/

@@ -37,2 +37,4 @@ type ConstraintMessage = string | null;

* @property \_\_attribute\_\_ name of the attribute in the same entity
*
* @category Schema
*/

@@ -55,2 +57,4 @@ export interface Attribute {

* @property type name of the Python class used to do the comparison
*
* @category Schema
*/

@@ -68,2 +72,4 @@ export interface Today {

* @property offset delta to current date at the time of the check
*
* @category Schema
*/

@@ -77,9 +83,7 @@ export interface Now {

* All the possible operators inside a constraint.
*
* @category Schema
*/
export type ConstraintOperator = ">" | ">=" | "<" | "<=";
/**
* @property value.boundary boudary value to compare the attribut
*
*/
export type BoundaryConstraint = ConstraintBase<

@@ -123,2 +127,4 @@ "BoundaryConstraint",

* Type representing all possible constraints for attributes.
*
* @category Schema
*/

@@ -138,2 +144,4 @@ export type AttributeConstraint = Readonly<

* Type representing all possible constraints for relations.
*
* @category Schema
*/

@@ -140,0 +148,0 @@ export type RelationConstraint = Readonly<

/**
* Type representing an entity schema.
*
* @category Schema
*/

@@ -12,3 +14,5 @@ export type EntityRawSchema = {

* Type representing a list of entity schemas.
*
* @category Schema
*/
export type EntityRawSchemaArray = ReadonlyArray<EntityRawSchema>;

@@ -7,2 +7,4 @@ import { EntityRole } from "../classes/Utils";

* Type representing all the possible cardinalities in CubicWeb.
*
* @category Schema
*/

@@ -13,2 +15,4 @@ export type Cardinality = "*" | "1" | "?" | "+";

* Type representing a cardinality pair as used in relation definitions.
*
* @category Schema
*/

@@ -115,2 +119,4 @@ export type CardinalityPair = `${Cardinality}${Cardinality}`;

* Type representing the possible options for an attribute.
*
* @category Schema
*/

@@ -125,2 +131,4 @@ export type AttributeOptions = {

* Type representing the possible options for a relation definition.
*
* @category Schema
*/

@@ -139,2 +147,4 @@ export type RelationOptions = {

* It can infer default values type depending on the object type if the relation is final.
*
* @category Schema
*/

@@ -166,2 +176,4 @@ export type RelationDefinitionRawSchema<

* Type representing a list of relation definitions.
*
* @category Schema
*/

@@ -168,0 +180,0 @@ export type RelationDefinitionRawSchemaArray<

@@ -9,2 +9,4 @@ import { EntityRawSchemaArray } from "./Entities";

* `cubicweb-ctl export-schema -f typescript <YOUR_INSTANCE_NAME>`
*
* @category Schema
*/

@@ -11,0 +13,0 @@ export type RawSchema<

@@ -9,2 +9,4 @@ import { EntityRawSchemaArray } from "./Entities";

* If the schema is strongly typed, the entities type would be a word (which is stricter than string).
*
* @category Schema
*/

@@ -17,2 +19,4 @@ export type IsLooseSchema<E extends EntityRawSchemaArray> =

* Use this to create conditional types.
*
* @category Schema
*/

@@ -27,2 +31,4 @@ export type IsETypeInStrictSchema<

* This type only works for EntityRawSchemaArray with literals as "type" property.
*
* @category Schema
*/

@@ -29,0 +35,0 @@ export type EntityRawSchemaByType<

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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