@cubicweb/client 1.4.0 → 1.5.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.
Files changed (74) hide show
  1. package/lib/api/Api.d.ts +87 -3
  2. package/lib/api/Api.d.ts.map +1 -1
  3. package/lib/api/Api.js +99 -10
  4. package/lib/api/Api.js.map +1 -1
  5. package/lib/api/Client.d.ts +39 -1
  6. package/lib/api/Client.d.ts.map +1 -1
  7. package/lib/api/Client.js +41 -1
  8. package/lib/api/Client.js.map +1 -1
  9. package/lib/api/Transaction.d.ts +42 -0
  10. package/lib/api/Transaction.d.ts.map +1 -1
  11. package/lib/api/Transaction.js +42 -0
  12. package/lib/api/Transaction.js.map +1 -1
  13. package/lib/index.d.ts +9 -3
  14. package/lib/index.d.ts.map +1 -1
  15. package/lib/index.js +13 -9
  16. package/lib/index.js.map +1 -1
  17. package/lib/schema/classes/EntitySchema.d.ts +71 -0
  18. package/lib/schema/classes/EntitySchema.d.ts.map +1 -0
  19. package/lib/schema/classes/EntitySchema.js +83 -0
  20. package/lib/schema/classes/EntitySchema.js.map +1 -0
  21. package/lib/schema/classes/RelationDefinitionSchema.d.ts +87 -0
  22. package/lib/schema/classes/RelationDefinitionSchema.d.ts.map +1 -0
  23. package/lib/schema/classes/RelationDefinitionSchema.js +128 -0
  24. package/lib/schema/classes/RelationDefinitionSchema.js.map +1 -0
  25. package/lib/schema/classes/Schema.d.ts +54 -0
  26. package/lib/schema/classes/Schema.d.ts.map +1 -0
  27. package/lib/schema/classes/Schema.js +75 -0
  28. package/lib/schema/classes/Schema.js.map +1 -0
  29. package/lib/schema/classes/Utils.d.ts +30 -0
  30. package/lib/schema/classes/Utils.d.ts.map +1 -0
  31. package/lib/schema/classes/Utils.js +25 -0
  32. package/lib/schema/classes/Utils.js.map +1 -0
  33. package/lib/schema/raw/Constraints.d.ts +58 -0
  34. package/lib/schema/raw/Constraints.d.ts.map +1 -0
  35. package/lib/schema/raw/Constraints.js +3 -0
  36. package/lib/schema/raw/Constraints.js.map +1 -0
  37. package/lib/schema/raw/Entities.d.ts +13 -0
  38. package/lib/schema/raw/Entities.d.ts.map +1 -0
  39. package/lib/schema/{SchemaJSON.js → raw/Entities.js} +1 -1
  40. package/lib/schema/raw/Entities.js.map +1 -0
  41. package/lib/schema/raw/RelationDefinitions.d.ts +113 -0
  42. package/lib/schema/raw/RelationDefinitions.d.ts.map +1 -0
  43. package/lib/schema/raw/RelationDefinitions.js +3 -0
  44. package/lib/schema/raw/RelationDefinitions.js.map +1 -0
  45. package/lib/schema/raw/Schema.d.ts +13 -0
  46. package/lib/schema/raw/Schema.d.ts.map +1 -0
  47. package/lib/schema/raw/Schema.js +3 -0
  48. package/lib/schema/raw/Schema.js.map +1 -0
  49. package/lib/schema/raw/Utils.d.ts +22 -0
  50. package/lib/schema/raw/Utils.d.ts.map +1 -0
  51. package/lib/schema/raw/Utils.js +3 -0
  52. package/lib/schema/raw/Utils.js.map +1 -0
  53. package/package.json +1 -1
  54. package/src/api/Api.ts +128 -15
  55. package/src/api/Client.ts +42 -1
  56. package/src/api/Transaction.ts +42 -0
  57. package/src/index.ts +15 -8
  58. package/src/schema/classes/EntitySchema.ts +125 -0
  59. package/src/schema/classes/RelationDefinitionSchema.ts +156 -0
  60. package/src/schema/classes/Schema.ts +122 -0
  61. package/src/schema/classes/Utils.ts +52 -0
  62. package/src/schema/raw/Constraints.ts +77 -0
  63. package/src/schema/raw/Entities.ts +13 -0
  64. package/src/schema/{SchemaJSON.ts → raw/RelationDefinitions.ts} +36 -101
  65. package/src/schema/raw/Schema.ts +16 -0
  66. package/src/schema/raw/Utils.ts +33 -0
  67. package/lib/schema/Schema.d.ts +0 -156
  68. package/lib/schema/Schema.d.ts.map +0 -1
  69. package/lib/schema/Schema.js +0 -246
  70. package/lib/schema/Schema.js.map +0 -1
  71. package/lib/schema/SchemaJSON.d.ts +0 -140
  72. package/lib/schema/SchemaJSON.d.ts.map +0 -1
  73. package/lib/schema/SchemaJSON.js.map +0 -1
  74. package/src/schema/Schema.ts +0 -371
@@ -1,36 +1,78 @@
1
1
  import { TransactionClosedError } from "../Errors";
2
2
  import Api, { RQLParams } from "./Api";
3
3
 
4
+ /**
5
+ * Class used to handle CubicWeb's transactions.
6
+ * A transaction allows to execute several RQL requests without altering the database until all
7
+ * changes are committed.
8
+ *
9
+ * You should never have to create this object yourself.
10
+ * Instead, retrieve this object from the methods in the `Client` class.
11
+ */
4
12
  export default class Transaction {
5
13
  private _uuid: string | null = null;
6
14
  private _closed = false;
7
15
 
16
+ /**
17
+ * Class used to handle CubicWeb's transactions.
18
+ * A transaction allows to execute several RQL requests without altering the database until all
19
+ * changes are committed.
20
+ *
21
+ * You should never have to create this object yourself.
22
+ * Instead, retrieve this object from the methods in the `Client` class.
23
+ *
24
+ * @param api The API object used to communicate with the CubicWeb backend.
25
+ */
8
26
  constructor(private api: Api) {}
9
27
 
28
+ /**
29
+ * @returns True if the connection is closed.
30
+ */
10
31
  isClosed() {
11
32
  return this._closed;
12
33
  }
13
34
 
35
+ /**
36
+ * This transaction unique identifier.
37
+ */
14
38
  get uuid() {
15
39
  return this._uuid;
16
40
  }
17
41
 
42
+ /**
43
+ * Begins a new transaction an retrieves the associated uuid.
44
+ */
18
45
  async begin() {
19
46
  this._closed = false;
20
47
  this._uuid = await this.api.transactionBegin();
21
48
  }
22
49
 
50
+ /**
51
+ * Executes the given query and waits for the response.
52
+ * Make sure you called `begin` before using this method.
53
+ * As this is a transaction changes will only be applied when you call the `commit` method.
54
+ *
55
+ * @param query The RQL query to send
56
+ * @param params The additional parameters for the request
57
+ * @returns A promise with the request's result set
58
+ */
23
59
  async execute(query: string, params: RQLParams = {}) {
24
60
  this.preventUsageIfClosed();
25
61
  return await this.api.transactionExecute(this.uuid, query, params);
26
62
  }
27
63
 
64
+ /**
65
+ * Commits the transaction to apply all the RQL queries sent with `execute`.
66
+ */
28
67
  async commit() {
29
68
  this.preventUsageIfClosed();
30
69
  await this.api.transactionCommit(this.uuid);
31
70
  this._closed = true;
32
71
  }
33
72
 
73
+ /**
74
+ * Rollbacks all the queries sent with `execute` and closes the transaction.
75
+ */
34
76
  async rollback() {
35
77
  this.preventUsageIfClosed();
36
78
  await this.api.transactionRollback(this.uuid);
package/src/index.ts CHANGED
@@ -1,13 +1,20 @@
1
- export {
2
- getLooseSchema,
3
- Schema,
4
- EntitySchema,
5
- RelationDefinitionSchema,
6
- } from "./schema/Schema";
7
- export * from "./schema/SchemaJSON";
1
+ // Raw Schema
2
+ export * from "./schema/raw/Constraints";
3
+ export * from "./schema/raw/Entities";
4
+ export * from "./schema/raw/RelationDefinitions";
5
+ export * from "./schema/raw/Schema";
6
+ export * from "./schema/raw/Utils";
7
+
8
+ // Schema Abstraction class
9
+ export * from "./schema/classes/EntitySchema";
10
+ export * from "./schema/classes/RelationDefinitionSchema";
11
+ export * from "./schema/classes/Schema";
12
+ export * from "./schema/classes/Utils";
13
+
8
14
  export * from "./Errors";
15
+
16
+ // API
9
17
  export { default as Client } from "./api/Client";
10
- export { default as Api } from "./api/Api";
11
18
  export { default as Transaction } from "./api/Transaction";
12
19
  export {
13
20
  RQLQuery,
@@ -0,0 +1,125 @@
1
+ import { EntityRawSchemaArray } from "../raw/Entities";
2
+ import { RelationDefinitionRawSchemaArray } from "../raw/RelationDefinitions";
3
+ import { RelationDefinitionSchema } from "./RelationDefinitionSchema";
4
+ import { Schema } from "./Schema";
5
+ import { MatchedRelationDefinition, RelationDefinitionMatcher } from "./Utils";
6
+
7
+ /**
8
+ * Wrapper around raw entity schemas from the Schema.
9
+ * You should never have to create this object yourself.
10
+ * Instead, retrieve these objects from the methods in the `Schema` class.
11
+ */
12
+ export class EntitySchema<
13
+ E extends EntityRawSchemaArray = EntityRawSchemaArray,
14
+ R extends RelationDefinitionRawSchemaArray<E> = RelationDefinitionRawSchemaArray<E>,
15
+ ERawSchema extends E[number] = E[number]
16
+ > {
17
+ /**
18
+ * Wrapper around raw entity schemas from the Schema.
19
+ * You should never have to create this object yourself.
20
+ * Instead, retrieve these objects from the methods in the `Schema` class.
21
+ *
22
+ * @param schema The Schema abstraction class used to create this object
23
+ * @param entityRawSchema The raw entity schema
24
+ */
25
+ constructor(
26
+ private schema: Schema<E, R>,
27
+ private entityRawSchema: ERawSchema
28
+ ) {}
29
+
30
+ /**
31
+ * The type of the entity schema. This can also be referred to as the entity schema's name.
32
+ */
33
+ get type(): ERawSchema["type"] {
34
+ return this.entityRawSchema.type;
35
+ }
36
+
37
+ /**
38
+ * A short description which can be used as documentation for the entity schema.
39
+ */
40
+ get description(): ERawSchema["description"] {
41
+ return this.entityRawSchema.description;
42
+ }
43
+
44
+ /**
45
+ * True if the current entity schema is a primitive type such as string or int
46
+ */
47
+ get final(): ERawSchema["final"] {
48
+ return this.entityRawSchema.final;
49
+ }
50
+
51
+ /**
52
+ * Gets the list of relation definitions schemas with this entity as subject.
53
+ * In case a relation definition schema has this entity as both object and subject,
54
+ * there will be dupicates when used along with `objectRelationsDefinitions`.
55
+ */
56
+ get subjectRelationDefinitions(): RelationDefinitionSchema<
57
+ E,
58
+ R,
59
+ MatchedRelationDefinition<
60
+ E,
61
+ R,
62
+ { subject: ERawSchema["type"]; final: false }
63
+ >
64
+ >[] {
65
+ return this.schema.matchRelationDefinitions({
66
+ subject: this.type,
67
+ final: false,
68
+ });
69
+ }
70
+
71
+ /**
72
+ * Gets the list of relation definitions schemas with this entity as object.
73
+ * In case a relation definition schema has this entity as both object and subject,
74
+ * there will be dupicates when used along with `subjectRelationDefinitions`.
75
+ */
76
+ get objectRelationsDefinitions(): RelationDefinitionSchema<
77
+ E,
78
+ R,
79
+ MatchedRelationDefinition<
80
+ E,
81
+ R,
82
+ { object: ERawSchema["type"]; final: false }
83
+ >
84
+ >[] {
85
+ return this.schema.matchRelationDefinitions({
86
+ object: this.type,
87
+ final: false,
88
+ });
89
+ }
90
+
91
+ /**
92
+ * Finds relations in the Schema matching the partial relation given.
93
+ *
94
+ * @param matcher Partial relation definition to match against
95
+ * @returns Matched relation schema classes
96
+ */
97
+ matchRelationDefinitions<M extends RelationDefinitionMatcher<E>>(
98
+ matcher: M
99
+ ): RelationDefinitionSchema<
100
+ E,
101
+ R,
102
+ MatchedRelationDefinition<E, R, { subject: ERawSchema["type"] }>
103
+ >[] {
104
+ return this.schema.matchRelationDefinitions(matcher);
105
+ }
106
+
107
+ /**
108
+ * Gets the list of attribute schemas (relation definition schemas with final at false)
109
+ * for this entity schema.
110
+ */
111
+ get attributes(): RelationDefinitionSchema<
112
+ E,
113
+ R,
114
+ MatchedRelationDefinition<
115
+ E,
116
+ R,
117
+ { subject: ERawSchema["type"]; final: true }
118
+ >
119
+ >[] {
120
+ return this.schema.matchRelationDefinitions({
121
+ final: true,
122
+ subject: this.type,
123
+ });
124
+ }
125
+ }
@@ -0,0 +1,156 @@
1
+ import { InconsistentSchemaError } from "../../Errors";
2
+ import { EntityRawSchemaArray } from "../raw/Entities";
3
+ import {
4
+ RelationDefinitionRawSchemaArray,
5
+ Cardinality,
6
+ } from "../raw/RelationDefinitions";
7
+ import { IsLooseSchema, EntityRawSchemaByType } from "../raw/Utils";
8
+ import { EntitySchema } from "./EntitySchema";
9
+ import { Schema } from "./Schema";
10
+ import { cardinalityRequired } from "./Utils";
11
+
12
+ /**
13
+ * Wrapper around raw relation definition schemas from the Schema.
14
+ * You should never have to create this object yourself.
15
+ * Instead, retrieve these objects from the methods in the `Schema` class.
16
+ */
17
+ export class RelationDefinitionSchema<
18
+ E extends EntityRawSchemaArray = EntityRawSchemaArray,
19
+ R extends RelationDefinitionRawSchemaArray<E> = RelationDefinitionRawSchemaArray<E>,
20
+ RDef extends R[number] = R[number]
21
+ > {
22
+ /**
23
+ * Wrapper around raw relation definition schemas from the Schema.
24
+ * You should never have to create this object yourself.
25
+ * Instead, retrieve these objects from the methods in the `Schema` class.
26
+ *
27
+ * @param schema The Schema abstractin class used to create this object
28
+ * @param relDef The raw relation definition schema
29
+ */
30
+ constructor(private schema: Schema<E, R>, private relDef: RDef) {}
31
+
32
+ /**
33
+ * The type of the relation definition. This can also be referred to as the relation definition's name.
34
+ */
35
+ get type(): RDef["type"] {
36
+ return this.relDef.type;
37
+ }
38
+
39
+ /**
40
+ * A short description which can be used as documentation for the relation definition schema.
41
+ */
42
+ get description(): RDef["description"] {
43
+ return this.relDef.description;
44
+ }
45
+
46
+ /**
47
+ * True if the object of the relation definition schema is a primitive type.
48
+ * In this case the relation is called an "attribute".
49
+ */
50
+ get final(): RDef["final"] {
51
+ return this.relDef.final;
52
+ }
53
+
54
+ /**
55
+ * The list of options set for this relation definition schema.
56
+ * The returned type will change if this relationd definition schema
57
+ * describes an attribute or a relation.
58
+ */
59
+ get options(): RDef["options"] {
60
+ return this.relDef.options;
61
+ }
62
+
63
+ /**
64
+ * The list of constraints set for this relation definition schema.
65
+ * The returned type will change if this relationd definition schema
66
+ * describes an attribute or a relation.
67
+ */
68
+ get constraints(): RDef["constraints"] {
69
+ return this.relDef.constraints;
70
+ }
71
+
72
+ /**
73
+ * The default value for this relation.
74
+ * It can be used when creating new relations if the user did not enter a value (even if required).
75
+ */
76
+ get default(): RDef extends { default: infer V } ? V : undefined {
77
+ type Default = RDef extends { default: infer V } ? V : undefined;
78
+
79
+ return (
80
+ "default" in this.relDef ? this.relDef.default : undefined
81
+ ) as Default;
82
+ }
83
+
84
+ /**
85
+ * The cardinality of this relation definition schema.
86
+ */
87
+ get cardinality(): RDef["cardinality"] {
88
+ return this.relDef.cardinality;
89
+ }
90
+
91
+ /**
92
+ * The cardinality of this relation definition schema's subject.
93
+ */
94
+ get subjectCardinality(): Cardinality {
95
+ return this.relDef.cardinality[0] as Cardinality;
96
+ }
97
+
98
+ /**
99
+ * The cardinality of this relation definition schema's object.
100
+ */
101
+ get objectCardinality(): Cardinality {
102
+ return this.relDef.cardinality[1] as Cardinality;
103
+ }
104
+
105
+ /**
106
+ * Gets the entity associated to this relation definition schema's subject.
107
+ *
108
+ * @throws InconsistentSchemaError if the relation definition schema's subject is not a valid entity
109
+ */
110
+ get subject(): IsLooseSchema<E> extends true
111
+ ? EntitySchema<E, R, E[number]>
112
+ : EntitySchema<E, R, EntityRawSchemaByType<E, RDef["subject"]>> {
113
+ const subjectSchema = this.schema.getEntity(this.relDef.subject);
114
+ if (subjectSchema === null) {
115
+ throw new InconsistentSchemaError(
116
+ `entity type ${this.relDef.subject} used as subject of relation ${this.type} is not declared`
117
+ );
118
+ }
119
+ // @ts-ignore: Cannot be null as we checked for this above
120
+ return subjectSchema;
121
+ }
122
+
123
+ /**
124
+ * Gets the entity associated to this relation definition schema's object.
125
+ *
126
+ * @throws InconsistentSchemaError if the relation definition schema's object is not a valid entity
127
+ */
128
+ get object(): IsLooseSchema<E> extends true
129
+ ? EntitySchema<E, R, E[number]>
130
+ : EntitySchema<E, R, EntityRawSchemaByType<E, RDef["object"]>> {
131
+ const objectSchema = this.schema.getEntity(this.relDef.object);
132
+ if (objectSchema === null) {
133
+ throw new InconsistentSchemaError(
134
+ `entity type ${this.relDef.object} used as object of relation ${this.type} is not declared`
135
+ );
136
+ }
137
+ // @ts-ignore: Cannot be null as we checked for this above
138
+ return objectSchema;
139
+ }
140
+
141
+ /**
142
+ * Checks if the relation is required when using the subject or object point of view.
143
+ *
144
+ * @param role The point of view to use
145
+ * @returns
146
+ */
147
+ isRequired(role: "subject" | "object") {
148
+ let cardinality: Cardinality;
149
+ if (role === "subject") {
150
+ cardinality = this.subjectCardinality;
151
+ } else {
152
+ cardinality = this.objectCardinality;
153
+ }
154
+ return cardinalityRequired(cardinality);
155
+ }
156
+ }
@@ -0,0 +1,122 @@
1
+ import { EntityRawSchemaArray } from "../raw/Entities";
2
+ import {
3
+ RelationDefinitionRawSchema,
4
+ RelationDefinitionRawSchemaArray,
5
+ } from "../raw/RelationDefinitions";
6
+ import { RawSchema } from "../raw/Schema";
7
+ import {
8
+ EntityRawSchemaByType,
9
+ IsETypeInStrictSchema,
10
+ IsLooseSchema,
11
+ } from "../raw/Utils";
12
+ import { EntitySchema } from "./EntitySchema";
13
+ import { RelationDefinitionSchema } from "./RelationDefinitionSchema";
14
+ import { RelationDefinitionMatcher, MatchedRelationDefinition } from "./Utils";
15
+
16
+ const rawSchemaKey: unique symbol = Symbol("Indexer of the rawSchema");
17
+
18
+ /**
19
+ * Wrapper around the raw JSON Schema.
20
+ * It is recommended to use this class instead of the raw JSON Schema
21
+ * as it is more robust to schema changes and provides utility functions.
22
+ */
23
+ export class Schema<
24
+ E extends EntityRawSchemaArray = EntityRawSchemaArray,
25
+ R extends RelationDefinitionRawSchemaArray<E> = RelationDefinitionRawSchemaArray<E>
26
+ > {
27
+ [rawSchemaKey]: RawSchema<E, R>;
28
+
29
+ /**
30
+ * Wrapper around the raw JSON Schema.
31
+ * It is recommended to use this class instead of the raw JSON Schema
32
+ * as it is more robust to schema changes and provides utility functions.
33
+ *
34
+ * @param rawSchema The raw JSON schema to create the wrapper from.
35
+ */
36
+ constructor(rawSchema: RawSchema<E, R>) {
37
+ this[rawSchemaKey] = rawSchema;
38
+ }
39
+
40
+ /**
41
+ * Returns the list of entity schemas in the schema using the EntitySchema abstraction class.
42
+ */
43
+ get entities(): EntitySchema<E, R, E[number]>[] {
44
+ return this[rawSchemaKey].entities.map(
45
+ (eSchema) => new EntitySchema(this, eSchema)
46
+ );
47
+ }
48
+
49
+ /**
50
+ * Returns the list of relation definitions schemas in the schema
51
+ * using the RelationDefinitionSchema abstraction class.
52
+ */
53
+ get relationsDefinitions(): RelationDefinitionSchema<E, R, R[number]>[] {
54
+ return this[rawSchemaKey].relations_definitions.map(
55
+ (rdefSchema) => new RelationDefinitionSchema(this, rdefSchema)
56
+ );
57
+ }
58
+
59
+ /**
60
+ * Returns the entity schema for the given entity type if it exists.
61
+ * When using TypeScript, this method can detect if the given type does not exist
62
+ * in the schema.
63
+ *
64
+ * @param entityType The entity type string
65
+ * @returns A new EntitySchema or null if the type does not exist
66
+ */
67
+ getEntity<EType extends string>(
68
+ entityType: EType
69
+ ): IsLooseSchema<E> extends true
70
+ ? EntitySchema<E, R, E[number]> | null
71
+ : IsETypeInStrictSchema<E, EType> extends true
72
+ ? EntitySchema<E, R, EntityRawSchemaByType<E, EType>>
73
+ : null {
74
+ const entityRawSchema = this[rawSchemaKey].entities.filter(
75
+ (eSchema) => eSchema.type === entityType
76
+ )[0];
77
+ if (!entityRawSchema) {
78
+ // @ts-ignore: Is only null when the given type is not in the schema.
79
+ // Thus the return type will be (EntitySchema | null)
80
+ // but TypeScript does not understand this
81
+ return null;
82
+ }
83
+ // @ts-ignore: see above
84
+ return new EntitySchema<E, R, E[number]>(
85
+ this,
86
+ entityRawSchema as EntityRawSchemaByType<E, EType>
87
+ );
88
+ }
89
+
90
+ /**
91
+ * Finds relations definition schemas in the Schema matching the
92
+ * raw partial relation definition schema given.
93
+ *
94
+ * @param matcher Partial raw relation definition schema to match against
95
+ * @returns Array of matched relation definition schema classes
96
+ */
97
+ matchRelationDefinitions<M extends RelationDefinitionMatcher<E>>(
98
+ matcher: M
99
+ ): RelationDefinitionSchema<
100
+ E,
101
+ R,
102
+ MatchedRelationDefinition<E, R, { subject: E[number]["type"] }>
103
+ >[] {
104
+ const matchArray = this[rawSchemaKey].relations_definitions.filter(
105
+ (relDef) => {
106
+ for (const key of Object.keys(
107
+ matcher
108
+ ) as (keyof RelationDefinitionRawSchema<E>)[]) {
109
+ if (matcher[key] !== relDef[key]) {
110
+ return false;
111
+ }
112
+ }
113
+ return true;
114
+ }
115
+ ) as MatchedRelationDefinition<
116
+ E,
117
+ R,
118
+ MatchedRelationDefinition<E, R, { subject: E[number]["type"] }>
119
+ >[];
120
+ return matchArray.map((m) => new RelationDefinitionSchema(this, m));
121
+ }
122
+ }
@@ -0,0 +1,52 @@
1
+ import { EntityRawSchemaArray } from "../raw/Entities";
2
+ import {
3
+ Cardinality,
4
+ RelationDefinitionRawSchema,
5
+ RelationDefinitionRawSchemaArray,
6
+ } from "../raw/RelationDefinitions";
7
+ import { Schema } from "./Schema";
8
+
9
+ /**
10
+ * Returns the given schema using loose typing.
11
+ * Can be useful when working with generic schemas
12
+ *
13
+ * @param schema The schema to create a loose type for
14
+ * @returns A loosely typed schema
15
+ */
16
+ export const getLooseSchema = <
17
+ E extends EntityRawSchemaArray = EntityRawSchemaArray,
18
+ R extends RelationDefinitionRawSchemaArray<E> = RelationDefinitionRawSchemaArray<E>
19
+ >(
20
+ schema: Schema<E, R>
21
+ ) => {
22
+ return schema as unknown as Schema;
23
+ };
24
+
25
+ /**
26
+ * Checks if the given cardinality requires at least one entity to be present
27
+ *
28
+ * @param cardinality The cardinality to check
29
+ * @returns True if the cardinality is 1 or +
30
+ */
31
+ export function cardinalityRequired(cardinality: Cardinality): boolean {
32
+ return cardinality === "1" || cardinality === "+";
33
+ }
34
+
35
+ /**
36
+ * Partial raw relation definition schema type.
37
+ */
38
+ export type RelationDefinitionMatcher<E extends EntityRawSchemaArray> = Partial<
39
+ RelationDefinitionRawSchema<E>
40
+ >;
41
+
42
+ /**
43
+ * Type representing a raw relation definition matched from a partial raw relation definition schema.
44
+ * If it finds a relation definition matching the partial one given, it will return its type.
45
+ * If it cannot find any relation definition matching, it will return the `never` type
46
+ * and TypeScript will give compile errors.
47
+ */
48
+ export type MatchedRelationDefinition<
49
+ E extends EntityRawSchemaArray,
50
+ R extends RelationDefinitionRawSchemaArray<EntityRawSchemaArray>,
51
+ M extends RelationDefinitionMatcher<E>
52
+ > = R[number] extends infer RDef ? (RDef extends M ? RDef : never) : never;
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Base type used to describe a constraint.
3
+ */
4
+ type ConstraintBase<
5
+ T extends string,
6
+ V extends Record<string, unknown> | null
7
+ > = {
8
+ type: T;
9
+ value: V;
10
+ };
11
+
12
+ /**
13
+ * All the possible operators inside a constraint.
14
+ */
15
+ export type ConstraintOperator = ">" | ">=" | "<" | "<=";
16
+
17
+ /**
18
+ * THe type of a constraint message when one is present.
19
+ */
20
+ type ConstraintMessage = string | null;
21
+
22
+ export type UniqueConstraint = ConstraintBase<"UniqueConstraint", null>;
23
+
24
+ export type SizeConstraint = ConstraintBase<
25
+ "SizeConstraint",
26
+ { min: number | null; max: number | null; msg: ConstraintMessage }
27
+ >;
28
+
29
+ export type RegexpConstraint = ConstraintBase<
30
+ "RegexpConstraint",
31
+ { regexp: string; flags: number; msg: ConstraintMessage }
32
+ >;
33
+
34
+ export type BoundaryConstraint = ConstraintBase<
35
+ "BoundaryConstraint",
36
+ { boundary: number | null; op: ConstraintOperator; msg: ConstraintMessage }
37
+ >;
38
+ export type IntervalBoundConstraint = ConstraintBase<
39
+ "IntervalBoundConstraint",
40
+ { minvalue: number | null; maxvalue: number | null; msg: ConstraintMessage }
41
+ >;
42
+
43
+ export type StaticVocabularyConstraint = ConstraintBase<
44
+ "StaticVocabularyConstraint",
45
+ { values: string[]; msg: ConstraintMessage }
46
+ >;
47
+
48
+ export type FormatConstraint = ConstraintBase<
49
+ "FormatConstraint",
50
+ {
51
+ values: ["text/rest", "text/markdown", "text/html", "text/plain"];
52
+ msg: ConstraintMessage;
53
+ }
54
+ >;
55
+
56
+ export type RQLVocabularyConstraint = ConstraintBase<
57
+ "RQLVocabularyConstraint",
58
+ { expression: string; mainvars: string[] }
59
+ >;
60
+
61
+ /**
62
+ * Type representing all possible constraints for attributes.
63
+ */
64
+ export type AttributeConstraint = Readonly<
65
+ | UniqueConstraint
66
+ | SizeConstraint
67
+ | RegexpConstraint
68
+ | BoundaryConstraint
69
+ | IntervalBoundConstraint
70
+ | StaticVocabularyConstraint
71
+ | FormatConstraint
72
+ >;
73
+
74
+ /**
75
+ * Type representing all possible constraints for relations.
76
+ */
77
+ export type RelationConstraint = Readonly<RQLVocabularyConstraint>;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Type representing an entity schema.
3
+ */
4
+ export type EntityRawSchema = {
5
+ type: string;
6
+ final: boolean;
7
+ description: string;
8
+ };
9
+
10
+ /**
11
+ * Type representing a list of entity schemas.
12
+ */
13
+ export type EntityRawSchemaArray = ReadonlyArray<EntityRawSchema>;