@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
|
@@ -24,13 +24,28 @@ const transformResponse = (resource, meta = {}, { contentType } = {}) => {
|
|
|
24
24
|
};
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
-
const
|
|
27
|
+
const transformComponent = (data, component) => {
|
|
28
|
+
if (Array.isArray(data)) {
|
|
29
|
+
return data.map(datum => transformComponent(datum, component));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const res = transformEntry(data, component);
|
|
33
|
+
|
|
34
|
+
if (isNil(res)) {
|
|
35
|
+
return res;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const { id, attributes } = res;
|
|
39
|
+
return { id, ...attributes };
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const transformEntry = (entry, type) => {
|
|
28
43
|
if (isNil(entry)) {
|
|
29
44
|
return entry;
|
|
30
45
|
}
|
|
31
46
|
|
|
32
47
|
if (Array.isArray(entry)) {
|
|
33
|
-
return entry.map(singleEntry => transformEntry(singleEntry,
|
|
48
|
+
return entry.map(singleEntry => transformEntry(singleEntry, type));
|
|
34
49
|
}
|
|
35
50
|
|
|
36
51
|
if (!isPlainObject(entry)) {
|
|
@@ -43,12 +58,22 @@ const transformEntry = (entry, contentType) => {
|
|
|
43
58
|
|
|
44
59
|
for (const key in properties) {
|
|
45
60
|
const property = properties[key];
|
|
46
|
-
const attribute =
|
|
61
|
+
const attribute = type && type.attributes[key];
|
|
47
62
|
|
|
48
63
|
if (attribute && attribute.type === 'relation') {
|
|
49
64
|
const data = transformEntry(property, strapi.contentType(attribute.target));
|
|
50
65
|
|
|
51
66
|
attributeValues[key] = { data };
|
|
67
|
+
} else if (attribute && attribute.type === 'component') {
|
|
68
|
+
attributeValues[key] = transformComponent(property, strapi.components[attribute.component]);
|
|
69
|
+
} else if (attribute && attribute.type === 'dynamiczone') {
|
|
70
|
+
if (isNil(property)) {
|
|
71
|
+
attributeValues[key] = property;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
attributeValues[key] = property.map(subProperty => {
|
|
75
|
+
return transformComponent(subProperty, strapi.components[subProperty.__component]);
|
|
76
|
+
});
|
|
52
77
|
} else if (attribute && attribute.type === 'media') {
|
|
53
78
|
const data = transformEntry(property, strapi.contentType('plugin::upload.file'));
|
|
54
79
|
|
|
@@ -28,19 +28,18 @@ const createCollectionTypeService = ({ model, strapi, utils }) => {
|
|
|
28
28
|
const { sanitizeInput, getFetchParams } = utils;
|
|
29
29
|
|
|
30
30
|
return {
|
|
31
|
-
async find(
|
|
32
|
-
const
|
|
31
|
+
async find(params = {}) {
|
|
32
|
+
const fetchParams = getFetchParams(params);
|
|
33
33
|
|
|
34
|
-
const paginationInfo = getPaginationInfo(
|
|
34
|
+
const paginationInfo = getPaginationInfo(fetchParams);
|
|
35
35
|
|
|
36
|
-
const results = await strapi.entityService.
|
|
37
|
-
|
|
36
|
+
const results = await strapi.entityService.findMany(uid, {
|
|
37
|
+
...fetchParams,
|
|
38
|
+
...convertPagedToStartLimit(paginationInfo),
|
|
38
39
|
});
|
|
39
40
|
|
|
40
|
-
if (shouldCount(
|
|
41
|
-
const count = await strapi.entityService.count(uid, {
|
|
42
|
-
params: { ...params, ...paginationInfo },
|
|
43
|
-
});
|
|
41
|
+
if (shouldCount(fetchParams)) {
|
|
42
|
+
const count = await strapi.entityService.count(uid, { ...fetchParams, ...paginationInfo });
|
|
44
43
|
|
|
45
44
|
return {
|
|
46
45
|
results,
|
|
@@ -54,30 +53,30 @@ const createCollectionTypeService = ({ model, strapi, utils }) => {
|
|
|
54
53
|
};
|
|
55
54
|
},
|
|
56
55
|
|
|
57
|
-
findOne(entityId,
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
return strapi.entityService.findOne(uid, entityId, { params });
|
|
56
|
+
findOne(entityId, params = {}) {
|
|
57
|
+
return strapi.entityService.findOne(uid, entityId, getFetchParams(params));
|
|
61
58
|
},
|
|
62
59
|
|
|
63
|
-
create(
|
|
60
|
+
create(params = {}) {
|
|
61
|
+
const { data } = params;
|
|
64
62
|
const sanitizedData = sanitizeInput(data);
|
|
65
63
|
|
|
66
64
|
if (hasDraftAndPublish(model)) {
|
|
67
65
|
setPublishedAt(sanitizedData);
|
|
68
66
|
}
|
|
69
67
|
|
|
70
|
-
return strapi.entityService.create(uid, { params, data: sanitizedData
|
|
68
|
+
return strapi.entityService.create(uid, { ...params, data: sanitizedData });
|
|
71
69
|
},
|
|
72
70
|
|
|
73
|
-
update(entityId,
|
|
71
|
+
update(entityId, params = {}) {
|
|
72
|
+
const { data } = params;
|
|
74
73
|
const sanitizedData = sanitizeInput(data);
|
|
75
74
|
|
|
76
|
-
return strapi.entityService.update(uid, entityId, { params, data: sanitizedData
|
|
75
|
+
return strapi.entityService.update(uid, entityId, { ...params, data: sanitizedData });
|
|
77
76
|
},
|
|
78
77
|
|
|
79
|
-
delete(entityId,
|
|
80
|
-
return strapi.entityService.delete(uid, entityId,
|
|
78
|
+
delete(entityId, params = {}) {
|
|
79
|
+
return strapi.entityService.delete(uid, entityId, params);
|
|
81
80
|
},
|
|
82
81
|
};
|
|
83
82
|
};
|
|
@@ -13,9 +13,8 @@ const createSingleTypeService = ({ model, strapi, utils }) => {
|
|
|
13
13
|
*
|
|
14
14
|
* @return {Promise}
|
|
15
15
|
*/
|
|
16
|
-
find(
|
|
17
|
-
|
|
18
|
-
return strapi.entityService.find(uid, { params: normalizedParams });
|
|
16
|
+
find(params = {}) {
|
|
17
|
+
return strapi.entityService.findMany(uid, getFetchParams(params));
|
|
19
18
|
},
|
|
20
19
|
|
|
21
20
|
/**
|
|
@@ -23,9 +22,10 @@ const createSingleTypeService = ({ model, strapi, utils }) => {
|
|
|
23
22
|
*
|
|
24
23
|
* @return {Promise}
|
|
25
24
|
*/
|
|
26
|
-
async createOrUpdate(
|
|
27
|
-
const entity = await this.find(
|
|
25
|
+
async createOrUpdate(params = {}) {
|
|
26
|
+
const entity = await this.find(params);
|
|
28
27
|
|
|
28
|
+
const { data } = params;
|
|
29
29
|
const sanitizedData = sanitizeInput(data);
|
|
30
30
|
|
|
31
31
|
if (!entity) {
|
|
@@ -34,14 +34,10 @@ const createSingleTypeService = ({ model, strapi, utils }) => {
|
|
|
34
34
|
throw strapi.errors.badRequest('singleType.alreadyExists');
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
return strapi.entityService.create(uid, { params, data: sanitizedData
|
|
38
|
-
} else {
|
|
39
|
-
return strapi.entityService.update(uid, entity.id, {
|
|
40
|
-
params,
|
|
41
|
-
data: sanitizedData,
|
|
42
|
-
files,
|
|
43
|
-
});
|
|
37
|
+
return strapi.entityService.create(uid, { ...params, data: sanitizedData });
|
|
44
38
|
}
|
|
39
|
+
|
|
40
|
+
return strapi.entityService.update(uid, entity.id, { ...params, data: sanitizedData });
|
|
45
41
|
},
|
|
46
42
|
|
|
47
43
|
/**
|
|
@@ -49,8 +45,8 @@ const createSingleTypeService = ({ model, strapi, utils }) => {
|
|
|
49
45
|
*
|
|
50
46
|
* @return {Promise}
|
|
51
47
|
*/
|
|
52
|
-
async delete(
|
|
53
|
-
const entity = await this.find(
|
|
48
|
+
async delete(params = {}) {
|
|
49
|
+
const entity = await this.find(params);
|
|
54
50
|
|
|
55
51
|
if (!entity) return;
|
|
56
52
|
|
package/lib/index.d.ts
CHANGED
|
@@ -1,40 +1,14 @@
|
|
|
1
1
|
import { Database } from '@strapi/database';
|
|
2
|
-
import {
|
|
2
|
+
import { EntityService } from './services/entity-service';
|
|
3
|
+
import { Strapi as StrapiClass } from './Strapi';
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
interface Options<T> {
|
|
7
|
-
params: Params<T>;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
interface Params<T> {
|
|
11
|
-
fields: (keyof T)[];
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
interface EntityService {
|
|
15
|
-
uploadFiles<T extends keyof AllTypes>(uid: T);
|
|
16
|
-
wrapOptions<T extends keyof AllTypes>(uid: T);
|
|
17
|
-
|
|
18
|
-
find<T extends keyof AllTypes>(uid: T): Promise<AllTypes[T][]>;
|
|
19
|
-
findPage<T extends keyof AllTypes>(uid: T): Promise<any>;
|
|
20
|
-
findWithRelationCounts<T extends keyof AllTypes>(uid: T): Promise<any>;
|
|
21
|
-
findOne<T extends keyof AllTypes>(
|
|
22
|
-
uid: T,
|
|
23
|
-
id: ID,
|
|
24
|
-
opts: Options<AllTypes[T]>
|
|
25
|
-
): Promise<AllTypes[T]>;
|
|
26
|
-
|
|
27
|
-
count<T extends keyof AllTypes>(uid: T): Promise<any>;
|
|
28
|
-
create<T extends keyof AllTypes>(uid: T): Promise<any>;
|
|
29
|
-
update<T extends keyof AllTypes>(uid: T): Promise<any>;
|
|
30
|
-
delete<T extends keyof AllTypes>(uid: T): Promise<any>;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
interface StrapiInterface extends Strapi {
|
|
5
|
+
interface StrapiInterface extends StrapiClass {
|
|
34
6
|
query: Database['query'];
|
|
35
7
|
entityService: EntityService;
|
|
36
8
|
}
|
|
37
9
|
|
|
10
|
+
export type Strapi = StrapiInterface;
|
|
11
|
+
|
|
38
12
|
declare global {
|
|
39
13
|
interface AllTypes {}
|
|
40
14
|
}
|
|
@@ -44,5 +18,9 @@ declare global {
|
|
|
44
18
|
strapi: StrapiInterface;
|
|
45
19
|
}
|
|
46
20
|
|
|
21
|
+
export type Strapi = StrapiInterface;
|
|
22
|
+
|
|
47
23
|
const strapi: StrapiInterface;
|
|
48
24
|
}
|
|
25
|
+
|
|
26
|
+
export default function(opts): Strapi;
|
|
@@ -19,11 +19,10 @@ module.exports = strapi => {
|
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
21
|
initialize() {
|
|
22
|
-
const { dir } = strapi;
|
|
23
22
|
const { maxAge, path: faviconPath } = strapi.config.middleware.settings.favicon;
|
|
24
23
|
|
|
25
24
|
strapi.server.use(
|
|
26
|
-
favicon(resolve(
|
|
25
|
+
favicon(resolve(strapi.dirs.root, faviconPath), {
|
|
27
26
|
maxAge,
|
|
28
27
|
})
|
|
29
28
|
);
|
package/lib/middlewares/index.js
CHANGED
|
@@ -25,7 +25,7 @@ module.exports = strapi => {
|
|
|
25
25
|
|
|
26
26
|
async initialize() {
|
|
27
27
|
const { defaultIndex, maxAge, path: publicPath } = strapi.config.middleware.settings.public;
|
|
28
|
-
const staticDir = path.resolve(strapi.
|
|
28
|
+
const staticDir = path.resolve(strapi.dirs.root, publicPath || strapi.config.paths.static);
|
|
29
29
|
|
|
30
30
|
if (defaultIndex === true) {
|
|
31
31
|
const index = fs.readFileSync(path.join(__dirname, 'index.html'), 'utf8');
|
|
@@ -98,7 +98,7 @@ module.exports = strapi => {
|
|
|
98
98
|
|
|
99
99
|
if (!strapi.config.serveAdminPanel) return;
|
|
100
100
|
|
|
101
|
-
const buildDir = path.resolve(strapi.
|
|
101
|
+
const buildDir = path.resolve(strapi.dirs.root, 'build');
|
|
102
102
|
const serveAdmin = async (ctx, next) => {
|
|
103
103
|
await next();
|
|
104
104
|
|
|
@@ -8,7 +8,8 @@ module.exports = strapi => {
|
|
|
8
8
|
strapi.server.use(async (ctx, next) => {
|
|
9
9
|
await next();
|
|
10
10
|
|
|
11
|
-
const
|
|
11
|
+
const status = ctx.status;
|
|
12
|
+
const responseFn = strapi.config.get(`middleware.settings.responses.handlers.${status}`);
|
|
12
13
|
if (_.isFunction(responseFn)) {
|
|
13
14
|
await responseFn(ctx);
|
|
14
15
|
}
|
|
@@ -9,9 +9,11 @@ const createRouteScopeGenerator = namespace => route => {
|
|
|
9
9
|
if (typeof route.handler === 'string') {
|
|
10
10
|
const [controller, action] = route.handler.split('.');
|
|
11
11
|
|
|
12
|
-
_.defaultsDeep(route
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
_.defaultsDeep(route, {
|
|
13
|
+
config: {
|
|
14
|
+
auth: {
|
|
15
|
+
scope: `${prefix}${controller}.${toLower(action)}`,
|
|
16
|
+
},
|
|
15
17
|
},
|
|
16
18
|
});
|
|
17
19
|
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { hasDraftAndPublish } = require('@strapi/utils').contentTypes;
|
|
4
|
+
|
|
5
|
+
const enableDraftAndPublish = async ({ oldContentTypes, contentTypes }) => {
|
|
6
|
+
if (!oldContentTypes) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
// run the after content types migrations
|
|
10
|
+
|
|
11
|
+
for (const uid in contentTypes) {
|
|
12
|
+
if (!oldContentTypes[uid]) {
|
|
13
|
+
continue;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const oldContentType = oldContentTypes[uid];
|
|
17
|
+
const contentType = contentTypes[uid];
|
|
18
|
+
|
|
19
|
+
// if d&p was enabled set publishedAt to eq createdAt
|
|
20
|
+
if (!hasDraftAndPublish(oldContentType) && hasDraftAndPublish(contentType)) {
|
|
21
|
+
const qb = strapi.db.queryBuilder(uid);
|
|
22
|
+
await qb
|
|
23
|
+
.update({ publishedAt: qb.ref('createdAt') })
|
|
24
|
+
.where({ publishedAt: null })
|
|
25
|
+
.execute();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const disableDraftAndPublish = async ({ oldContentTypes, contentTypes }) => {
|
|
31
|
+
if (!oldContentTypes) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
for (const uid in contentTypes) {
|
|
36
|
+
if (!oldContentTypes[uid]) {
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const oldContentType = oldContentTypes[uid];
|
|
41
|
+
const contentType = contentTypes[uid];
|
|
42
|
+
|
|
43
|
+
// if d&p was disabled remove unpublish content before sync
|
|
44
|
+
if (hasDraftAndPublish(oldContentType) && !hasDraftAndPublish(contentType)) {
|
|
45
|
+
await strapi.db
|
|
46
|
+
.queryBuilder(uid)
|
|
47
|
+
.delete()
|
|
48
|
+
.where({ publishedAt: null })
|
|
49
|
+
.execute();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
module.exports = {
|
|
55
|
+
enable: enableDraftAndPublish,
|
|
56
|
+
disable: disableDraftAndPublish,
|
|
57
|
+
};
|
|
@@ -69,7 +69,7 @@ const createAuthentication = () => {
|
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
return ctx.unauthorized('Missing credentials');
|
|
72
|
+
return ctx.unauthorized('Missing or invalid credentials');
|
|
73
73
|
},
|
|
74
74
|
async verify(auth, config = {}) {
|
|
75
75
|
if (config === false) {
|
|
@@ -81,7 +81,7 @@ const createAuthentication = () => {
|
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
if (typeof auth.strategy.verify === 'function') {
|
|
84
|
-
return
|
|
84
|
+
return auth.strategy.verify(auth, config);
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
return;
|
|
@@ -22,21 +22,37 @@ const coreStoreModel = {
|
|
|
22
22
|
},
|
|
23
23
|
};
|
|
24
24
|
|
|
25
|
-
const createCoreStore = ({
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
25
|
+
const createCoreStore = ({ db }) => {
|
|
26
|
+
const mergeParams = (defaultParams, params) => {
|
|
27
|
+
return {
|
|
28
|
+
...defaultParams,
|
|
29
|
+
...params,
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const store = function(defaultParams = {}) {
|
|
34
|
+
return {
|
|
35
|
+
get: params => store.get(mergeParams(defaultParams, params)),
|
|
36
|
+
set: params => store.set(mergeParams(defaultParams, params)),
|
|
37
|
+
delete: params => store.delete(mergeParams(defaultParams, params)),
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
Object.assign(store, {
|
|
42
|
+
/**
|
|
43
|
+
* Get value from the core store
|
|
44
|
+
* @param {Object} params
|
|
45
|
+
* @returns {*}
|
|
46
|
+
*/
|
|
47
|
+
async get(params = {}) {
|
|
48
|
+
const { key, type = 'core', environment, name, tag } = params;
|
|
33
49
|
|
|
34
50
|
const prefix = `${type}${name ? `_${name}` : ''}`;
|
|
35
51
|
|
|
36
52
|
const where = {
|
|
37
53
|
key: `${prefix}_${key}`,
|
|
38
|
-
environment,
|
|
39
|
-
tag,
|
|
54
|
+
environment: environment || null,
|
|
55
|
+
tag: tag || null,
|
|
40
56
|
};
|
|
41
57
|
|
|
42
58
|
const data = await db.query('strapi::core-store').findOne({ where });
|
|
@@ -57,71 +73,70 @@ const createCoreStore = ({ environment: defaultEnv, db }) => {
|
|
|
57
73
|
return new Date(data.value);
|
|
58
74
|
}
|
|
59
75
|
} else if (data.type === 'number') {
|
|
60
|
-
return
|
|
76
|
+
return Number(data.value);
|
|
61
77
|
} else {
|
|
62
78
|
return null;
|
|
63
79
|
}
|
|
64
|
-
}
|
|
80
|
+
},
|
|
65
81
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
82
|
+
/**
|
|
83
|
+
* Set value in the core store
|
|
84
|
+
* @param {Object} params
|
|
85
|
+
* @returns {*}
|
|
86
|
+
*/
|
|
87
|
+
async set(params = {}) {
|
|
88
|
+
const { key, value, type, environment, name, tag } = params;
|
|
72
89
|
|
|
73
90
|
const prefix = `${type}${name ? `_${name}` : ''}`;
|
|
74
91
|
|
|
75
92
|
const where = {
|
|
76
93
|
key: `${prefix}_${key}`,
|
|
77
|
-
environment,
|
|
78
|
-
tag,
|
|
94
|
+
environment: environment || null,
|
|
95
|
+
tag: tag || null,
|
|
79
96
|
};
|
|
80
97
|
|
|
81
98
|
const data = await db.query('strapi::core-store').findOne({ where });
|
|
82
99
|
|
|
83
100
|
if (data) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
101
|
+
return db.query('strapi::core-store').update({
|
|
102
|
+
where: { id: data.id },
|
|
103
|
+
data: {
|
|
104
|
+
value: JSON.stringify(value) || value.toString(),
|
|
105
|
+
type: typeof value,
|
|
106
|
+
},
|
|
87
107
|
});
|
|
108
|
+
}
|
|
88
109
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
110
|
+
return db.query('strapi::core-store').create({
|
|
111
|
+
data: {
|
|
112
|
+
...where,
|
|
92
113
|
value: JSON.stringify(value) || value.toString(),
|
|
93
|
-
type:
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
await db.query('strapi::core-store').create({ data });
|
|
98
|
-
}
|
|
99
|
-
}
|
|
114
|
+
type: typeof value,
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
},
|
|
100
118
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
119
|
+
/**
|
|
120
|
+
* Deletes a value from the core store
|
|
121
|
+
* @param {Object} params
|
|
122
|
+
* @returns {*}
|
|
123
|
+
*/
|
|
124
|
+
async delete(params = {}) {
|
|
125
|
+
const { key, environment, type, name, tag } = params;
|
|
107
126
|
|
|
108
127
|
const prefix = `${type}${name ? `_${name}` : ''}`;
|
|
109
128
|
|
|
110
129
|
const where = {
|
|
111
130
|
key: `${prefix}_${key}`,
|
|
112
|
-
environment,
|
|
113
|
-
tag,
|
|
131
|
+
environment: environment || null,
|
|
132
|
+
tag: tag || null,
|
|
114
133
|
};
|
|
115
134
|
|
|
116
|
-
|
|
117
|
-
}
|
|
135
|
+
return db.query('strapi::core-store').delete({ where });
|
|
136
|
+
},
|
|
137
|
+
});
|
|
118
138
|
|
|
119
|
-
|
|
120
|
-
get,
|
|
121
|
-
set,
|
|
122
|
-
delete: deleteFn,
|
|
123
|
-
};
|
|
124
|
-
};
|
|
139
|
+
return store;
|
|
125
140
|
};
|
|
126
141
|
|
|
127
142
|
module.exports = {
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { Job } = require('node-schedule');
|
|
4
|
+
const { isFunction } = require('lodash/fp');
|
|
5
|
+
|
|
6
|
+
const createCronService = () => {
|
|
7
|
+
let jobsSpecs = [];
|
|
8
|
+
|
|
9
|
+
return {
|
|
10
|
+
add(tasks = {}) {
|
|
11
|
+
for (const taskExpression in tasks) {
|
|
12
|
+
const taskValue = tasks[taskExpression];
|
|
13
|
+
|
|
14
|
+
let fn;
|
|
15
|
+
let options;
|
|
16
|
+
if (isFunction(taskValue)) {
|
|
17
|
+
fn = taskValue.bind(tasks);
|
|
18
|
+
options = taskExpression;
|
|
19
|
+
} else if (isFunction(taskValue.task)) {
|
|
20
|
+
fn = taskValue.task.bind(taskValue);
|
|
21
|
+
options = taskValue.options;
|
|
22
|
+
} else {
|
|
23
|
+
throw new Error(
|
|
24
|
+
`Could not schedule a cron job for "${taskExpression}": no function found.`
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const fnWithStrapi = (...args) => fn({ strapi }, ...args);
|
|
29
|
+
|
|
30
|
+
const job = new Job(null, fnWithStrapi);
|
|
31
|
+
jobsSpecs.push({ job, options });
|
|
32
|
+
}
|
|
33
|
+
return this;
|
|
34
|
+
},
|
|
35
|
+
start() {
|
|
36
|
+
if (!strapi.config.get('server.cron.enabled')) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
jobsSpecs.forEach(({ job, options }) => job.schedule(options));
|
|
40
|
+
return this;
|
|
41
|
+
},
|
|
42
|
+
stop() {
|
|
43
|
+
jobsSpecs.forEach(({ job }) => job.cancel());
|
|
44
|
+
return this;
|
|
45
|
+
},
|
|
46
|
+
destroy() {
|
|
47
|
+
this.stop();
|
|
48
|
+
jobsSpecs = [];
|
|
49
|
+
return this;
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
module.exports = createCronService;
|