@strapi/strapi 4.13.0-beta.0 → 4.13.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 (62) hide show
  1. package/README.md +13 -5
  2. package/lib/Strapi.js +11 -0
  3. package/lib/commands/actions/import/action.js +4 -4
  4. package/lib/commands/actions/import/command.js +1 -1
  5. package/lib/commands/actions/transfer/action.js +3 -6
  6. package/lib/commands/actions/transfer/command.js +1 -1
  7. package/lib/commands/actions/watch-admin/action.js +1 -1
  8. package/lib/commands/builders/admin.js +1 -1
  9. package/lib/commands/utils/data-transfer.js +39 -1
  10. package/lib/core/loaders/index.js +1 -0
  11. package/lib/core/loaders/plugins/get-enabled-plugins.js +40 -13
  12. package/lib/core/loaders/sanitizers.js +1 -1
  13. package/lib/core/loaders/validators.js +5 -0
  14. package/lib/core/registries/validators.js +26 -0
  15. package/lib/core-api/controller/collection-type.js +14 -8
  16. package/lib/core-api/controller/index.js +15 -3
  17. package/lib/core-api/controller/single-type.js +2 -0
  18. package/lib/factories.d.ts +10 -13
  19. package/lib/factories.js +12 -2
  20. package/lib/services/entity-service/index.d.ts +1 -100
  21. package/lib/services/entity-service/index.js +1 -0
  22. package/lib/services/entity-service/types/index.d.ts +228 -0
  23. package/lib/services/entity-service/types/params/attributes.d.ts +146 -0
  24. package/lib/services/entity-service/types/params/data.d.ts +4 -0
  25. package/lib/services/entity-service/types/params/fields.d.ts +74 -0
  26. package/lib/services/entity-service/types/params/filters/index.d.ts +75 -0
  27. package/lib/services/entity-service/types/params/filters/operators.d.ts +30 -0
  28. package/lib/services/entity-service/types/params/index.d.ts +79 -0
  29. package/lib/services/entity-service/types/params/pagination.d.ts +13 -0
  30. package/lib/services/entity-service/types/params/populate.d.ts +130 -0
  31. package/lib/services/entity-service/types/params/publication-state.d.ts +38 -0
  32. package/lib/services/entity-service/types/params/search.d.ts +1 -0
  33. package/lib/services/entity-service/types/params/sort.d.ts +106 -0
  34. package/lib/services/entity-service/types/plugin.d.ts +11 -0
  35. package/lib/services/entity-service/types/result.d.ts +205 -0
  36. package/lib/types/core/attributes/common.d.ts +13 -10
  37. package/lib/types/core/attributes/component.d.ts +3 -0
  38. package/lib/types/core/attributes/date-time.d.ts +2 -1
  39. package/lib/types/core/attributes/dynamic-zone.d.ts +10 -7
  40. package/lib/types/core/attributes/media.d.ts +8 -0
  41. package/lib/types/core/attributes/relation.d.ts +69 -28
  42. package/lib/types/core/attributes/time.d.ts +1 -1
  43. package/lib/types/core/attributes/timestamp.d.ts +1 -1
  44. package/lib/types/core/attributes/uid.d.ts +7 -17
  45. package/lib/types/core/attributes/utils.d.ts +61 -6
  46. package/lib/types/core/common/index.d.ts +12 -0
  47. package/lib/types/core/common/uid.d.ts +12 -16
  48. package/lib/types/core/index.d.ts +1 -0
  49. package/lib/types/core/plugins/index.d.ts +16 -0
  50. package/lib/types/core/schemas/index.d.ts +1 -0
  51. package/lib/types/core/strapi/index.d.ts +7 -2
  52. package/lib/types/core-api/controller.d.ts +12 -10
  53. package/lib/types/index.d.ts +2 -0
  54. package/lib/types/shared/entity-service.d.ts +1 -0
  55. package/lib/types/shared/index.d.ts +2 -0
  56. package/lib/types/shared/plugins.d.ts +3 -0
  57. package/lib/types/utils/expression.d.ts +29 -6
  58. package/lib/types/utils/guard.d.ts +14 -1
  59. package/lib/types/utils/index.d.ts +8 -0
  60. package/lib/types/utils/object.d.ts +35 -1
  61. package/lib/types/utils/string.d.ts +18 -0
  62. package/package.json +17 -16
@@ -0,0 +1,228 @@
1
+ import type { Attribute, Common, Utils } from '@strapi/strapi';
2
+ import type { PartialEntity, Entity, Result, PaginatedResult } from './result';
3
+
4
+ import type * as Params from './params';
5
+
6
+ // TODO: Move params to @strapi/utils (related to convert-query-params)
7
+ export * as Params from './params';
8
+
9
+ export * from './result';
10
+ export * from './plugin';
11
+
12
+ type WrapAction = Omit<keyof EntityService, 'wrapParams' | 'wrapResult' | 'emitEvent'>;
13
+
14
+ export interface EntityService {
15
+ wrapParams<
16
+ TResult = unknown,
17
+ TContentTypeUID extends Common.UID.ContentType = Common.UID.ContentType,
18
+ TParams extends object = object
19
+ >(
20
+ params?: TParams,
21
+ options?: { uid: TContentTypeUID; action: WrapAction }
22
+ ): Promise<TResult> | TResult;
23
+
24
+ wrapResult<
25
+ TResult = unknown,
26
+ TContentTypeUID extends Common.UID.ContentType = Common.UID.ContentType
27
+ >(
28
+ result: unknown,
29
+ options?: { uid: TContentTypeUID; action: WrapAction }
30
+ ): Promise<TResult> | TResult;
31
+
32
+ emitEvent<TContentTypeUID extends Common.UID.ContentType>(
33
+ uid: TContentTypeUID,
34
+ event: string,
35
+ entity: Entity<TContentTypeUID>
36
+ ): Promise<void>;
37
+ // TODO: Split in 2 different signatures for both single types & collection types
38
+ findMany<
39
+ TContentTypeUID extends Common.UID.ContentType,
40
+ TParams extends Params.Pick<
41
+ TContentTypeUID,
42
+ | 'fields'
43
+ | 'filters'
44
+ | '_q'
45
+ | 'pagination:offset'
46
+ | 'sort'
47
+ | 'populate'
48
+ | 'publicationState'
49
+ | 'plugin'
50
+ >
51
+ >(
52
+ uid: TContentTypeUID,
53
+ params?: TParams
54
+ ): Utils.Expression.MatchFirst<
55
+ [
56
+ [Common.UID.IsCollectionType<TContentTypeUID>, Promise<Result<TContentTypeUID, TParams>[]>],
57
+ [Common.UID.IsSingleType<TContentTypeUID>, Promise<Result<TContentTypeUID, TParams> | null>]
58
+ ],
59
+ Promise<(Result<TContentTypeUID, TParams> | null) | Result<TContentTypeUID, TParams>[]>
60
+ >;
61
+
62
+ findOne<
63
+ TContentTypeUID extends Common.UID.ContentType,
64
+ TParams extends Params.Pick<TContentTypeUID, 'fields' | 'populate'>
65
+ >(
66
+ uid: TContentTypeUID,
67
+ entityId: Params.Attribute.ID,
68
+ params?: TParams
69
+ ): Promise<Result<TContentTypeUID, TParams> | null>;
70
+
71
+ delete<
72
+ TContentTypeUID extends Common.UID.ContentType,
73
+ TParams extends Params.Pick<TContentTypeUID, 'fields' | 'populate'>
74
+ >(
75
+ uid: TContentTypeUID,
76
+ entityId: Params.Attribute.ID,
77
+ params?: TParams
78
+ ): Promise<Result<TContentTypeUID, TParams> | null>;
79
+
80
+ create<
81
+ TContentTypeUID extends Common.UID.ContentType,
82
+ TParams extends Params.Pick<TContentTypeUID, 'data' | 'files' | 'fields' | 'populate'>
83
+ >(
84
+ uid: TContentTypeUID,
85
+ params?: TParams
86
+ ): Promise<Result<TContentTypeUID, TParams>>;
87
+
88
+ update<
89
+ TContentTypeUID extends Common.UID.ContentType,
90
+ TParams extends Params.Pick<TContentTypeUID, 'data:partial' | 'files' | 'fields' | 'populate'>
91
+ >(
92
+ uid: TContentTypeUID,
93
+ entityId: Params.Attribute.ID,
94
+ params?: TParams
95
+ ): Promise<Result<TContentTypeUID, TParams> | null>;
96
+
97
+ findPage<
98
+ TContentTypeUID extends Common.UID.ContentType,
99
+ TParams extends Params.Pick<
100
+ TContentTypeUID,
101
+ | 'fields'
102
+ | 'populate'
103
+ | 'pagination'
104
+ | 'sort'
105
+ | 'filters'
106
+ | '_q'
107
+ | 'publicationState'
108
+ | 'plugin'
109
+ >
110
+ >(
111
+ uid: TContentTypeUID,
112
+ params?: TParams
113
+ ): Promise<PaginatedResult<TContentTypeUID, TParams>>;
114
+
115
+ clone<
116
+ TContentTypeUID extends Common.UID.ContentType,
117
+ TParams extends Params.Pick<TContentTypeUID, 'data' | 'files' | 'fields' | 'populate'>
118
+ >(
119
+ uid: TContentTypeUID,
120
+ cloneId: Params.Attribute.ID,
121
+ params?: TParams
122
+ ): Promise<Result<TContentTypeUID, TParams> | null>;
123
+
124
+ /**
125
+ * @deprecated
126
+ */
127
+ deleteMany<TContentTypeUID extends Common.UID.ContentType>(
128
+ uid: TContentTypeUID,
129
+ params: Params.Pick<TContentTypeUID, 'filters' | '_q'>
130
+ ): Promise<{ count: number }>;
131
+
132
+ /**
133
+ * TODO: seems the same as findMany, it's not returning count by default
134
+ * @deprecated
135
+ */
136
+ findWithRelationCounts<
137
+ TContentTypeUID extends Common.UID.Schema,
138
+ TParams extends Params.Pick<
139
+ TContentTypeUID,
140
+ | 'fields'
141
+ | 'filters'
142
+ | '_q'
143
+ | 'pagination:offset'
144
+ | 'sort'
145
+ | 'populate'
146
+ | 'publicationState'
147
+ | 'plugin'
148
+ >
149
+ >(
150
+ uid: TContentTypeUID,
151
+ params?: TParams
152
+ ): Promise<Result<TContentTypeUID, TParams>[]>;
153
+
154
+ /**
155
+ * @deprecated
156
+ */
157
+ findWithRelationCountsPage<
158
+ TContentTypeUID extends Common.UID.Schema,
159
+ TParams extends Params.Pick<
160
+ TContentTypeUID,
161
+ | 'fields'
162
+ | 'filters'
163
+ | '_q'
164
+ | 'pagination'
165
+ | 'sort'
166
+ | 'populate'
167
+ | 'publicationState'
168
+ | 'plugin'
169
+ >
170
+ >(
171
+ uid: TContentTypeUID,
172
+ params?: TParams
173
+ ): Promise<PaginatedResult<TContentTypeUID, TParams>>;
174
+
175
+ count<TContentTypeUID extends Common.UID.ContentType>(
176
+ uid: TContentTypeUID,
177
+ params?: Params.Pick<TContentTypeUID, 'filters' | '_q'>
178
+ ): Promise<number>;
179
+
180
+ /**
181
+ * TODO: Considering making this API public include providing a valid return type
182
+ * @internal
183
+ */
184
+ load<
185
+ TContentTypeUID extends Common.UID.ContentType,
186
+ TField extends Attribute.GetPopulatableKeys<TContentTypeUID>
187
+ >(
188
+ uid: TContentTypeUID,
189
+ entity: PartialEntity<TContentTypeUID>,
190
+ field: Utils.Guard.Never<TField, string>,
191
+ params?: GetPopulatableFieldParams<TContentTypeUID, TField>
192
+ ): Promise<any>;
193
+
194
+ /**
195
+ * TODO: Considering making this API public include providing a valid return type
196
+ * @internal
197
+ */
198
+ loadPages<
199
+ TContentTypeUID extends Common.UID.ContentType,
200
+ TField extends Attribute.GetPopulatableKeys<TContentTypeUID>
201
+ >(
202
+ uid: TContentTypeUID,
203
+ entity: PartialEntity<TContentTypeUID>,
204
+ field: Utils.Guard.Never<TField, string>,
205
+ params?: GetPopulatableFieldParams<TContentTypeUID, TField>,
206
+ pagination?: Params.Pagination.Any
207
+ ): Promise<any>;
208
+ }
209
+
210
+ type GetPopulatableFieldParams<
211
+ TContentTypeUID extends Common.UID.ContentType,
212
+ TField extends Attribute.GetPopulatableKeys<TContentTypeUID>
213
+ > = Utils.Expression.MatchFirst<
214
+ [
215
+ [
216
+ Attribute.HasTarget<TContentTypeUID, TField>,
217
+ Params.Populate.NestedParams<Attribute.GetTarget<TContentTypeUID, TField>>
218
+ ],
219
+ [
220
+ Attribute.HasMorphTargets<TContentTypeUID, TField>,
221
+ (
222
+ | Params.Populate.Fragment<Attribute.GetMorphTargets<TContentTypeUID, TField>>
223
+ | Params.Populate.NestedParams<Common.UID.Schema>
224
+ )
225
+ ]
226
+ ],
227
+ Params.Populate.Fragment<Common.UID.Schema> | Params.Populate.NestedParams<Common.UID.Schema>
228
+ >;
@@ -0,0 +1,146 @@
1
+ import type { Attribute, Common, Utils } from '@strapi/strapi';
2
+
3
+ export type NonFilterableKind = Extract<Attribute.Kind, 'password' | 'dynamiczone'>;
4
+ export type FilterableKind = Exclude<Attribute.Kind, NonFilterableKind>;
5
+
6
+ export type GetNonFilterableKeys<TSchemaUID extends Common.UID.Schema> = Utils.Object.KeysBy<
7
+ Attribute.GetAll<TSchemaUID>,
8
+ Attribute.OfType<NonFilterableKind>
9
+ >;
10
+
11
+ export type GetScalarKeys<TSchemaUID extends Common.UID.Schema> = Exclude<
12
+ Attribute.GetKeysByType<TSchemaUID, Attribute.NonPopulatableKind>,
13
+ GetNonFilterableKeys<TSchemaUID>
14
+ >;
15
+
16
+ export type GetNestedKeys<TSchemaUID extends Common.UID.Schema> = Exclude<
17
+ Attribute.GetKeysWithTarget<TSchemaUID>,
18
+ GetNonFilterableKeys<TSchemaUID>
19
+ >;
20
+
21
+ export type ID = `${number}` | number;
22
+
23
+ export type BooleanValue = boolean | 'true' | 'false' | 't' | 'f' | '1' | '0' | 1 | 0;
24
+
25
+ export type NumberValue = string | number;
26
+
27
+ export type DateValue = Attribute.DateValue | number;
28
+
29
+ export type TimeValue = Attribute.TimeValue | number;
30
+
31
+ export type DateTimeValue = Attribute.DateTimeValue | number;
32
+
33
+ export type TimeStampValue = Attribute.TimestampValue;
34
+
35
+ /**
36
+ * List of possible values for the scalar attributes
37
+ * Uses the local GetValue to benefit from the values' overrides
38
+ */
39
+ export type ScalarValues = GetValue<
40
+ | Attribute.BigInteger
41
+ | Attribute.Boolean
42
+ | Attribute.DateTime
43
+ | Attribute.Date
44
+ | Attribute.Decimal
45
+ | Attribute.Email
46
+ | Attribute.Enumeration<string[]>
47
+ | Attribute.Float
48
+ | Attribute.Integer
49
+ | Attribute.JSON
50
+ // /!\ Password attributes are NOT filterable and should NOT be part of this union type.
51
+ // The member below has been commented on purpose to avoid adding it back without noticing.
52
+ // | Attribute.Password
53
+ | Attribute.RichText
54
+ | Attribute.String
55
+ | Attribute.Text
56
+ | Attribute.Time
57
+ | Attribute.Timestamp
58
+ | Attribute.UID<Common.UID.Schema | undefined>
59
+ >;
60
+
61
+ /**
62
+ * Attribute.GetValues override with extended values
63
+ */
64
+ export type GetValues<TSchemaUID extends Common.UID.Schema> = OmitRelationWithoutTarget<
65
+ TSchemaUID,
66
+ {
67
+ [TKey in Attribute.GetOptionalKeys<TSchemaUID>]?: GetValue<Attribute.Get<TSchemaUID, TKey>>;
68
+ } & {
69
+ [TKey in Attribute.GetRequiredKeys<TSchemaUID>]-?: GetValue<Attribute.Get<TSchemaUID, TKey>>;
70
+ }
71
+ >;
72
+
73
+ export type OmitRelationWithoutTarget<TSchemaUID extends Common.UID.Schema, TValue> = Omit<
74
+ TValue,
75
+ Exclude<Attribute.GetKeysByType<TSchemaUID, 'relation'>, Attribute.GetKeysWithTarget<TSchemaUID>>
76
+ >;
77
+
78
+ /**
79
+ * Attribute.GetValue override with extended values
80
+ *
81
+ * Fallback to unknown if never is found
82
+ */
83
+ export type GetValue<TAttribute extends Attribute.Attribute> = Utils.Expression.If<
84
+ Utils.Expression.IsNotNever<TAttribute>,
85
+ Utils.Expression.MatchFirst<
86
+ [
87
+ // Relation
88
+ [
89
+ Utils.Expression.Extends<TAttribute, Attribute.OfType<'relation'>>,
90
+ TAttribute extends Attribute.Relation<infer _TOrigin, infer TRelationKind, infer TTarget>
91
+ ? Utils.Expression.If<
92
+ Utils.Expression.IsNotNever<TTarget>,
93
+ Attribute.RelationPluralityModifier<TRelationKind, ID>
94
+ >
95
+ : never
96
+ ],
97
+ // DynamicZone
98
+ [
99
+ Utils.Expression.Extends<TAttribute, Attribute.OfType<'dynamiczone'>>,
100
+ TAttribute extends Attribute.DynamicZone<infer TComponentsUIDs>
101
+ ? Array<
102
+ // Extract tuple values to a component uid union type
103
+ Utils.Array.Values<TComponentsUIDs> extends infer TComponentUID
104
+ ? TComponentUID extends Common.UID.Component
105
+ ? GetValues<TComponentUID> & { __component: TComponentUID }
106
+ : never
107
+ : never
108
+ >
109
+ : never
110
+ ],
111
+ // Component
112
+ [
113
+ Utils.Expression.Extends<TAttribute, Attribute.OfType<'component'>>,
114
+ TAttribute extends Attribute.Component<infer TComponentUID, infer TRepeatable>
115
+ ? TComponentUID extends Common.UID.Component
116
+ ? GetValues<TComponentUID> extends infer TValues
117
+ ? Utils.Expression.If<TRepeatable, TValues[], TValues>
118
+ : never
119
+ : never
120
+ : never
121
+ ],
122
+ // Boolean
123
+ [Utils.Expression.Extends<TAttribute, Attribute.Boolean>, BooleanValue],
124
+ // Number
125
+ [
126
+ Utils.Expression.Extends<
127
+ TAttribute,
128
+ Attribute.Integer | Attribute.BigInteger | Attribute.Float | Attribute.Decimal
129
+ >,
130
+ NumberValue
131
+ ],
132
+ // Date / Time
133
+ [Utils.Expression.Extends<TAttribute, Attribute.Time>, TimeValue],
134
+ [Utils.Expression.Extends<TAttribute, Attribute.Date>, DateValue],
135
+ [
136
+ Utils.Expression.Extends<TAttribute, Attribute.Timestamp | Attribute.DateTime>,
137
+ DateTimeValue
138
+ ],
139
+ // Fallback
140
+ // If none of the above attribute type, fallback to the original Attribute.GetValue (while making sure it's an attribute)
141
+ [Utils.Expression.True, Attribute.GetValue<TAttribute, unknown>]
142
+ ],
143
+ unknown
144
+ >,
145
+ unknown
146
+ >;
@@ -0,0 +1,4 @@
1
+ import { Common } from '@strapi/strapi';
2
+ import * as AttributeUtils from './attributes';
3
+
4
+ export type Input<TSchemaUID extends Common.UID.Schema> = AttributeUtils.GetValues<TSchemaUID>;
@@ -0,0 +1,74 @@
1
+ import type { Attribute, Common, Utils } from '@strapi/strapi';
2
+
3
+ /**
4
+ * Wildcard notation for the fields.
5
+ *
6
+ * When used, it represents every non-populatable field from the given schema
7
+ */
8
+ export type WildcardNotation = '*';
9
+
10
+ /**
11
+ * Single non-populatable attribute representation
12
+ *
13
+ * @example
14
+ * type A = 'title'; // ✅
15
+ * type B = 'description'; // ✅
16
+ * type C = 'populatableField'; // ❌
17
+ * type D = '<random_string>'; // ❌
18
+ */
19
+ export type SingleAttribute<TSchemaUID extends Common.UID.Schema> =
20
+ | 'id'
21
+ | Utils.Guard.Never<Attribute.GetNonPopulatableKeys<TSchemaUID>, string>;
22
+
23
+ /**
24
+ * Union of all possible string representation for fields
25
+ *
26
+ * @example
27
+ * type A = 'title'; // ✅
28
+ * type B = 'title,description'; // ✅
29
+ * type C = 'id'; // ✅
30
+ * type D = '*'; // ✅
31
+ * type E = 'populatableField'; // ❌
32
+ * type F = '<random_string>'; // ❌
33
+ */
34
+ export type StringNotation<TSchemaUID extends Common.UID.Schema> =
35
+ | WildcardNotation
36
+ | SingleAttribute<TSchemaUID>
37
+ // TODO: Loose type checking to avoid circular dependencies & infinite recursion
38
+ | `${string},${string}`;
39
+
40
+ /**
41
+ * Array notation for fields
42
+ *
43
+ * @example
44
+ * type A = ['title']; // ✅
45
+ * type B = ['title', 'description']; // ✅
46
+ * type C = ['id']; // ✅
47
+ * type E = ['*']; // ❌
48
+ * type F = ['populatableField']; // ❌
49
+ * type G = ['<random_string>']; // ❌
50
+ */
51
+ export type ArrayNotation<TSchemaUID extends Common.UID.Schema> = Exclude<
52
+ StringNotation<TSchemaUID>,
53
+ WildcardNotation
54
+ >[];
55
+
56
+ /**
57
+ * Represents any notation for a sort (string, array, object)
58
+ *
59
+ * @example
60
+ * type A = '*'; // ✅
61
+ * type B = 'id'; // ✅
62
+ * type C = 'title'; // ✅
63
+ * type D = 'title,description'; // ✅
64
+ * type E = ['title', 'description']; // ✅
65
+ * type F = [id, 'title,description']; // ✅
66
+ * type G = ['*']; // ❌
67
+ * type H = ['populatableField']; // ❌
68
+ * type I = ['<random_string>']; // ❌
69
+ * type J = 'populatableField'; // ❌
70
+ * type K = '<random_string>'; // ❌
71
+ */
72
+ export type Any<TSchemaUID extends Common.UID.Schema> =
73
+ | StringNotation<TSchemaUID>
74
+ | ArrayNotation<TSchemaUID>;
@@ -0,0 +1,75 @@
1
+ import type { Attribute, Common, Utils } from '@strapi/strapi';
2
+
3
+ import type * as Operator from './operators';
4
+ import type * as AttributeUtils from '../attributes';
5
+
6
+ export { Operator };
7
+
8
+ /**
9
+ * Filter representation for nested attributes
10
+ */
11
+ type NestedAttributeCondition<
12
+ TSchemaUID extends Common.UID.Schema,
13
+ TAttributeName extends Attribute.GetKeys<TSchemaUID>
14
+ > = ObjectNotation<
15
+ Utils.Guard.Never<Attribute.GetTarget<TSchemaUID, TAttributeName>, Common.UID.Schema>
16
+ >;
17
+
18
+ /**
19
+ * Filter representation for scalar attributes
20
+ */
21
+ type AttributeCondition<
22
+ TSchemaUID extends Common.UID.Schema,
23
+ TAttributeName extends Attribute.GetKeys<TSchemaUID>
24
+ > = Utils.Expression.If<
25
+ Utils.Expression.IsNotNever<TAttributeName>,
26
+ // Get the filter attribute value for the given attribute
27
+ AttributeUtils.GetValue<Attribute.Get<TSchemaUID, TAttributeName>>,
28
+ // Fallback to the list of all possible scalar attributes' value if the attribute is not valid (never)
29
+ AttributeUtils.ScalarValues
30
+ > extends infer TAttributeValue
31
+ ?
32
+ | TAttributeValue // Implicit $eq operator
33
+ | ({
34
+ [TIter in Operator.BooleanValue]?: boolean;
35
+ } & {
36
+ [TIter in Operator.DynamicValue]?: TAttributeValue;
37
+ } & {
38
+ [TIter in Operator.DynamicArrayValue]?: TAttributeValue[];
39
+ } & {
40
+ [TIter in Operator.DynamicBoundValue]?: [TAttributeValue, TAttributeValue];
41
+ } & {
42
+ [TIter in Operator.Logical]?: AttributeCondition<TSchemaUID, TAttributeName>;
43
+ } & {
44
+ [TIter in Operator.Group]?: AttributeCondition<TSchemaUID, TAttributeName>[];
45
+ })
46
+ : never;
47
+
48
+ /**
49
+ * Tree representation of a Strapi filter for a given schema UID
50
+ */
51
+ export type ObjectNotation<TSchemaUID extends Common.UID.Schema> = {
52
+ [TIter in Operator.Group]?: ObjectNotation<TSchemaUID>[];
53
+ } & {
54
+ [TIter in Operator.Logical]?: ObjectNotation<TSchemaUID>;
55
+ } & ([AttributeUtils.GetScalarKeys<TSchemaUID>, AttributeUtils.GetNestedKeys<TSchemaUID>] extends [
56
+ infer TScalarKeys extends AttributeUtils.GetScalarKeys<TSchemaUID>,
57
+ infer TNestedKeys extends AttributeUtils.GetNestedKeys<TSchemaUID>
58
+ ]
59
+ ? // If both the scalar and nested keys are resolved, then create a strongly
60
+ // typed filter object, else create a loose generic abstraction.
61
+ Utils.Expression.If<
62
+ Utils.Expression.And<
63
+ Utils.Expression.IsNotNever<TScalarKeys>,
64
+ Utils.Expression.IsNotNever<TNestedKeys>
65
+ >,
66
+ // Strongly typed representation of the filter object tree
67
+ | { [TIter in TScalarKeys]?: AttributeCondition<TSchemaUID, TIter> }
68
+ | { [TIter in TNestedKeys]?: NestedAttributeCondition<TSchemaUID, TIter> },
69
+ // Generic representation of the filter object tree in case we don't have access to the attributes' list
70
+ | { [TKey in string]?: AttributeCondition<TSchemaUID, never> }
71
+ | { [TKey in string]?: NestedAttributeCondition<TSchemaUID, never> }
72
+ >
73
+ : never);
74
+
75
+ export type Any<TSchemaUID extends Common.UID.Schema> = ObjectNotation<TSchemaUID>;
@@ -0,0 +1,30 @@
1
+ export type Array = '$in' | '$notIn' | '$between';
2
+
3
+ export type Group = '$and' | '$or';
4
+
5
+ export type Logical = '$not';
6
+
7
+ export type BooleanValue = '$null' | '$notNull';
8
+
9
+ export type DynamicValue =
10
+ | '$eq'
11
+ | '$eqi'
12
+ | '$ne'
13
+ | '$gt'
14
+ | '$gte'
15
+ | '$lt'
16
+ | '$lte'
17
+ | '$startsWith'
18
+ | '$endsWith'
19
+ | '$startsWithi'
20
+ | '$endsWithi'
21
+ | '$contains'
22
+ | '$notContains'
23
+ | '$containsi'
24
+ | '$notContainsi';
25
+
26
+ export type DynamicArrayValue = '$in' | '$notIn';
27
+
28
+ export type DynamicBoundValue = '$between';
29
+
30
+ export type Where = BooleanValue | DynamicValue | DynamicArrayValue | DynamicBoundValue;
@@ -0,0 +1,79 @@
1
+ import type { Common, EntityService, Utils } from '@strapi/strapi';
2
+ // Params
3
+ import type * as Sort from './sort';
4
+ import type * as Pagination from './pagination';
5
+ import type * as Fields from './fields';
6
+ import type * as Filters from './filters';
7
+ import type * as Populate from './populate';
8
+ import type * as PublicationState from './publication-state';
9
+ import type * as Data from './data';
10
+ import type * as Search from './search';
11
+
12
+ // Utils
13
+ import type * as Attribute from './attributes';
14
+
15
+ export type Pick<
16
+ TSchemaUID extends Common.UID.Schema,
17
+ TKind extends Kind
18
+ > = Utils.Expression.MatchAllIntersect<
19
+ [
20
+ // Sort
21
+ [HasMember<TKind, 'sort'>, { sort?: Sort.Any<TSchemaUID> }],
22
+ [HasMember<TKind, 'sort:string'>, { sort?: Sort.StringNotation<TSchemaUID> }],
23
+ [HasMember<TKind, 'sort:array'>, { sort?: Sort.ArrayNotation<TSchemaUID> }],
24
+ [HasMember<TKind, 'sort:object'>, { sort?: Sort.ObjectNotation<TSchemaUID> }],
25
+ // Fields
26
+ [HasMember<TKind, 'fields'>, { fields?: Fields.Any<TSchemaUID> }],
27
+ [HasMember<TKind, 'fields:string'>, { fields?: Fields.StringNotation<TSchemaUID> }],
28
+ [HasMember<TKind, 'fields:array'>, { fields?: Fields.ArrayNotation<TSchemaUID> }],
29
+ // Filters
30
+ [HasMember<TKind, 'filters'>, { filters?: Filters.Any<TSchemaUID> }],
31
+ // Populate
32
+ [HasMember<TKind, 'populate'>, { populate?: Populate.Any<TSchemaUID> }],
33
+ [HasMember<TKind, 'populate:string'>, { populate?: Populate.StringNotation<TSchemaUID> }],
34
+ [HasMember<TKind, 'populate:array'>, { populate?: Populate.ArrayNotation<TSchemaUID> }],
35
+ [HasMember<TKind, 'populate:object'>, { populate?: Populate.ObjectNotation<TSchemaUID> }],
36
+ // Pagination
37
+ [HasMember<TKind, 'pagination'>, Pagination.Any],
38
+ [HasMember<TKind, 'pagination:offset'>, Pagination.OffsetNotation],
39
+ [HasMember<TKind, 'pagination:page'>, Pagination.PageNotation],
40
+ // Publication State
41
+ [HasMember<TKind, 'publicationState'>, PublicationState.For<TSchemaUID>],
42
+ // Plugin
43
+ [HasMember<TKind, 'plugin'>, EntityService.GetPluginParams<TSchemaUID>],
44
+ // Data
45
+ [HasMember<TKind, 'data'>, { data?: Data.Input<TSchemaUID> }],
46
+ [HasMember<TKind, 'data:partial'>, { data?: Partial<Data.Input<TSchemaUID>> }],
47
+ // Files
48
+ [HasMember<TKind, 'files'>, { files?: unknown }], // TODO
49
+ // Search
50
+ [HasMember<TKind, '_q'>, { _q?: Search.Q }]
51
+ ]
52
+ >;
53
+
54
+ export type Kind =
55
+ | 'sort'
56
+ | 'sort:string'
57
+ | 'sort:array'
58
+ | 'sort:object'
59
+ | 'fields'
60
+ | 'fields:string'
61
+ | 'fields:array'
62
+ | 'filters'
63
+ | 'populate'
64
+ | 'populate:string'
65
+ | 'populate:array'
66
+ | 'populate:object'
67
+ | 'pagination'
68
+ | 'pagination:offset'
69
+ | 'pagination:page'
70
+ | 'publicationState'
71
+ | 'plugin'
72
+ | 'data'
73
+ | 'data:partial'
74
+ | 'files'
75
+ | '_q';
76
+
77
+ type HasMember<TValue extends Kind, TTest extends Kind> = Utils.Expression.Extends<TTest, TValue>;
78
+
79
+ export type { Sort, Pagination, Fields, Filters, Populate, PublicationState, Data, Attribute };
@@ -0,0 +1,13 @@
1
+ import type { Utils } from '@strapi/strapi';
2
+
3
+ export type PageNotation = {
4
+ page?: number;
5
+ pageSize?: number;
6
+ };
7
+
8
+ export type OffsetNotation = {
9
+ start?: number;
10
+ limit?: number;
11
+ };
12
+
13
+ export type Any = Utils.XOR<PageNotation, OffsetNotation>;