@strapi/strapi 4.0.0-next.11 → 4.0.0-next.15
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/bin/strapi.js +1 -4
- package/lib/Strapi.js +82 -28
- package/lib/commands/console.js +1 -1
- package/lib/commands/develop.js +4 -3
- package/lib/core/domain/content-type/index.js +3 -7
- package/lib/core/domain/module/index.js +2 -2
- package/lib/core/loaders/apis.js +4 -6
- package/lib/core/loaders/components.js +3 -5
- package/lib/core/loaders/index.js +1 -0
- package/lib/core/loaders/middlewares.js +1 -1
- package/lib/core/loaders/plugins/get-enabled-plugins.js +2 -2
- package/lib/core/loaders/plugins/index.js +7 -7
- package/lib/core/loaders/policies.js +1 -1
- package/lib/core/loaders/src-index.js +38 -0
- package/lib/core/registries/hooks.js +37 -0
- package/lib/core/registries/services.js +7 -7
- package/lib/core-api/controller/collection-type.js +5 -5
- package/lib/core-api/controller/single-type.js +3 -3
- package/lib/core-api/controller/transform.js +28 -3
- package/lib/core-api/service/collection-type.js +18 -19
- package/lib/core-api/service/single-type.js +10 -14
- package/lib/index.d.ts +9 -31
- package/lib/middlewares/cors/index.js +1 -1
- package/lib/middlewares/{boom → error}/defaults.json +1 -1
- package/lib/middlewares/{boom → error}/index.js +1 -1
- package/lib/middlewares/favicon/index.js +1 -2
- package/lib/middlewares/index.js +1 -1
- package/lib/middlewares/public/index.js +2 -2
- package/lib/middlewares/responses/index.js +2 -1
- package/lib/middlewares/router/index.js +5 -3
- package/lib/migrations/draft-publish.js +57 -0
- package/lib/services/auth/index.js +2 -2
- package/lib/services/core-store.js +64 -49
- package/lib/services/cron.js +54 -0
- package/lib/services/entity-service/components.js +37 -12
- package/lib/services/entity-service/index.d.ts +91 -0
- package/lib/services/entity-service/index.js +52 -50
- package/lib/services/entity-service/params.js +74 -57
- package/lib/services/fs.js +1 -1
- package/lib/services/metrics/index.js +1 -1
- package/lib/services/server/policy.js +15 -4
- package/lib/services/webhook-runner.js +1 -1
- package/lib/utils/ee.js +3 -3
- package/lib/utils/get-dirs.js +15 -0
- package/lib/utils/index.js +2 -0
- package/lib/utils/update-notifier/index.js +2 -1
- package/package.json +88 -98
- package/lib/middlewares/cron/defaults.json +0 -5
- package/lib/middlewares/cron/index.js +0 -43
- package/lib/middlewares/language/defaults.json +0 -9
- package/lib/middlewares/language/index.js +0 -40
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const _ = require('lodash');
|
|
4
|
-
const { has, prop, omit } = require('lodash/fp');
|
|
4
|
+
const { has, prop, omit, toString } = require('lodash/fp');
|
|
5
5
|
|
|
6
6
|
const { contentTypes: contentTypesUtils } = require('@strapi/utils');
|
|
7
7
|
|
|
@@ -131,11 +131,26 @@ const updateComponents = async (uid, entityToUpdate, data) => {
|
|
|
131
131
|
componentValue.map(value => updateOrCreateComponent(componentUID, value))
|
|
132
132
|
);
|
|
133
133
|
|
|
134
|
-
|
|
135
|
-
|
|
134
|
+
componentBody[attributeName] = components.filter(_.negate(_.isNil)).map(({ id }, idx) => {
|
|
135
|
+
return {
|
|
136
|
+
id,
|
|
137
|
+
__pivot: {
|
|
138
|
+
order: idx + 1,
|
|
139
|
+
field: attributeName,
|
|
140
|
+
component_type: componentUID,
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
});
|
|
136
144
|
} else {
|
|
137
145
|
const component = await updateOrCreateComponent(componentUID, componentValue);
|
|
138
|
-
componentBody[attributeName] = component &&
|
|
146
|
+
componentBody[attributeName] = component && {
|
|
147
|
+
id: component.id,
|
|
148
|
+
__pivot: {
|
|
149
|
+
order: 1,
|
|
150
|
+
field: attributeName,
|
|
151
|
+
component_type: componentUID,
|
|
152
|
+
},
|
|
153
|
+
};
|
|
139
154
|
}
|
|
140
155
|
|
|
141
156
|
continue;
|
|
@@ -151,9 +166,17 @@ const updateComponents = async (uid, entityToUpdate, data) => {
|
|
|
151
166
|
}
|
|
152
167
|
|
|
153
168
|
componentBody[attributeName] = await Promise.all(
|
|
154
|
-
dynamiczoneValues.map(async value => {
|
|
169
|
+
dynamiczoneValues.map(async (value, idx) => {
|
|
155
170
|
const { id } = await updateOrCreateComponent(value.__component, value);
|
|
156
|
-
|
|
171
|
+
|
|
172
|
+
return {
|
|
173
|
+
id,
|
|
174
|
+
__component: value.__component,
|
|
175
|
+
__pivot: {
|
|
176
|
+
order: idx + 1,
|
|
177
|
+
field: attributeName,
|
|
178
|
+
},
|
|
179
|
+
};
|
|
157
180
|
})
|
|
158
181
|
);
|
|
159
182
|
|
|
@@ -175,11 +198,13 @@ const deleteOldComponents = async (
|
|
|
175
198
|
|
|
176
199
|
const idsToKeep = _.castArray(componentValue)
|
|
177
200
|
.filter(has('id'))
|
|
178
|
-
.map(prop('id'))
|
|
201
|
+
.map(prop('id'))
|
|
202
|
+
.map(toString);
|
|
179
203
|
|
|
180
204
|
const allIds = _.castArray(previousValue)
|
|
181
205
|
.filter(has('id'))
|
|
182
|
-
.map(prop('id'))
|
|
206
|
+
.map(prop('id'))
|
|
207
|
+
.map(toString);
|
|
183
208
|
|
|
184
209
|
idsToKeep.forEach(id => {
|
|
185
210
|
if (!allIds.includes(id)) {
|
|
@@ -206,14 +231,14 @@ const deleteOldDZComponents = async (uid, entityToUpdate, attributeName, dynamic
|
|
|
206
231
|
const idsToKeep = _.castArray(dynamiczoneValues)
|
|
207
232
|
.filter(has('id'))
|
|
208
233
|
.map(({ id, __component }) => ({
|
|
209
|
-
id,
|
|
234
|
+
id: toString(id),
|
|
210
235
|
__component,
|
|
211
236
|
}));
|
|
212
237
|
|
|
213
238
|
const allIds = _.castArray(previousValue)
|
|
214
239
|
.filter(has('id'))
|
|
215
240
|
.map(({ id, __component }) => ({
|
|
216
|
-
id,
|
|
241
|
+
id: toString(id),
|
|
217
242
|
__component,
|
|
218
243
|
}));
|
|
219
244
|
|
|
@@ -293,7 +318,7 @@ const createComponent = async (uid, data) => {
|
|
|
293
318
|
|
|
294
319
|
const componentData = await createComponents(uid, data);
|
|
295
320
|
|
|
296
|
-
return
|
|
321
|
+
return strapi.query(uid).create({
|
|
297
322
|
data: Object.assign(omitComponentData(model, data), componentData),
|
|
298
323
|
});
|
|
299
324
|
};
|
|
@@ -304,7 +329,7 @@ const updateComponent = async (uid, componentToUpdate, data) => {
|
|
|
304
329
|
|
|
305
330
|
const componentData = await updateComponents(uid, componentToUpdate, data);
|
|
306
331
|
|
|
307
|
-
return
|
|
332
|
+
return strapi.query(uid).update({
|
|
308
333
|
where: {
|
|
309
334
|
id: componentToUpdate.id,
|
|
310
335
|
},
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { Database } from '@strapi/database';
|
|
2
|
+
import { Strapi } from '../../';
|
|
3
|
+
|
|
4
|
+
type ID = number | string;
|
|
5
|
+
|
|
6
|
+
type EntityServiceAction =
|
|
7
|
+
| 'findMany'
|
|
8
|
+
| 'findPage'
|
|
9
|
+
| 'findWithRelationCounts'
|
|
10
|
+
| 'findOne'
|
|
11
|
+
| 'count'
|
|
12
|
+
| 'create'
|
|
13
|
+
| 'update'
|
|
14
|
+
| 'delete';
|
|
15
|
+
|
|
16
|
+
type PaginationInfo = {
|
|
17
|
+
page: number;
|
|
18
|
+
pageSize: number;
|
|
19
|
+
pageCount: number;
|
|
20
|
+
total: number;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
type Params<T> = {
|
|
24
|
+
fields?: (keyof T)[];
|
|
25
|
+
filters?: any;
|
|
26
|
+
_q?: string;
|
|
27
|
+
populate?: any;
|
|
28
|
+
sort?: any;
|
|
29
|
+
start?: number;
|
|
30
|
+
limit?: number;
|
|
31
|
+
page?: number;
|
|
32
|
+
pageSize?: number;
|
|
33
|
+
publicationState?: string;
|
|
34
|
+
data?: any;
|
|
35
|
+
files?: any;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
interface EntityService {
|
|
39
|
+
uploadFiles<K extends keyof AllTypes, T extends AllTypes[K]>(uid: K, entity, files);
|
|
40
|
+
wrapParams<K extends keyof AllTypes, T extends AllTypes[K]>(
|
|
41
|
+
params: Params<T>,
|
|
42
|
+
{ uid: K, action: EntityServiceAction }
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
findMany<K extends keyof AllTypes, T extends AllTypes[K]>(
|
|
46
|
+
uid: K,
|
|
47
|
+
params: Params<T>
|
|
48
|
+
): Promise<T[]>;
|
|
49
|
+
findPage<K extends keyof AllTypes, T extends AllTypes[K]>(
|
|
50
|
+
uid: K,
|
|
51
|
+
params: Params<T>
|
|
52
|
+
): Promise<{
|
|
53
|
+
results: T[];
|
|
54
|
+
pagination: PaginationInfo;
|
|
55
|
+
}>;
|
|
56
|
+
|
|
57
|
+
findWithRelationCounts<K extends keyof AllTypes, T extends AllTypes[K]>(
|
|
58
|
+
uid: K,
|
|
59
|
+
params: Params<T>
|
|
60
|
+
): Promise<{
|
|
61
|
+
results: T[];
|
|
62
|
+
pagination: PaginationInfo;
|
|
63
|
+
}>;
|
|
64
|
+
|
|
65
|
+
findOne<K extends keyof AllTypes, T extends AllTypes[K]>(
|
|
66
|
+
uid: K,
|
|
67
|
+
entityId: ID,
|
|
68
|
+
params: Params<T>
|
|
69
|
+
): Promise<T>;
|
|
70
|
+
|
|
71
|
+
count<K extends keyof AllTypes, T extends AllTypes[K]>(uid: K, params: Params<T>): Promise<any>;
|
|
72
|
+
create<K extends keyof AllTypes, T extends AllTypes[K]>(uid: K, params: Params<T>): Promise<any>;
|
|
73
|
+
update<K extends keyof AllTypes, T extends AllTypes[K]>(
|
|
74
|
+
uid: K,
|
|
75
|
+
entityId: ID,
|
|
76
|
+
params: Params<T>
|
|
77
|
+
): Promise<any>;
|
|
78
|
+
delete<K extends keyof AllTypes, T extends AllTypes[K]>(
|
|
79
|
+
uid: K,
|
|
80
|
+
entityId: ID,
|
|
81
|
+
params: Params<T>
|
|
82
|
+
): Promise<any>;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export default function(opts: {
|
|
86
|
+
strapi: Strapi;
|
|
87
|
+
db: Database;
|
|
88
|
+
// TODO: define types
|
|
89
|
+
eventHub: any;
|
|
90
|
+
entityValidator: any;
|
|
91
|
+
}): EntityService;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const delegate = require('delegates');
|
|
4
|
+
const { pipe } = require('lodash/fp');
|
|
5
|
+
|
|
4
6
|
const {
|
|
5
7
|
sanitizeEntity,
|
|
6
8
|
webhook: webhookUtils,
|
|
7
9
|
contentTypes: contentTypesUtils,
|
|
8
|
-
relations: relationsUtils,
|
|
9
10
|
} = require('@strapi/utils');
|
|
10
11
|
const uploadFiles = require('../utils/upload-files');
|
|
11
12
|
|
|
@@ -15,9 +16,12 @@ const {
|
|
|
15
16
|
updateComponents,
|
|
16
17
|
deleteComponents,
|
|
17
18
|
} = require('./components');
|
|
18
|
-
const {
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
const {
|
|
20
|
+
transformCommonParams,
|
|
21
|
+
transformPaginationParams,
|
|
22
|
+
transformParamsToQuery,
|
|
23
|
+
pickSelectionParams,
|
|
24
|
+
} = require('./params');
|
|
21
25
|
|
|
22
26
|
// TODO: those should be strapi events used by the webhooks not the other way arround
|
|
23
27
|
const { ENTRY_CREATE, ENTRY_UPDATE, ENTRY_DELETE } = webhookUtils.webhookEvents;
|
|
@@ -45,10 +49,13 @@ module.exports = ctx => {
|
|
|
45
49
|
return service;
|
|
46
50
|
};
|
|
47
51
|
|
|
52
|
+
/**
|
|
53
|
+
* @type {import('.').default}
|
|
54
|
+
*/
|
|
48
55
|
const createDefaultImplementation = ({ strapi, db, eventHub, entityValidator }) => ({
|
|
49
56
|
uploadFiles,
|
|
50
57
|
|
|
51
|
-
async
|
|
58
|
+
async wrapParams(options = {}) {
|
|
52
59
|
return options;
|
|
53
60
|
},
|
|
54
61
|
|
|
@@ -61,13 +68,12 @@ const createDefaultImplementation = ({ strapi, db, eventHub, entityValidator })
|
|
|
61
68
|
});
|
|
62
69
|
},
|
|
63
70
|
|
|
64
|
-
|
|
65
|
-
async find(uid, opts) {
|
|
71
|
+
async findMany(uid, opts) {
|
|
66
72
|
const { kind } = strapi.getModel(uid);
|
|
67
73
|
|
|
68
|
-
const
|
|
74
|
+
const wrappedParams = await this.wrapParams(opts, { uid, action: 'findMany' });
|
|
69
75
|
|
|
70
|
-
const query = transformParamsToQuery(uid,
|
|
76
|
+
const query = transformParamsToQuery(uid, wrappedParams);
|
|
71
77
|
|
|
72
78
|
if (kind === 'singleType') {
|
|
73
79
|
return db.query(uid).findOne(query);
|
|
@@ -77,42 +83,20 @@ const createDefaultImplementation = ({ strapi, db, eventHub, entityValidator })
|
|
|
77
83
|
},
|
|
78
84
|
|
|
79
85
|
async findPage(uid, opts) {
|
|
80
|
-
const
|
|
86
|
+
const wrappedParams = await this.wrapParams(opts, { uid, action: 'findPage' });
|
|
81
87
|
|
|
82
|
-
const query = transformParamsToQuery(uid,
|
|
88
|
+
const query = transformParamsToQuery(uid, wrappedParams);
|
|
83
89
|
|
|
84
90
|
return db.query(uid).findPage(query);
|
|
85
91
|
},
|
|
86
92
|
|
|
87
93
|
// TODO: streamline the logic based on the populate option
|
|
88
94
|
async findWithRelationCounts(uid, opts) {
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
const { params } = await this.wrapOptions(opts, { uid, action: 'findWithRelationCounts' });
|
|
95
|
+
const wrappedParams = await this.wrapParams(opts, { uid, action: 'findWithRelationCounts' });
|
|
92
96
|
|
|
93
|
-
const query = transformParamsToQuery(uid,
|
|
94
|
-
|
|
95
|
-
const { attributes } = model;
|
|
96
|
-
|
|
97
|
-
const populate = (query.populate || []).reduce((populate, attributeName) => {
|
|
98
|
-
const attribute = attributes[attributeName];
|
|
99
|
-
|
|
100
|
-
if (
|
|
101
|
-
MANY_RELATIONS.includes(attribute.relation) &&
|
|
102
|
-
contentTypesUtils.isVisibleAttribute(model, attributeName)
|
|
103
|
-
) {
|
|
104
|
-
populate[attributeName] = { count: true };
|
|
105
|
-
} else {
|
|
106
|
-
populate[attributeName] = true;
|
|
107
|
-
}
|
|
97
|
+
const query = transformParamsToQuery(uid, wrappedParams);
|
|
108
98
|
|
|
109
|
-
|
|
110
|
-
}, {});
|
|
111
|
-
|
|
112
|
-
const { results, pagination } = await db.query(uid).findPage({
|
|
113
|
-
...query,
|
|
114
|
-
populate,
|
|
115
|
-
});
|
|
99
|
+
const { results, pagination } = await db.query(uid).findPage(query);
|
|
116
100
|
|
|
117
101
|
return {
|
|
118
102
|
results,
|
|
@@ -121,23 +105,24 @@ const createDefaultImplementation = ({ strapi, db, eventHub, entityValidator })
|
|
|
121
105
|
},
|
|
122
106
|
|
|
123
107
|
async findOne(uid, entityId, opts) {
|
|
124
|
-
const
|
|
108
|
+
const wrappedParams = await this.wrapParams(opts, { uid, action: 'findOne' });
|
|
125
109
|
|
|
126
|
-
const query = transformParamsToQuery(uid, pickSelectionParams(
|
|
110
|
+
const query = transformParamsToQuery(uid, pickSelectionParams(wrappedParams));
|
|
127
111
|
|
|
128
112
|
return db.query(uid).findOne({ ...query, where: { id: entityId } });
|
|
129
113
|
},
|
|
130
114
|
|
|
131
115
|
async count(uid, opts) {
|
|
132
|
-
const
|
|
116
|
+
const wrappedParams = await this.wrapParams(opts, { uid, action: 'count' });
|
|
133
117
|
|
|
134
|
-
const query = transformParamsToQuery(uid,
|
|
118
|
+
const query = transformParamsToQuery(uid, wrappedParams);
|
|
135
119
|
|
|
136
120
|
return db.query(uid).count(query);
|
|
137
121
|
},
|
|
138
122
|
|
|
139
123
|
async create(uid, opts) {
|
|
140
|
-
const
|
|
124
|
+
const wrappedParams = await this.wrapParams(opts, { uid, action: 'create' });
|
|
125
|
+
const { data, files } = wrappedParams;
|
|
141
126
|
|
|
142
127
|
const model = strapi.getModel(uid);
|
|
143
128
|
|
|
@@ -145,7 +130,7 @@ const createDefaultImplementation = ({ strapi, db, eventHub, entityValidator })
|
|
|
145
130
|
const validData = await entityValidator.validateEntityCreation(model, data, { isDraft });
|
|
146
131
|
|
|
147
132
|
// select / populate
|
|
148
|
-
const query = transformParamsToQuery(uid, pickSelectionParams(
|
|
133
|
+
const query = transformParamsToQuery(uid, pickSelectionParams(wrappedParams));
|
|
149
134
|
|
|
150
135
|
// TODO: wrap into transaction
|
|
151
136
|
const componentData = await createComponents(uid, validData);
|
|
@@ -159,7 +144,7 @@ const createDefaultImplementation = ({ strapi, db, eventHub, entityValidator })
|
|
|
159
144
|
// FIXME: upload in components
|
|
160
145
|
if (files && Object.keys(files).length > 0) {
|
|
161
146
|
await this.uploadFiles(uid, entity, files);
|
|
162
|
-
entity = await this.findOne(uid, entity.id,
|
|
147
|
+
entity = await this.findOne(uid, entity.id, wrappedParams);
|
|
163
148
|
}
|
|
164
149
|
|
|
165
150
|
this.emitEvent(uid, ENTRY_CREATE, entity);
|
|
@@ -168,7 +153,8 @@ const createDefaultImplementation = ({ strapi, db, eventHub, entityValidator })
|
|
|
168
153
|
},
|
|
169
154
|
|
|
170
155
|
async update(uid, entityId, opts) {
|
|
171
|
-
const
|
|
156
|
+
const wrappedParams = await this.wrapParams(opts, { uid, action: 'update' });
|
|
157
|
+
const { data, files } = wrappedParams;
|
|
172
158
|
|
|
173
159
|
const model = strapi.getModel(uid);
|
|
174
160
|
|
|
@@ -184,7 +170,7 @@ const createDefaultImplementation = ({ strapi, db, eventHub, entityValidator })
|
|
|
184
170
|
isDraft,
|
|
185
171
|
});
|
|
186
172
|
|
|
187
|
-
const query = transformParamsToQuery(uid, pickSelectionParams(
|
|
173
|
+
const query = transformParamsToQuery(uid, pickSelectionParams(wrappedParams));
|
|
188
174
|
|
|
189
175
|
// TODO: wrap in transaction
|
|
190
176
|
const componentData = await updateComponents(uid, entityToUpdate, validData);
|
|
@@ -199,7 +185,7 @@ const createDefaultImplementation = ({ strapi, db, eventHub, entityValidator })
|
|
|
199
185
|
// FIXME: upload in components
|
|
200
186
|
if (files && Object.keys(files).length > 0) {
|
|
201
187
|
await this.uploadFiles(uid, entity, files);
|
|
202
|
-
entity = await this.findOne(uid, entity.id,
|
|
188
|
+
entity = await this.findOne(uid, entity.id, wrappedParams);
|
|
203
189
|
}
|
|
204
190
|
|
|
205
191
|
this.emitEvent(uid, ENTRY_UPDATE, entity);
|
|
@@ -208,10 +194,10 @@ const createDefaultImplementation = ({ strapi, db, eventHub, entityValidator })
|
|
|
208
194
|
},
|
|
209
195
|
|
|
210
196
|
async delete(uid, entityId, opts) {
|
|
211
|
-
const
|
|
197
|
+
const wrappedParams = await this.wrapParams(opts, { uid, action: 'delete' });
|
|
212
198
|
|
|
213
199
|
// select / populate
|
|
214
|
-
const query = transformParamsToQuery(uid, pickSelectionParams(
|
|
200
|
+
const query = transformParamsToQuery(uid, pickSelectionParams(wrappedParams));
|
|
215
201
|
|
|
216
202
|
const entityToDelete = await db.query(uid).findOne({
|
|
217
203
|
...query,
|
|
@@ -232,11 +218,27 @@ const createDefaultImplementation = ({ strapi, db, eventHub, entityValidator })
|
|
|
232
218
|
|
|
233
219
|
// FIXME: used only for the CM to be removed
|
|
234
220
|
async deleteMany(uid, opts) {
|
|
235
|
-
const
|
|
221
|
+
const wrappedParams = await this.wrapParams(opts, { uid, action: 'delete' });
|
|
236
222
|
|
|
237
223
|
// select / populate
|
|
238
|
-
const query = transformParamsToQuery(uid,
|
|
224
|
+
const query = transformParamsToQuery(uid, wrappedParams);
|
|
239
225
|
|
|
240
226
|
return db.query(uid).deleteMany(query);
|
|
241
227
|
},
|
|
228
|
+
|
|
229
|
+
load(uid, entity, field, params) {
|
|
230
|
+
const { attributes } = strapi.getModel(uid);
|
|
231
|
+
|
|
232
|
+
const attribute = attributes[field];
|
|
233
|
+
|
|
234
|
+
const loadParams =
|
|
235
|
+
attribute.type === 'relation'
|
|
236
|
+
? transformParamsToQuery(attribute.target, params)
|
|
237
|
+
: pipe(
|
|
238
|
+
transformCommonParams,
|
|
239
|
+
transformPaginationParams
|
|
240
|
+
)(params);
|
|
241
|
+
|
|
242
|
+
return db.query(uid).load(entity, field, loadParams);
|
|
243
|
+
},
|
|
242
244
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const { pick } = require('lodash/fp');
|
|
3
|
+
const { pick, pipe, isNil } = require('lodash/fp');
|
|
4
4
|
|
|
5
5
|
const {
|
|
6
6
|
convertSortQueryParams,
|
|
@@ -15,45 +15,26 @@ const { contentTypes: contentTypesUtils } = require('@strapi/utils');
|
|
|
15
15
|
|
|
16
16
|
const { PUBLISHED_AT_ATTRIBUTE } = contentTypesUtils.constants;
|
|
17
17
|
|
|
18
|
-
// TODO:
|
|
19
|
-
const
|
|
20
|
-
const model = strapi.getModel(uid);
|
|
21
|
-
|
|
18
|
+
// TODO: to remove once the front is migrated
|
|
19
|
+
const convertOldQuery = params => {
|
|
22
20
|
const query = {};
|
|
23
21
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
fields,
|
|
32
|
-
populate,
|
|
33
|
-
publicationState,
|
|
34
|
-
_q,
|
|
35
|
-
_where,
|
|
36
|
-
...rest
|
|
37
|
-
} = params;
|
|
38
|
-
|
|
39
|
-
if (_q) {
|
|
40
|
-
query._q = _q;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if (page) {
|
|
44
|
-
query.page = Number(page);
|
|
45
|
-
}
|
|
22
|
+
Object.keys(params).forEach(key => {
|
|
23
|
+
if (key.startsWith('_')) {
|
|
24
|
+
query[key.slice(1)] = params[key];
|
|
25
|
+
} else {
|
|
26
|
+
query[key] = params[key];
|
|
27
|
+
}
|
|
28
|
+
});
|
|
46
29
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
30
|
+
return query;
|
|
31
|
+
};
|
|
50
32
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
33
|
+
const transformCommonParams = (params = {}) => {
|
|
34
|
+
const { _q, sort, filters, _where, fields, populate, ...query } = params;
|
|
54
35
|
|
|
55
|
-
if (
|
|
56
|
-
query.
|
|
36
|
+
if (_q) {
|
|
37
|
+
query._q = _q;
|
|
57
38
|
}
|
|
58
39
|
|
|
59
40
|
if (sort) {
|
|
@@ -78,8 +59,50 @@ const transformParamsToQuery = (uid, params = {}) => {
|
|
|
78
59
|
query.populate = convertPopulateQueryParams(populate);
|
|
79
60
|
}
|
|
80
61
|
|
|
81
|
-
|
|
82
|
-
|
|
62
|
+
return { ...convertOldQuery(query), ...query };
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const transformPaginationParams = (params = {}) => {
|
|
66
|
+
const { page, pageSize, start, limit, ...query } = params;
|
|
67
|
+
|
|
68
|
+
const isPagePagination = !isNil(page) || !isNil(pageSize);
|
|
69
|
+
const isOffsetPagination = !isNil(start) || !isNil(limit);
|
|
70
|
+
|
|
71
|
+
if (isPagePagination && isOffsetPagination) {
|
|
72
|
+
throw new Error(
|
|
73
|
+
'Invalid pagination attributes. You cannot use page and offset pagination in the same query'
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (page) {
|
|
78
|
+
query.page = Number(page);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (pageSize) {
|
|
82
|
+
query.pageSize = Number(pageSize);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (start) {
|
|
86
|
+
query.offset = convertStartQueryParams(start);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (limit) {
|
|
90
|
+
query.limit = convertLimitQueryParams(limit);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return { ...convertOldQuery(query), ...query };
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const transformPublicationStateParams = uid => (params = {}) => {
|
|
97
|
+
const contentType = strapi.getModel(uid);
|
|
98
|
+
|
|
99
|
+
if (!contentType) {
|
|
100
|
+
return params;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const { publicationState, ...query } = params;
|
|
104
|
+
|
|
105
|
+
if (publicationState && contentTypesUtils.hasDraftAndPublish(contentType)) {
|
|
83
106
|
const { publicationState = 'live' } = params;
|
|
84
107
|
|
|
85
108
|
const liveClause = {
|
|
@@ -97,32 +120,26 @@ const transformParamsToQuery = (uid, params = {}) => {
|
|
|
97
120
|
}
|
|
98
121
|
}
|
|
99
122
|
|
|
100
|
-
|
|
101
|
-
...convertOldQuery(rest),
|
|
102
|
-
...query,
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
return finalQuery;
|
|
123
|
+
return { ...convertOldQuery(query), ...query };
|
|
106
124
|
};
|
|
107
125
|
|
|
108
|
-
|
|
109
|
-
const convertOldQuery = params => {
|
|
110
|
-
const obj = {};
|
|
111
|
-
|
|
112
|
-
Object.keys(params).forEach(key => {
|
|
113
|
-
if (key.startsWith('_')) {
|
|
114
|
-
obj[key.slice(1)] = params[key];
|
|
115
|
-
} else {
|
|
116
|
-
obj[key] = params[key];
|
|
117
|
-
}
|
|
118
|
-
});
|
|
126
|
+
const pickSelectionParams = pick(['fields', 'populate']);
|
|
119
127
|
|
|
120
|
-
|
|
128
|
+
const transformParamsToQuery = (uid, params) => {
|
|
129
|
+
return pipe(
|
|
130
|
+
// _q, _where, filters, etc...
|
|
131
|
+
transformCommonParams,
|
|
132
|
+
// page, pageSize, start, limit
|
|
133
|
+
transformPaginationParams,
|
|
134
|
+
// publicationState
|
|
135
|
+
transformPublicationStateParams(uid)
|
|
136
|
+
)(params);
|
|
121
137
|
};
|
|
122
138
|
|
|
123
|
-
const pickSelectionParams = pick(['fields', 'populate']);
|
|
124
|
-
|
|
125
139
|
module.exports = {
|
|
140
|
+
transformCommonParams,
|
|
141
|
+
transformPublicationStateParams,
|
|
142
|
+
transformPaginationParams,
|
|
126
143
|
transformParamsToQuery,
|
|
127
144
|
pickSelectionParams,
|
|
128
145
|
};
|
package/lib/services/fs.js
CHANGED
|
@@ -88,7 +88,7 @@ const hashProject = strapi =>
|
|
|
88
88
|
|
|
89
89
|
const hashDep = strapi => {
|
|
90
90
|
const depStr = JSON.stringify(strapi.config.info.dependencies);
|
|
91
|
-
const readmePath = path.join(strapi.
|
|
91
|
+
const readmePath = path.join(strapi.dirs.root, 'README.md');
|
|
92
92
|
|
|
93
93
|
try {
|
|
94
94
|
if (fs.existsSync(readmePath)) {
|
|
@@ -11,11 +11,22 @@ const resolvePolicies = route => {
|
|
|
11
11
|
const { pluginName, apiName } = route.info || {};
|
|
12
12
|
const policiesConfig = getPoliciesConfig(route);
|
|
13
13
|
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
});
|
|
14
|
+
const policiesMiddleware = async (ctx, next) => {
|
|
15
|
+
const context = policy.createPolicyContext('koa', ctx);
|
|
17
16
|
|
|
18
|
-
|
|
17
|
+
for (const policyName of policiesConfig) {
|
|
18
|
+
const resolvedPolicy = await policy.get(policyName, { pluginName, apiName });
|
|
19
|
+
const result = await resolvedPolicy({ ctx: context, strapi });
|
|
20
|
+
|
|
21
|
+
if (![true, undefined].includes(result)) {
|
|
22
|
+
throw new Error('Policies failed.');
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
await next();
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
return [policiesMiddleware, bodyPolicy];
|
|
19
30
|
};
|
|
20
31
|
|
|
21
32
|
module.exports = {
|
package/lib/utils/ee.js
CHANGED
|
@@ -78,7 +78,7 @@ module.exports = ({ dir, logger = noLog }) => {
|
|
|
78
78
|
};
|
|
79
79
|
|
|
80
80
|
Object.defineProperty(module.exports, 'licenseInfo', {
|
|
81
|
-
get
|
|
81
|
+
get() {
|
|
82
82
|
mustHaveKey('licenseInfo');
|
|
83
83
|
return internals.licenseInfo;
|
|
84
84
|
},
|
|
@@ -87,7 +87,7 @@ Object.defineProperty(module.exports, 'licenseInfo', {
|
|
|
87
87
|
});
|
|
88
88
|
|
|
89
89
|
Object.defineProperty(module.exports, 'isEE', {
|
|
90
|
-
get
|
|
90
|
+
get() {
|
|
91
91
|
mustHaveKey('isEE');
|
|
92
92
|
return internals.isEE;
|
|
93
93
|
},
|
|
@@ -96,7 +96,7 @@ Object.defineProperty(module.exports, 'isEE', {
|
|
|
96
96
|
});
|
|
97
97
|
|
|
98
98
|
Object.defineProperty(module.exports, 'features', {
|
|
99
|
-
get
|
|
99
|
+
get() {
|
|
100
100
|
mustHaveKey('licenseInfo');
|
|
101
101
|
|
|
102
102
|
const { type: licenseType } = module.exports.licenseInfo;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { join } = require('path');
|
|
4
|
+
|
|
5
|
+
const getDirs = root => ({
|
|
6
|
+
root,
|
|
7
|
+
src: join(root, 'src'),
|
|
8
|
+
api: join(root, 'src', 'api'),
|
|
9
|
+
components: join(root, 'src', 'components'),
|
|
10
|
+
extensions: join(root, 'src', 'extensions'),
|
|
11
|
+
policies: join(root, 'src', 'policies'),
|
|
12
|
+
config: join(root, 'config'),
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
module.exports = getDirs;
|