@cubicweb/client 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +502 -0
- package/README.md +3 -0
- package/lib/Errors.d.ts +10 -0
- package/lib/Errors.d.ts.map +1 -0
- package/lib/Errors.js +25 -0
- package/lib/Errors.js.map +1 -0
- package/lib/api/Api.d.ts +27 -0
- package/lib/api/Api.d.ts.map +1 -0
- package/lib/api/Api.js +94 -0
- package/lib/api/Api.js.map +1 -0
- package/lib/api/Client.d.ts +11 -0
- package/lib/api/Client.d.ts.map +1 -0
- package/lib/api/Client.js +46 -0
- package/lib/api/Client.js.map +1 -0
- package/lib/api/Transaction.d.ts +15 -0
- package/lib/api/Transaction.d.ts.map +1 -0
- package/lib/api/Transaction.js +60 -0
- package/lib/api/Transaction.js.map +1 -0
- package/lib/index.d.ts +6 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +30 -0
- package/lib/index.js.map +1 -0
- package/lib/schema/Schema.d.ts +169 -0
- package/lib/schema/Schema.d.ts.map +1 -0
- package/lib/schema/Schema.js +269 -0
- package/lib/schema/Schema.js.map +1 -0
- package/lib/schema/SchemaJSON.d.ts +121 -0
- package/lib/schema/SchemaJSON.d.ts.map +1 -0
- package/lib/schema/SchemaJSON.js +3 -0
- package/lib/schema/SchemaJSON.js.map +1 -0
- package/package.json +21 -0
- package/src/Errors.ts +26 -0
- package/src/api/Api.ts +97 -0
- package/src/api/Client.ts +30 -0
- package/src/api/Transaction.ts +47 -0
- package/src/index.ts +16 -0
- package/src/schema/Schema.ts +414 -0
- package/src/schema/SchemaJSON.ts +195 -0
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RelationDefinitionSchema = exports.EntitySchema = exports.Schema = exports.getLooseSchema = void 0;
|
|
4
|
+
const Errors_1 = require("../Errors");
|
|
5
|
+
const rawSchemaKey = Symbol("Indexer of the rawSchema");
|
|
6
|
+
/**
|
|
7
|
+
* Returns the given schema using loose typing.
|
|
8
|
+
* Can be useful when working for generic schemas
|
|
9
|
+
*
|
|
10
|
+
* @param schema The schema to create a loose type for
|
|
11
|
+
* @returns
|
|
12
|
+
*/
|
|
13
|
+
const getLooseSchema = (schema) => {
|
|
14
|
+
return schema;
|
|
15
|
+
};
|
|
16
|
+
exports.getLooseSchema = getLooseSchema;
|
|
17
|
+
/**
|
|
18
|
+
* Wrapper around the raw JSON Schema
|
|
19
|
+
*/
|
|
20
|
+
class Schema {
|
|
21
|
+
constructor(rawSchema) {
|
|
22
|
+
this[rawSchemaKey] = rawSchema;
|
|
23
|
+
}
|
|
24
|
+
get entities() {
|
|
25
|
+
return this[rawSchemaKey].entities.map((eSchema) => new EntitySchema(this, eSchema));
|
|
26
|
+
}
|
|
27
|
+
get relationsDefinitions() {
|
|
28
|
+
return this[rawSchemaKey].relations_definitions.map((rdefSchema) => new RelationDefinitionSchema(this, rdefSchema));
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Returns the entity schema for the given entity type if it exists.
|
|
32
|
+
* When using TypeScript, this method can detect if the given type does not exist
|
|
33
|
+
* in the schema.
|
|
34
|
+
*
|
|
35
|
+
* @param entityType The entity type string
|
|
36
|
+
* @returns A new EntitySchema or null if the type does not exist
|
|
37
|
+
*/
|
|
38
|
+
getEntity(entityType) {
|
|
39
|
+
const entityRawSchema = this[rawSchemaKey].entities.filter((eSchema) => eSchema.type === entityType)[0];
|
|
40
|
+
if (!entityRawSchema) {
|
|
41
|
+
// Is only null when the given type is not in the schema.
|
|
42
|
+
// Thus the return type will be (EntitySchema | null)
|
|
43
|
+
// but TypeScript does not understand this
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
45
|
+
// @ts-ignore
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
49
|
+
// @ts-ignore
|
|
50
|
+
return new EntitySchema(this, entityRawSchema);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Finds relations in the Schema matching the partial relation given
|
|
54
|
+
*
|
|
55
|
+
* @param matcher Partial relation definition to match against
|
|
56
|
+
* @returns Matched relation schema classes
|
|
57
|
+
*/
|
|
58
|
+
matchRelationDefinitions(matcher) {
|
|
59
|
+
const matchArray = this[rawSchemaKey].relations_definitions.filter((relDef) => {
|
|
60
|
+
for (const key of Object.keys(matcher)) {
|
|
61
|
+
if (matcher[key] !== relDef[key]) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return true;
|
|
66
|
+
});
|
|
67
|
+
return matchArray.map((m) => new RelationDefinitionSchema(this, m));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
exports.Schema = Schema;
|
|
71
|
+
/**
|
|
72
|
+
* Wrapper around raw entities from the Schema
|
|
73
|
+
*/
|
|
74
|
+
class EntitySchema {
|
|
75
|
+
constructor(schema, entityRawSchema) {
|
|
76
|
+
this.schema = schema;
|
|
77
|
+
this.entityRawSchema = entityRawSchema;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* The type of the entity. This can also be referred to as the entity' name.
|
|
81
|
+
*/
|
|
82
|
+
get type() {
|
|
83
|
+
return this.entityRawSchema.type;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* A short description which can be used as documentation for the entity.
|
|
87
|
+
*/
|
|
88
|
+
get description() {
|
|
89
|
+
return this.entityRawSchema.description;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* True if the current entity is a primitive type such as string or int
|
|
93
|
+
*/
|
|
94
|
+
get final() {
|
|
95
|
+
return this.entityRawSchema.final;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Gets the list of relation definitions with this entity as subject
|
|
99
|
+
*/
|
|
100
|
+
get subjectRelationDefinitions() {
|
|
101
|
+
return this.schema.matchRelationDefinitions({
|
|
102
|
+
subject: this.type,
|
|
103
|
+
final: false,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Gets the list of relation definitions with this entity as object
|
|
108
|
+
*/
|
|
109
|
+
get objectRelationsDefinitions() {
|
|
110
|
+
return this.schema.matchRelationDefinitions({
|
|
111
|
+
object: this.type,
|
|
112
|
+
final: false,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Finds the first relation of the given type with this entity as subject
|
|
117
|
+
*
|
|
118
|
+
* @param relationType The relation type to find
|
|
119
|
+
* @throws RelationNotFoundError if the current entity is not a subject of the given relation
|
|
120
|
+
* @returns The found relation
|
|
121
|
+
*/
|
|
122
|
+
getSubjectRelationDefinition(relationType) {
|
|
123
|
+
const resultArray = this.schema.matchRelationDefinitions({
|
|
124
|
+
subject: this.type,
|
|
125
|
+
type: relationType,
|
|
126
|
+
});
|
|
127
|
+
if (resultArray.length > 0) {
|
|
128
|
+
return resultArray[0];
|
|
129
|
+
}
|
|
130
|
+
throw new Errors_1.RelationNotFoundError(relationType, "subject", this.type);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Finds the first relation of the given type with this entity as object
|
|
134
|
+
*
|
|
135
|
+
* @param relationType The relation type to find
|
|
136
|
+
* @throws RelationNotFoundError if the current entity is not an object of the given relation
|
|
137
|
+
* @returns The found relation
|
|
138
|
+
*/
|
|
139
|
+
getObjectRelationDefinition(relationType) {
|
|
140
|
+
const resultArray = this.schema.matchRelationDefinitions({
|
|
141
|
+
object: this.type,
|
|
142
|
+
type: relationType,
|
|
143
|
+
});
|
|
144
|
+
if (resultArray.length > 0) {
|
|
145
|
+
return resultArray[0];
|
|
146
|
+
}
|
|
147
|
+
throw new Errors_1.RelationNotFoundError(relationType, "object", this.type);
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Gets the list of attributes names for this entity
|
|
151
|
+
*/
|
|
152
|
+
get attributes() {
|
|
153
|
+
return this.schema.matchRelationDefinitions({
|
|
154
|
+
final: true,
|
|
155
|
+
subject: this.type,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Checks whether the current entity is required for the given relation and role
|
|
160
|
+
*
|
|
161
|
+
* @param relationType The relation to check
|
|
162
|
+
* @param role The role for this entity in the given relation
|
|
163
|
+
* @returns True if this entity is required in the relation for the given role
|
|
164
|
+
*/
|
|
165
|
+
isRelationRequired(relationType, role) {
|
|
166
|
+
let relation;
|
|
167
|
+
let cardinality;
|
|
168
|
+
if (role === "subject") {
|
|
169
|
+
relation = this.getSubjectRelationDefinition(relationType);
|
|
170
|
+
cardinality = relation.cardinality[0];
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
relation = this.getObjectRelationDefinition(relationType);
|
|
174
|
+
cardinality = relation.cardinality[1];
|
|
175
|
+
}
|
|
176
|
+
return cardinalityRequired(cardinality);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
exports.EntitySchema = EntitySchema;
|
|
180
|
+
/**
|
|
181
|
+
* Wrapper around raw relation definitions from the Schema
|
|
182
|
+
*/
|
|
183
|
+
class RelationDefinitionSchema {
|
|
184
|
+
constructor(schema, relDef) {
|
|
185
|
+
this.schema = schema;
|
|
186
|
+
this.relDef = relDef;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* The type of the relation. This can also be referred to as the relation's name.
|
|
190
|
+
*/
|
|
191
|
+
get type() {
|
|
192
|
+
return this.relDef.type;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* A short description which can be used as documentation for the relation.
|
|
196
|
+
*/
|
|
197
|
+
get description() {
|
|
198
|
+
return this.relDef.description;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* True if the object of the relation is a primitive type.
|
|
202
|
+
* In this case the relation iscalled an "attribute"
|
|
203
|
+
*/
|
|
204
|
+
get final() {
|
|
205
|
+
return this.relDef.final;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* The list of constraints if any. Only attributes (relations with final = true) have constraints.
|
|
209
|
+
* In other cases this returns null.
|
|
210
|
+
*/
|
|
211
|
+
get constraints() {
|
|
212
|
+
return this.relDef.constraints;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* The default value for this relation.
|
|
216
|
+
* It can be used when creating new relations if user did not enter a value (even if required).
|
|
217
|
+
*/
|
|
218
|
+
get default() {
|
|
219
|
+
return ("default" in this.relDef ? this.relDef.default : undefined);
|
|
220
|
+
}
|
|
221
|
+
get cardinality() {
|
|
222
|
+
return this.relDef.cardinality;
|
|
223
|
+
}
|
|
224
|
+
get subjectCardinality() {
|
|
225
|
+
return this.relDef.cardinality[0];
|
|
226
|
+
}
|
|
227
|
+
get objectCardinality() {
|
|
228
|
+
return this.relDef.cardinality[1];
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Gets the entity associated to this relation's subject
|
|
232
|
+
*
|
|
233
|
+
* @throws InconsistentSchemaError if the relation's subject is not a valid entity
|
|
234
|
+
*/
|
|
235
|
+
get subject() {
|
|
236
|
+
const subjectSchema = this.schema.getEntity(this.relDef.subject);
|
|
237
|
+
if (subjectSchema === null) {
|
|
238
|
+
throw new Errors_1.InconsistentSchemaError(`entity type ${this.relDef.subject} used as subject of relation ${this.type} is not declared`);
|
|
239
|
+
}
|
|
240
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
241
|
+
// @ts-ignore
|
|
242
|
+
return subjectSchema;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Gets the entity associated to this relation's object
|
|
246
|
+
*
|
|
247
|
+
* @throws InconsistentSchemaError if the relation's object is not a valid entity
|
|
248
|
+
*/
|
|
249
|
+
get object() {
|
|
250
|
+
const objectSchema = this.schema.getEntity(this.relDef.object);
|
|
251
|
+
if (objectSchema === null) {
|
|
252
|
+
throw new Errors_1.InconsistentSchemaError(`entity type ${this.relDef.object} used as object of relation ${this.type} is not declared`);
|
|
253
|
+
}
|
|
254
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
255
|
+
// @ts-ignore
|
|
256
|
+
return objectSchema;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
exports.RelationDefinitionSchema = RelationDefinitionSchema;
|
|
260
|
+
/**
|
|
261
|
+
* Checks if the given cardinality requires at least one entity to be present
|
|
262
|
+
*
|
|
263
|
+
* @param cardinality The cardinality to check
|
|
264
|
+
* @returns
|
|
265
|
+
*/
|
|
266
|
+
function cardinalityRequired(cardinality) {
|
|
267
|
+
return cardinality === "1" || cardinality === "+";
|
|
268
|
+
}
|
|
269
|
+
//# sourceMappingURL=Schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Schema.js","sourceRoot":"","sources":["../../src/schema/Schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
declare type ConstraintBase<T extends string, V extends Record<string, unknown> | null> = {
|
|
2
|
+
type: T;
|
|
3
|
+
value: V;
|
|
4
|
+
};
|
|
5
|
+
export declare type ConstraintOperator = ">" | ">=" | "<" | "<=";
|
|
6
|
+
declare type ConstraintMessage = string | null;
|
|
7
|
+
export declare type UniqueConstraint = ConstraintBase<"UniqueConstraint", null>;
|
|
8
|
+
export declare type SizeConstraint = ConstraintBase<"SizeConstraint", {
|
|
9
|
+
min: number | null;
|
|
10
|
+
max: number | null;
|
|
11
|
+
msg: ConstraintMessage;
|
|
12
|
+
}>;
|
|
13
|
+
export declare type RegexpConstraint = ConstraintBase<"RegexpConstraint", {
|
|
14
|
+
regexp: string;
|
|
15
|
+
flags: number;
|
|
16
|
+
msg: ConstraintMessage;
|
|
17
|
+
}>;
|
|
18
|
+
export declare type BoundaryConstraint = ConstraintBase<"BoundaryConstraint", {
|
|
19
|
+
boundary: number | null;
|
|
20
|
+
op: ConstraintOperator;
|
|
21
|
+
msg: ConstraintMessage;
|
|
22
|
+
}>;
|
|
23
|
+
export declare type IntervalBoundConstraint = ConstraintBase<"IntervalBoundConstraint", {
|
|
24
|
+
minvalue: number | null;
|
|
25
|
+
maxvalue: number | null;
|
|
26
|
+
msg: ConstraintMessage;
|
|
27
|
+
}>;
|
|
28
|
+
export declare type StaticVocabularyConstraint = ConstraintBase<"StaticVocabularyConstraint", {
|
|
29
|
+
values: string[];
|
|
30
|
+
msg: ConstraintMessage;
|
|
31
|
+
}>;
|
|
32
|
+
export declare type FormatConstraint = ConstraintBase<"FormatConstraint", {
|
|
33
|
+
values: ["text/rest", "text/markdown", "text/html", "text/plain"];
|
|
34
|
+
msg: ConstraintMessage;
|
|
35
|
+
}>;
|
|
36
|
+
export declare type Constraint = Readonly<UniqueConstraint | SizeConstraint | RegexpConstraint | BoundaryConstraint | IntervalBoundConstraint | StaticVocabularyConstraint | FormatConstraint>;
|
|
37
|
+
declare type BuildObjBase<T extends string> = {
|
|
38
|
+
object: T;
|
|
39
|
+
final: true;
|
|
40
|
+
required?: boolean;
|
|
41
|
+
};
|
|
42
|
+
interface StringBuildObj extends BuildObjBase<"String"> {
|
|
43
|
+
default: string | null;
|
|
44
|
+
}
|
|
45
|
+
interface PasswordBuildObj extends BuildObjBase<"Password"> {
|
|
46
|
+
default: string | null;
|
|
47
|
+
}
|
|
48
|
+
interface BytesBuildObj extends BuildObjBase<"Bytes"> {
|
|
49
|
+
default: string | null;
|
|
50
|
+
}
|
|
51
|
+
interface IntBuildObj extends BuildObjBase<"Int"> {
|
|
52
|
+
default: number | null;
|
|
53
|
+
}
|
|
54
|
+
interface BigIntBuildObj extends BuildObjBase<"BigInt"> {
|
|
55
|
+
default: number | null;
|
|
56
|
+
}
|
|
57
|
+
interface FloatBuildObj extends BuildObjBase<"Float"> {
|
|
58
|
+
default: number | null;
|
|
59
|
+
}
|
|
60
|
+
interface BooleanBuildObj extends BuildObjBase<"Boolean"> {
|
|
61
|
+
default: boolean | null;
|
|
62
|
+
}
|
|
63
|
+
interface DecimalBuildObj extends BuildObjBase<"Decimal"> {
|
|
64
|
+
default: number | null;
|
|
65
|
+
}
|
|
66
|
+
interface DateBuildObj extends BuildObjBase<"Date"> {
|
|
67
|
+
default: unknown;
|
|
68
|
+
}
|
|
69
|
+
interface TimeBuildObj extends BuildObjBase<"Time"> {
|
|
70
|
+
default: unknown;
|
|
71
|
+
}
|
|
72
|
+
interface DatetimeBuildObj extends BuildObjBase<"Datetime"> {
|
|
73
|
+
default: Date | "NOW" | "TODAY" | null;
|
|
74
|
+
}
|
|
75
|
+
interface TZTimeBuildObj extends BuildObjBase<"TZTime"> {
|
|
76
|
+
default: unknown;
|
|
77
|
+
}
|
|
78
|
+
interface TZDatetimeBuildObj extends BuildObjBase<"TZDatetime"> {
|
|
79
|
+
default: unknown;
|
|
80
|
+
}
|
|
81
|
+
interface IntervalBuildObj extends BuildObjBase<"Interval"> {
|
|
82
|
+
default: unknown;
|
|
83
|
+
}
|
|
84
|
+
export declare type BuildObj = Readonly<StringBuildObj | PasswordBuildObj | BytesBuildObj | IntBuildObj | BigIntBuildObj | FloatBuildObj | BooleanBuildObj | DecimalBuildObj | DateBuildObj | TimeBuildObj | DatetimeBuildObj | TZTimeBuildObj | TZDatetimeBuildObj | IntervalBuildObj>;
|
|
85
|
+
export declare type Cardinality = "*" | "1" | "?" | "+";
|
|
86
|
+
export declare type CardinalityPair = `${Cardinality}${Cardinality}`;
|
|
87
|
+
export declare type EntityRawSchema = {
|
|
88
|
+
type: string;
|
|
89
|
+
final: boolean;
|
|
90
|
+
description: string;
|
|
91
|
+
};
|
|
92
|
+
export declare type EntityRawSchemaArray = ReadonlyArray<EntityRawSchema>;
|
|
93
|
+
export declare type RelationDefinitionRawSchema<ESchemas extends EntityRawSchemaArray, Final extends boolean = boolean> = Readonly<{
|
|
94
|
+
type: string;
|
|
95
|
+
description: string;
|
|
96
|
+
cardinality: CardinalityPair;
|
|
97
|
+
subject: ESchemas[number]["type"];
|
|
98
|
+
} & (Final extends true ? BuildObj & {
|
|
99
|
+
constraints: Constraint[];
|
|
100
|
+
} : {
|
|
101
|
+
object: EntityRawSchema["type"];
|
|
102
|
+
final: false;
|
|
103
|
+
constraints: null;
|
|
104
|
+
})>;
|
|
105
|
+
export declare type RelationDefinitionRawSchemaArray<ESchemas extends EntityRawSchemaArray> = ReadonlyArray<RelationDefinitionRawSchema<ESchemas, boolean>>;
|
|
106
|
+
export declare type RawSchema<E extends EntityRawSchemaArray = EntityRawSchemaArray, R extends RelationDefinitionRawSchemaArray<E> = RelationDefinitionRawSchemaArray<E>> = {
|
|
107
|
+
entities: E;
|
|
108
|
+
relations_definitions: R;
|
|
109
|
+
};
|
|
110
|
+
export declare type IsLooseSchema<E extends EntityRawSchemaArray> = string extends E[number]["type"] ? true : false;
|
|
111
|
+
export declare type IsETypeInStrictSchema<E extends EntityRawSchemaArray, EType extends string> = EType extends E[number]["type"] ? true : false;
|
|
112
|
+
/**
|
|
113
|
+
* Type representing the entity's raw schema matching this type.
|
|
114
|
+
* This type only works for EntityRawSchemaArray with literals as "type" property.
|
|
115
|
+
*
|
|
116
|
+
**/
|
|
117
|
+
export declare type EntityRawSchemaByType<E extends EntityRawSchemaArray, T extends string> = E[number] extends infer ESchema ? ESchema extends {
|
|
118
|
+
type: T;
|
|
119
|
+
} ? ESchema : never : never;
|
|
120
|
+
export {};
|
|
121
|
+
//# sourceMappingURL=SchemaJSON.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaJSON.d.ts","sourceRoot":"","sources":["../../src/schema/SchemaJSON.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaJSON.js","sourceRoot":"","sources":["../../src/schema/SchemaJSON.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cubicweb/client",
|
|
3
|
+
"description": "Official JS client for CubicWeb API",
|
|
4
|
+
"author": "Logilab",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"license": "LGPL-2.1-or-later",
|
|
7
|
+
"main": "lib/index.js",
|
|
8
|
+
"types": "lib/index.d.ts",
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsc --project tsconfig.build.json"
|
|
11
|
+
},
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "hg",
|
|
14
|
+
"url": "https://forge.extranet.logilab.fr/cubicweb/cubicwebjs"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"cubicweb",
|
|
18
|
+
"client",
|
|
19
|
+
"js"
|
|
20
|
+
]
|
|
21
|
+
}
|
package/src/Errors.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export class InconsistentSchemaError extends Error {
|
|
2
|
+
constructor(message: string) {
|
|
3
|
+
super(`Inconsistent schema: ${message}`);
|
|
4
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export class RelationNotFoundError extends Error {
|
|
9
|
+
constructor(
|
|
10
|
+
entityType: string,
|
|
11
|
+
role: "object" | "subject",
|
|
12
|
+
relationType: string
|
|
13
|
+
) {
|
|
14
|
+
super(
|
|
15
|
+
`Relation Not Found: relation type ${relationType} with entity type ${entityType} as ${role} is not declared`
|
|
16
|
+
);
|
|
17
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export class TransactionClosedError extends Error {
|
|
22
|
+
constructor() {
|
|
23
|
+
super("Trying to use a closed transaction");
|
|
24
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
25
|
+
}
|
|
26
|
+
}
|
package/src/api/Api.ts
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { RawSchema } from "../schema/SchemaJSON";
|
|
2
|
+
|
|
3
|
+
export type RQLQuery = [string, RQLParams];
|
|
4
|
+
|
|
5
|
+
export interface RQLParams {
|
|
6
|
+
[key: string]: string | number;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export type RqlRow = Array<string | number | boolean | null>;
|
|
10
|
+
export type ResultSet = Array<RqlRow>;
|
|
11
|
+
export type ApiError = { error: string; message: string };
|
|
12
|
+
export type ApiErrorResponse = {
|
|
13
|
+
status: number;
|
|
14
|
+
} & ApiError;
|
|
15
|
+
|
|
16
|
+
export default class Api {
|
|
17
|
+
private apiUrl: string;
|
|
18
|
+
private transactionApiUrl: string;
|
|
19
|
+
|
|
20
|
+
constructor(apiUrl: string) {
|
|
21
|
+
this.apiUrl = `${apiUrl}/v1`;
|
|
22
|
+
this.transactionApiUrl = `${this.apiUrl}/transaction`;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async execute(query: string, params: RQLParams) {
|
|
26
|
+
return fetchApi(`${this.apiUrl}/rql`, {
|
|
27
|
+
method: "POST",
|
|
28
|
+
body: JSON.stringify({ query, params }),
|
|
29
|
+
credentials: "include", // FIXME is it secure?
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async schema(): Promise<RawSchema> {
|
|
34
|
+
const res = await fetch(`${this.apiUrl}/schema`);
|
|
35
|
+
const schema = await res.json();
|
|
36
|
+
return schema as RawSchema;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async transactionBegin() {
|
|
40
|
+
const body = JSON.stringify({ action: "begin" });
|
|
41
|
+
return await fetch(this.transactionApiUrl, {
|
|
42
|
+
method: "POST",
|
|
43
|
+
body,
|
|
44
|
+
credentials: "include",
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async transactionExecute(uuid: string, query: string, params: RQLParams) {
|
|
49
|
+
const body = JSON.stringify({ action: "execute", uuid, query, params });
|
|
50
|
+
return fetchApi(this.transactionApiUrl, {
|
|
51
|
+
method: "POST",
|
|
52
|
+
body,
|
|
53
|
+
credentials: "include",
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async transactionCommit(uuid: string) {
|
|
58
|
+
const body = JSON.stringify({ action: "commit", uuid });
|
|
59
|
+
return await fetch(this.transactionApiUrl, {
|
|
60
|
+
method: "POST",
|
|
61
|
+
body,
|
|
62
|
+
credentials: "include",
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async transactionRollback(uuid: string) {
|
|
67
|
+
const body = JSON.stringify({ action: "commit", uuid });
|
|
68
|
+
return await fetch(this.transactionApiUrl, {
|
|
69
|
+
method: "POST",
|
|
70
|
+
body,
|
|
71
|
+
credentials: "include",
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export const fetchApi = (input: RequestInfo, init?: RequestInit) => {
|
|
77
|
+
return new Promise(
|
|
78
|
+
(
|
|
79
|
+
resolve: (value: ResultSet) => void,
|
|
80
|
+
reject: (reason: ApiErrorResponse) => void
|
|
81
|
+
) =>
|
|
82
|
+
fetch(input, init).then((response) => {
|
|
83
|
+
const status = response.status;
|
|
84
|
+
if (status === 200) {
|
|
85
|
+
response.json().then(resolve);
|
|
86
|
+
} else {
|
|
87
|
+
response.json().then((data: ApiError) => {
|
|
88
|
+
reject({
|
|
89
|
+
status,
|
|
90
|
+
error: data.error,
|
|
91
|
+
message: data.message,
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
})
|
|
96
|
+
);
|
|
97
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Schema } from "../schema/Schema";
|
|
2
|
+
import Api, { RQLParams } from "./Api";
|
|
3
|
+
import Transaction from "./Transaction";
|
|
4
|
+
|
|
5
|
+
export default class Client {
|
|
6
|
+
private api: Api;
|
|
7
|
+
|
|
8
|
+
constructor(apiUrl: string) {
|
|
9
|
+
this.api = new Api(apiUrl);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async execute(query: string, params: RQLParams = {}) {
|
|
13
|
+
return await this.api.execute(query, params);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async schema(): Promise<Schema> {
|
|
17
|
+
const schema = await this.api.schema();
|
|
18
|
+
return new Schema(schema);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async transaction<T>(callback: (tr: Transaction) => Promise<T>): Promise<T> {
|
|
22
|
+
const transaction = new Transaction(this.api);
|
|
23
|
+
await transaction.begin();
|
|
24
|
+
const result = await callback(transaction);
|
|
25
|
+
if (!transaction.isClosed()) {
|
|
26
|
+
transaction.commit();
|
|
27
|
+
}
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { TransactionClosedError } from "../Errors";
|
|
2
|
+
import Api, { RQLParams } from "./Api";
|
|
3
|
+
|
|
4
|
+
export default class Transaction {
|
|
5
|
+
private _uuid: string | null = null;
|
|
6
|
+
private _closed = false;
|
|
7
|
+
|
|
8
|
+
constructor(private api: Api) {}
|
|
9
|
+
|
|
10
|
+
isClosed() {
|
|
11
|
+
return this._closed;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
get uuid() {
|
|
15
|
+
return this._uuid;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async begin() {
|
|
19
|
+
this._closed = false;
|
|
20
|
+
const response = await this.api.transactionBegin();
|
|
21
|
+
const json = await response.json();
|
|
22
|
+
this._uuid = json;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async execute(query: string, params: RQLParams = {}) {
|
|
26
|
+
this.preventUsageIfClosed();
|
|
27
|
+
return await this.api.transactionExecute(this.uuid, query, params);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async commit() {
|
|
31
|
+
this.preventUsageIfClosed();
|
|
32
|
+
await this.api.transactionCommit(this.uuid);
|
|
33
|
+
this._closed = true;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async rollback() {
|
|
37
|
+
this.preventUsageIfClosed();
|
|
38
|
+
await this.api.transactionRollback(this.uuid);
|
|
39
|
+
this._closed = true;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
private preventUsageIfClosed(): asserts this is { uuid: string } {
|
|
43
|
+
if (this.isClosed()) {
|
|
44
|
+
throw new TransactionClosedError();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export {
|
|
2
|
+
getLooseSchema,
|
|
3
|
+
Schema,
|
|
4
|
+
EntitySchema,
|
|
5
|
+
RelationDefinitionSchema,
|
|
6
|
+
} from "./schema/Schema";
|
|
7
|
+
export * from "./schema/SchemaJSON";
|
|
8
|
+
export * from "./Errors";
|
|
9
|
+
export { default as Client } from "./api/Client";
|
|
10
|
+
export {
|
|
11
|
+
RQLQuery,
|
|
12
|
+
RQLParams,
|
|
13
|
+
RqlRow,
|
|
14
|
+
ResultSet,
|
|
15
|
+
ApiErrorResponse,
|
|
16
|
+
} from "./api/Api";
|