@strapi/strapi 4.11.0-exp.push-transfer-push-stuck → 4.11.1-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commands/actions/develop/action.js +5 -6
- package/lib/commands/actions/ts/generate-types/action.js +12 -9
- package/lib/commands/actions/ts/generate-types/command.js +4 -4
- package/lib/core/domain/content-type/index.js +1 -7
- package/lib/factories.d.ts +21 -0
- package/lib/global.d.ts +0 -44
- package/lib/index.d.ts +2 -1
- package/lib/services/entity-service/index.d.ts +1 -3
- package/lib/services/entity-service/index.js +60 -20
- package/lib/services/webhook-store.js +32 -4
- package/lib/types/core/attributes/base.d.ts +8 -5
- package/lib/types/core/attributes/biginteger.d.ts +8 -15
- package/lib/types/core/attributes/boolean.d.ts +7 -13
- package/lib/types/core/attributes/common.d.ts +46 -20
- package/lib/types/core/attributes/component.d.ts +24 -29
- package/lib/types/core/attributes/date-time.d.ts +8 -15
- package/lib/types/core/attributes/date.d.ts +8 -17
- package/lib/types/core/attributes/decimal.d.ts +8 -15
- package/lib/types/core/attributes/dynamic-zone.d.ts +18 -21
- package/lib/types/core/attributes/email.d.ts +9 -19
- package/lib/types/core/attributes/enumeration.d.ts +12 -22
- package/lib/types/core/attributes/float.d.ts +8 -17
- package/lib/types/core/attributes/integer.d.ts +8 -15
- package/lib/types/core/attributes/json.d.ts +8 -11
- package/lib/types/core/attributes/media.d.ts +23 -25
- package/lib/types/core/attributes/password.d.ts +8 -15
- package/lib/types/core/attributes/relation.d.ts +96 -48
- package/lib/types/core/attributes/richtext.d.ts +8 -15
- package/lib/types/core/attributes/string.d.ts +11 -21
- package/lib/types/core/attributes/text.d.ts +11 -21
- package/lib/types/core/attributes/time.d.ts +8 -17
- package/lib/types/core/attributes/timestamp.d.ts +8 -15
- package/lib/types/core/attributes/uid.d.ts +35 -39
- package/lib/types/core/attributes/utils.d.ts +69 -79
- package/lib/types/core/common/controller.d.ts +8 -0
- package/lib/types/core/common/index.d.ts +4 -0
- package/lib/types/core/common/schema.d.ts +3 -0
- package/lib/types/core/common/service.d.ts +3 -0
- package/lib/types/core/common/uid.d.ts +62 -0
- package/lib/types/core/index.d.ts +7 -2
- package/lib/types/core/namespace.d.ts +99 -0
- package/lib/types/core/registry.d.ts +68 -0
- package/lib/types/core/schemas/index.d.ts +16 -15
- package/lib/types/core/strapi/index.d.ts +7 -11
- package/lib/types/core/uid.d.ts +167 -0
- package/lib/types/core-api/controller.d.ts +52 -0
- package/lib/types/core-api/index.d.ts +3 -0
- package/lib/types/core-api/router.d.ts +65 -0
- package/lib/types/core-api/service.d.ts +48 -0
- package/lib/types/index.d.ts +4 -2
- package/lib/types/shared/index.d.ts +1 -0
- package/lib/types/shared/registries.d.ts +45 -0
- package/lib/types/utils/array.d.ts +25 -0
- package/lib/types/utils/expression.d.ts +68 -0
- package/lib/types/utils/guard.d.ts +14 -0
- package/lib/types/utils/index.d.ts +19 -0
- package/lib/types/utils/object.d.ts +29 -0
- package/lib/types/utils/string.d.ts +41 -0
- package/lib/types/utils/tuple.d.ts +13 -0
- package/package.json +17 -17
- package/lib/core/registries/services.d.ts +0 -7
- package/lib/core-api/controller/index.d.ts +0 -27
- package/lib/core-api/service/index.d.ts +0 -25
- package/lib/types/factories.d.ts +0 -60
- package/lib/types/utils.d.ts +0 -95
|
@@ -121,13 +121,12 @@ const workerProcess = async ({ appDir, distDir, watchAdmin, polling, isTSProject
|
|
|
121
121
|
const shouldGenerateTypeScriptTypes = strapiInstance.config.get('typescript.autogenerate', false);
|
|
122
122
|
|
|
123
123
|
if (shouldGenerateTypeScriptTypes) {
|
|
124
|
-
|
|
125
|
-
// NOTE: We should probably add some configuration options to manage the file structure output or the verbosity level
|
|
126
|
-
tsUtils.generators.generateSchemasDefinitions({
|
|
124
|
+
await tsUtils.generators.generate({
|
|
127
125
|
strapi: strapiInstance,
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
silent: true,
|
|
126
|
+
pwd: appDir,
|
|
127
|
+
rootDir: undefined,
|
|
128
|
+
logger: { silent: true, debug: false },
|
|
129
|
+
artifacts: { contentTypes: true, components: true },
|
|
131
130
|
});
|
|
132
131
|
}
|
|
133
132
|
|
|
@@ -4,22 +4,25 @@ const tsUtils = require('@strapi/typescript-utils');
|
|
|
4
4
|
|
|
5
5
|
const strapi = require('../../../../index');
|
|
6
6
|
|
|
7
|
-
module.exports = async ({
|
|
8
|
-
if (verbose && silent) {
|
|
9
|
-
console.error('
|
|
7
|
+
module.exports = async ({ debug, silent, verbose, outDir }) => {
|
|
8
|
+
if ((debug || verbose) && silent) {
|
|
9
|
+
console.error('Flags conflict: both silent and debug mode are enabled, exiting...');
|
|
10
10
|
process.exit(1);
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
const appContext = await strapi.compile();
|
|
14
14
|
const app = await strapi(appContext).register();
|
|
15
15
|
|
|
16
|
-
await tsUtils.generators.
|
|
16
|
+
await tsUtils.generators.generate({
|
|
17
17
|
strapi: app,
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
pwd: appContext.appDir,
|
|
19
|
+
rootDir: outDir ?? undefined,
|
|
20
|
+
logger: {
|
|
21
|
+
silent,
|
|
22
|
+
// TODO V5: verbose is deprecated and should be removed
|
|
23
|
+
debug: debug || verbose,
|
|
24
|
+
},
|
|
25
|
+
artifacts: { contentTypes: true, components: true },
|
|
23
26
|
});
|
|
24
27
|
|
|
25
28
|
app.destroy();
|
|
@@ -10,12 +10,12 @@ module.exports = ({ command }) => {
|
|
|
10
10
|
command
|
|
11
11
|
.command('ts:generate-types')
|
|
12
12
|
.description(`Generate TypeScript typings for your schemas`)
|
|
13
|
+
.option('--verbose', `[DEPRECATED] The verbose option has been replaced by debug`, false)
|
|
14
|
+
.option('-d, --debug', `Run the generation with debug messages`, false)
|
|
15
|
+
.option('-s, --silent', `Run the generation silently, without any output`, false)
|
|
13
16
|
.option(
|
|
14
17
|
'-o, --out-dir <outDir>',
|
|
15
|
-
'Specify a relative directory in which the
|
|
18
|
+
'Specify a relative root directory in which the definitions will be generated. Changing this value might break types exposed by Strapi that relies on generated types.'
|
|
16
19
|
)
|
|
17
|
-
.option('-f, --file <file>', 'Specify a filename to store the schemas definitions')
|
|
18
|
-
.option('--verbose', `Display more information about the types generation`, false)
|
|
19
|
-
.option('-s, --silent', `Run the generation silently, without any output`, false)
|
|
20
20
|
.action(getLocalScript('ts/generate-types'));
|
|
21
21
|
};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const { cloneDeep } = require('lodash/fp');
|
|
4
4
|
const _ = require('lodash');
|
|
5
|
-
const { hasDraftAndPublish
|
|
5
|
+
const { hasDraftAndPublish } = require('@strapi/utils').contentTypes;
|
|
6
6
|
const {
|
|
7
7
|
CREATED_AT_ATTRIBUTE,
|
|
8
8
|
UPDATED_AT_ATTRIBUTE,
|
|
@@ -58,12 +58,6 @@ const createContentType = (uid, definition) => {
|
|
|
58
58
|
);
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
Object.defineProperty(schema, 'privateAttributes', {
|
|
62
|
-
get() {
|
|
63
|
-
return getPrivateAttributes(schema);
|
|
64
|
-
},
|
|
65
|
-
});
|
|
66
|
-
|
|
67
61
|
// attributes
|
|
68
62
|
Object.assign(schema.attributes, {
|
|
69
63
|
[CREATED_AT_ATTRIBUTE]: {
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Common, CoreApi, Strapi } from '@strapi/strapi';
|
|
2
|
+
|
|
3
|
+
type WithStrapiCallback<T> = <S extends { strapi: Strapi }>(params: S) => T;
|
|
4
|
+
|
|
5
|
+
export declare function createCoreRouter<T extends Common.UID.ContentType>(
|
|
6
|
+
uid: T,
|
|
7
|
+
cfg?: CoreApi.Router.RouterConfig<T>
|
|
8
|
+
): () => CoreApi.Router.Router;
|
|
9
|
+
|
|
10
|
+
export declare function createCoreController<
|
|
11
|
+
T extends Common.UID.ContentType,
|
|
12
|
+
S extends Partial<CoreApi.Controller.Extendable<T>>
|
|
13
|
+
>(
|
|
14
|
+
uid: T,
|
|
15
|
+
config?: WithStrapiCallback<S> | S
|
|
16
|
+
): () => Required<S & CoreApi.Controller.ContentType<T>>;
|
|
17
|
+
|
|
18
|
+
export declare function createCoreService<
|
|
19
|
+
T extends Common.UID.ContentType,
|
|
20
|
+
S extends Partial<CoreApi.Service.Extendable<T>>
|
|
21
|
+
>(uid: T, config?: WithStrapiCallback<S> | S): () => Required<S & CoreApi.Service.ContentType<T>>;
|
package/lib/global.d.ts
CHANGED
|
@@ -1,51 +1,7 @@
|
|
|
1
1
|
import type { Strapi as StrapiInterface } from './types/core';
|
|
2
|
-
import type {
|
|
3
|
-
CollectionTypeSchema,
|
|
4
|
-
SingleTypeSchema,
|
|
5
|
-
ComponentSchema,
|
|
6
|
-
ContentTypeSchema,
|
|
7
|
-
} from './types/core/schemas';
|
|
8
|
-
import type { KeysBy } from './types/utils';
|
|
9
2
|
|
|
10
3
|
declare global {
|
|
11
4
|
namespace Strapi {
|
|
12
|
-
/**
|
|
13
|
-
* Map of UID / schemas used as a schemas database for other types.
|
|
14
|
-
* It must be extended by the user application or plugins.
|
|
15
|
-
*
|
|
16
|
-
* @example
|
|
17
|
-
* ```ts
|
|
18
|
-
* declare global {
|
|
19
|
-
* namespace Strapi {
|
|
20
|
-
* interface Schemas {
|
|
21
|
-
* 'xxx::xxx.uid: ContentTypeSchema | ComponentSchema;
|
|
22
|
-
* }
|
|
23
|
-
* }
|
|
24
|
-
* }
|
|
25
|
-
* ```
|
|
26
|
-
*/
|
|
27
|
-
interface Schemas {}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Literal union type of every content type registered in Strapi.Schemas
|
|
31
|
-
*/
|
|
32
|
-
type ContentTypeUIDs = KeysBy<Schemas, ContentTypeSchema>;
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Literal union type of every collection type registered in Strapi.Schemas
|
|
36
|
-
*/
|
|
37
|
-
type CollectionTypeUIDs = KeysBy<Schemas, CollectionTypeSchema>;
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Literal union type of every single type registered in Strapi.Schemas
|
|
41
|
-
*/
|
|
42
|
-
type SingleTypeUIDs = KeysBy<Schemas, SingleTypeSchema>;
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Literal union type of every component registered in Strapi.Schemas
|
|
46
|
-
*/
|
|
47
|
-
type ComponentUIDs = KeysBy<Schemas, ComponentSchema>;
|
|
48
|
-
|
|
49
5
|
/**
|
|
50
6
|
* Global shorthand to access the `StrapiInterface` type
|
|
51
7
|
*/
|
package/lib/index.d.ts
CHANGED
|
@@ -4,11 +4,7 @@ const _ = require('lodash');
|
|
|
4
4
|
const delegate = require('delegates');
|
|
5
5
|
const { InvalidTimeError, InvalidDateError, InvalidDateTimeError, InvalidRelationError } =
|
|
6
6
|
require('@strapi/database').errors;
|
|
7
|
-
const {
|
|
8
|
-
webhook: webhookUtils,
|
|
9
|
-
contentTypes: contentTypesUtils,
|
|
10
|
-
sanitize,
|
|
11
|
-
} = require('@strapi/utils');
|
|
7
|
+
const { contentTypes: contentTypesUtils, sanitize } = require('@strapi/utils');
|
|
12
8
|
const { ValidationError } = require('@strapi/utils').errors;
|
|
13
9
|
const { isAnyToMany } = require('@strapi/utils').relations;
|
|
14
10
|
const { transformParamsToQuery } = require('@strapi/utils').convertQueryParams;
|
|
@@ -31,9 +27,6 @@ const transformLoadParamsToQuery = (uid, field, params = {}, pagination = {}) =>
|
|
|
31
27
|
};
|
|
32
28
|
};
|
|
33
29
|
|
|
34
|
-
// TODO: those should be strapi events used by the webhooks not the other way arround
|
|
35
|
-
const { ENTRY_CREATE, ENTRY_UPDATE, ENTRY_DELETE } = webhookUtils.webhookEvents;
|
|
36
|
-
|
|
37
30
|
const databaseErrorsToTransform = [
|
|
38
31
|
InvalidTimeError,
|
|
39
32
|
InvalidDateTimeError,
|
|
@@ -49,6 +42,12 @@ const updatePipeline = (data, context) => {
|
|
|
49
42
|
return applyTransforms(data, context);
|
|
50
43
|
};
|
|
51
44
|
|
|
45
|
+
const ALLOWED_WEBHOOK_EVENTS = {
|
|
46
|
+
ENTRY_CREATE: 'entry.create',
|
|
47
|
+
ENTRY_UPDATE: 'entry.update',
|
|
48
|
+
ENTRY_DELETE: 'entry.delete',
|
|
49
|
+
};
|
|
50
|
+
|
|
52
51
|
/**
|
|
53
52
|
* @type {import('.').default}
|
|
54
53
|
*/
|
|
@@ -59,6 +58,10 @@ const createDefaultImplementation = ({ strapi, db, eventHub, entityValidator })
|
|
|
59
58
|
return options;
|
|
60
59
|
},
|
|
61
60
|
|
|
61
|
+
async wrapResult(result) {
|
|
62
|
+
return result;
|
|
63
|
+
},
|
|
64
|
+
|
|
62
65
|
async emitEvent(uid, event, entity) {
|
|
63
66
|
// Ignore audit log events to prevent infinite loops
|
|
64
67
|
if (uid === 'admin::audit-log') {
|
|
@@ -83,10 +86,12 @@ const createDefaultImplementation = ({ strapi, db, eventHub, entityValidator })
|
|
|
83
86
|
const query = transformParamsToQuery(uid, wrappedParams);
|
|
84
87
|
|
|
85
88
|
if (kind === 'singleType') {
|
|
86
|
-
|
|
89
|
+
const entity = db.query(uid).findOne(query);
|
|
90
|
+
return this.wrapResult(entity, { uid, action: 'findOne' });
|
|
87
91
|
}
|
|
88
92
|
|
|
89
|
-
|
|
93
|
+
const entities = await db.query(uid).findMany(query);
|
|
94
|
+
return this.wrapResult(entities, { uid, action: 'findMany' });
|
|
90
95
|
},
|
|
91
96
|
|
|
92
97
|
async findPage(uid, opts) {
|
|
@@ -94,7 +99,11 @@ const createDefaultImplementation = ({ strapi, db, eventHub, entityValidator })
|
|
|
94
99
|
|
|
95
100
|
const query = transformParamsToQuery(uid, wrappedParams);
|
|
96
101
|
|
|
97
|
-
|
|
102
|
+
const page = await db.query(uid).findPage(query);
|
|
103
|
+
return {
|
|
104
|
+
...page,
|
|
105
|
+
results: await this.wrapResult(page.results, { uid, action: 'findPage' }),
|
|
106
|
+
};
|
|
98
107
|
},
|
|
99
108
|
|
|
100
109
|
// TODO: streamline the logic based on the populate option
|
|
@@ -103,7 +112,11 @@ const createDefaultImplementation = ({ strapi, db, eventHub, entityValidator })
|
|
|
103
112
|
|
|
104
113
|
const query = transformParamsToQuery(uid, wrappedParams);
|
|
105
114
|
|
|
106
|
-
|
|
115
|
+
const entities = await db.query(uid).findPage(query);
|
|
116
|
+
return {
|
|
117
|
+
...entities,
|
|
118
|
+
results: await this.wrapResult(entities.results, { uid, action: 'findWithRelationCounts' }),
|
|
119
|
+
};
|
|
107
120
|
},
|
|
108
121
|
|
|
109
122
|
async findWithRelationCounts(uid, opts) {
|
|
@@ -111,7 +124,8 @@ const createDefaultImplementation = ({ strapi, db, eventHub, entityValidator })
|
|
|
111
124
|
|
|
112
125
|
const query = transformParamsToQuery(uid, wrappedParams);
|
|
113
126
|
|
|
114
|
-
|
|
127
|
+
const entities = await db.query(uid).findMany(query);
|
|
128
|
+
return this.wrapResult(entities, { uid, action: 'findWithRelationCounts' });
|
|
115
129
|
},
|
|
116
130
|
|
|
117
131
|
async findOne(uid, entityId, opts) {
|
|
@@ -119,7 +133,8 @@ const createDefaultImplementation = ({ strapi, db, eventHub, entityValidator })
|
|
|
119
133
|
|
|
120
134
|
const query = transformParamsToQuery(uid, pickSelectionParams(wrappedParams));
|
|
121
135
|
|
|
122
|
-
|
|
136
|
+
const entity = await db.query(uid).findOne({ ...query, where: { id: entityId } });
|
|
137
|
+
return this.wrapResult(entity, { uid, action: 'findOne' });
|
|
123
138
|
},
|
|
124
139
|
|
|
125
140
|
async count(uid, opts) {
|
|
@@ -162,6 +177,9 @@ const createDefaultImplementation = ({ strapi, db, eventHub, entityValidator })
|
|
|
162
177
|
entity = await this.findOne(uid, entity.id, wrappedParams);
|
|
163
178
|
}
|
|
164
179
|
|
|
180
|
+
entity = await this.wrapResult(entity, { uid, action: 'create' });
|
|
181
|
+
|
|
182
|
+
const { ENTRY_CREATE } = ALLOWED_WEBHOOK_EVENTS;
|
|
165
183
|
await this.emitEvent(uid, ENTRY_CREATE, entity);
|
|
166
184
|
|
|
167
185
|
return entity;
|
|
@@ -213,6 +231,9 @@ const createDefaultImplementation = ({ strapi, db, eventHub, entityValidator })
|
|
|
213
231
|
entity = await this.findOne(uid, entity.id, wrappedParams);
|
|
214
232
|
}
|
|
215
233
|
|
|
234
|
+
entity = await this.wrapResult(entity, { uid, action: 'update' });
|
|
235
|
+
|
|
236
|
+
const { ENTRY_UPDATE } = ALLOWED_WEBHOOK_EVENTS;
|
|
216
237
|
await this.emitEvent(uid, ENTRY_UPDATE, entity);
|
|
217
238
|
|
|
218
239
|
return entity;
|
|
@@ -224,7 +245,7 @@ const createDefaultImplementation = ({ strapi, db, eventHub, entityValidator })
|
|
|
224
245
|
// select / populate
|
|
225
246
|
const query = transformParamsToQuery(uid, pickSelectionParams(wrappedParams));
|
|
226
247
|
|
|
227
|
-
|
|
248
|
+
let entityToDelete = await db.query(uid).findOne({
|
|
228
249
|
...query,
|
|
229
250
|
where: { id: entityId },
|
|
230
251
|
});
|
|
@@ -238,6 +259,9 @@ const createDefaultImplementation = ({ strapi, db, eventHub, entityValidator })
|
|
|
238
259
|
await db.query(uid).delete({ where: { id: entityToDelete.id } });
|
|
239
260
|
await deleteComponents(uid, componentsToDelete, { loadComponents: false });
|
|
240
261
|
|
|
262
|
+
entityToDelete = await this.wrapResult(entityToDelete, { uid, action: 'delete' });
|
|
263
|
+
|
|
264
|
+
const { ENTRY_DELETE } = ALLOWED_WEBHOOK_EVENTS;
|
|
241
265
|
await this.emitEvent(uid, ENTRY_DELETE, entityToDelete);
|
|
242
266
|
|
|
243
267
|
return entityToDelete;
|
|
@@ -250,7 +274,7 @@ const createDefaultImplementation = ({ strapi, db, eventHub, entityValidator })
|
|
|
250
274
|
// select / populate
|
|
251
275
|
const query = transformParamsToQuery(uid, wrappedParams);
|
|
252
276
|
|
|
253
|
-
|
|
277
|
+
let entitiesToDelete = await db.query(uid).findMany(query);
|
|
254
278
|
|
|
255
279
|
if (!entitiesToDelete.length) {
|
|
256
280
|
return null;
|
|
@@ -265,21 +289,28 @@ const createDefaultImplementation = ({ strapi, db, eventHub, entityValidator })
|
|
|
265
289
|
componentsToDelete.map((compos) => deleteComponents(uid, compos, { loadComponents: false }))
|
|
266
290
|
);
|
|
267
291
|
|
|
292
|
+
entitiesToDelete = await this.wrapResult(entitiesToDelete, { uid, action: 'delete' });
|
|
293
|
+
|
|
268
294
|
// Trigger webhooks. One for each entity
|
|
295
|
+
const { ENTRY_DELETE } = ALLOWED_WEBHOOK_EVENTS;
|
|
269
296
|
await Promise.all(entitiesToDelete.map((entity) => this.emitEvent(uid, ENTRY_DELETE, entity)));
|
|
270
297
|
|
|
271
298
|
return deletedEntities;
|
|
272
299
|
},
|
|
273
300
|
|
|
274
|
-
load(uid, entity, field, params = {}) {
|
|
301
|
+
async load(uid, entity, field, params = {}) {
|
|
275
302
|
if (!_.isString(field)) {
|
|
276
303
|
throw new Error(`Invalid load. Expected "${field}" to be a string`);
|
|
277
304
|
}
|
|
278
305
|
|
|
279
|
-
|
|
306
|
+
const loadedEntity = await db
|
|
307
|
+
.query(uid)
|
|
308
|
+
.load(entity, field, transformLoadParamsToQuery(uid, field, params));
|
|
309
|
+
|
|
310
|
+
return this.wrapResult(loadedEntity, { uid, field, action: 'load' });
|
|
280
311
|
},
|
|
281
312
|
|
|
282
|
-
loadPages(uid, entity, field, params = {}, pagination = {}) {
|
|
313
|
+
async loadPages(uid, entity, field, params = {}, pagination = {}) {
|
|
283
314
|
if (!_.isString(field)) {
|
|
284
315
|
throw new Error(`Invalid load. Expected "${field}" to be a string`);
|
|
285
316
|
}
|
|
@@ -293,11 +324,20 @@ const createDefaultImplementation = ({ strapi, db, eventHub, entityValidator })
|
|
|
293
324
|
|
|
294
325
|
const query = transformLoadParamsToQuery(uid, field, params, pagination);
|
|
295
326
|
|
|
296
|
-
|
|
327
|
+
const loadedPage = await db.query(uid).loadPages(entity, field, query);
|
|
328
|
+
|
|
329
|
+
return {
|
|
330
|
+
...loadedPage,
|
|
331
|
+
results: await this.wrapResult(loadedPage.results, { uid, field, action: 'load' }),
|
|
332
|
+
};
|
|
297
333
|
},
|
|
298
334
|
});
|
|
299
335
|
|
|
300
336
|
module.exports = (ctx) => {
|
|
337
|
+
Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {
|
|
338
|
+
ctx.strapi.webhookStore.addAllowedEvent(key, value);
|
|
339
|
+
});
|
|
340
|
+
|
|
301
341
|
const implementation = createDefaultImplementation(ctx);
|
|
302
342
|
|
|
303
343
|
const service = {
|
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
'use strict';
|
|
6
6
|
|
|
7
|
+
const { mapAsync } = require('@strapi/utils');
|
|
8
|
+
const { ValidationError } = require('@strapi/utils').errors;
|
|
9
|
+
|
|
7
10
|
const webhookModel = {
|
|
8
11
|
uid: 'webhook',
|
|
9
12
|
collectionName: 'strapi_webhooks',
|
|
@@ -47,30 +50,56 @@ const fromDBObject = (row) => {
|
|
|
47
50
|
};
|
|
48
51
|
};
|
|
49
52
|
|
|
53
|
+
const webhookEventValidator = async (allowedEvents, events) => {
|
|
54
|
+
const allowedValues = Array.from(allowedEvents.values());
|
|
55
|
+
|
|
56
|
+
await mapAsync(events, (event) => {
|
|
57
|
+
if (allowedValues.includes(event)) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
throw new ValidationError(`Webhook event ${event} is not supported`);
|
|
62
|
+
});
|
|
63
|
+
};
|
|
64
|
+
|
|
50
65
|
const createWebhookStore = ({ db }) => {
|
|
51
66
|
const webhookQueries = db.query('webhook');
|
|
52
67
|
|
|
53
68
|
return {
|
|
69
|
+
allowedEvents: new Map([]),
|
|
70
|
+
addAllowedEvent(key, value) {
|
|
71
|
+
this.allowedEvents.set(key, value);
|
|
72
|
+
},
|
|
73
|
+
removeAllowedEvent(key) {
|
|
74
|
+
this.allowedEvents.delete(key);
|
|
75
|
+
},
|
|
76
|
+
listAllowedEvents() {
|
|
77
|
+
return Array.from(this.allowedEvents.keys());
|
|
78
|
+
},
|
|
79
|
+
getAllowedEvent(key) {
|
|
80
|
+
return this.allowedEvents.get(key);
|
|
81
|
+
},
|
|
54
82
|
async findWebhooks() {
|
|
55
83
|
const results = await webhookQueries.findMany();
|
|
56
84
|
|
|
57
85
|
return results.map(fromDBObject);
|
|
58
86
|
},
|
|
59
|
-
|
|
60
87
|
async findWebhook(id) {
|
|
61
88
|
const result = await webhookQueries.findOne({ where: { id } });
|
|
62
89
|
return result ? fromDBObject(result) : null;
|
|
63
90
|
},
|
|
91
|
+
async createWebhook(data) {
|
|
92
|
+
await webhookEventValidator(this.allowedEvents, data.events);
|
|
64
93
|
|
|
65
|
-
createWebhook(data) {
|
|
66
94
|
return webhookQueries
|
|
67
95
|
.create({
|
|
68
96
|
data: toDBObject({ ...data, isEnabled: true }),
|
|
69
97
|
})
|
|
70
98
|
.then(fromDBObject);
|
|
71
99
|
},
|
|
72
|
-
|
|
73
100
|
async updateWebhook(id, data) {
|
|
101
|
+
await webhookEventValidator(this.allowedEvents, data.events);
|
|
102
|
+
|
|
74
103
|
const webhook = await webhookQueries.update({
|
|
75
104
|
where: { id },
|
|
76
105
|
data: toDBObject(data),
|
|
@@ -78,7 +107,6 @@ const createWebhookStore = ({ db }) => {
|
|
|
78
107
|
|
|
79
108
|
return webhook ? fromDBObject(webhook) : null;
|
|
80
109
|
},
|
|
81
|
-
|
|
82
110
|
async deleteWebhook(id) {
|
|
83
111
|
const webhook = await webhookQueries.delete({ where: { id } });
|
|
84
112
|
return webhook ? fromDBObject(webhook) : null;
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import { GetAttributeValue } from './utils';
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
* List of all the Strapi attribute types
|
|
5
3
|
*/
|
|
6
|
-
export type
|
|
4
|
+
export type Kind =
|
|
7
5
|
| 'string'
|
|
8
6
|
| 'text'
|
|
9
7
|
| 'richtext'
|
|
@@ -29,11 +27,11 @@ export type AttributeType =
|
|
|
29
27
|
/**
|
|
30
28
|
* Most basic shape of a schema attribute
|
|
31
29
|
*/
|
|
32
|
-
export interface Attribute<
|
|
30
|
+
export interface Attribute<TKind extends Kind = Kind> {
|
|
33
31
|
/**
|
|
34
32
|
* Type of the attribute
|
|
35
33
|
*/
|
|
36
|
-
type:
|
|
34
|
+
type: TKind;
|
|
37
35
|
|
|
38
36
|
/**
|
|
39
37
|
* Options defined and used by the plugins
|
|
@@ -41,6 +39,11 @@ export interface Attribute<T extends AttributeType = AttributeType> {
|
|
|
41
39
|
pluginOptions?: object;
|
|
42
40
|
}
|
|
43
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Creates a basic Attribute of type T
|
|
44
|
+
*/
|
|
45
|
+
export type OfType<T extends Kind> = Attribute<T>;
|
|
46
|
+
|
|
44
47
|
// Common attributes Options
|
|
45
48
|
|
|
46
49
|
export interface RequiredOption {
|
|
@@ -1,22 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Attribute,
|
|
3
|
-
ConfigurableOption,
|
|
4
|
-
DefaultOption,
|
|
5
|
-
MinMaxOption,
|
|
6
|
-
PrivateOption,
|
|
7
|
-
RequiredOption,
|
|
8
|
-
} from './base';
|
|
1
|
+
import type { Attribute } from '@strapi/strapi';
|
|
9
2
|
|
|
10
|
-
export type
|
|
3
|
+
export type BigInteger = Attribute.OfType<'biginteger'> &
|
|
11
4
|
// Options
|
|
12
|
-
ConfigurableOption &
|
|
13
|
-
DefaultOption<BigIntegerValue> &
|
|
14
|
-
MinMaxOption<string> &
|
|
15
|
-
PrivateOption &
|
|
16
|
-
RequiredOption;
|
|
5
|
+
Attribute.ConfigurableOption &
|
|
6
|
+
Attribute.DefaultOption<BigIntegerValue> &
|
|
7
|
+
Attribute.MinMaxOption<string> &
|
|
8
|
+
Attribute.PrivateOption &
|
|
9
|
+
Attribute.RequiredOption;
|
|
17
10
|
|
|
18
11
|
export type BigIntegerValue = string;
|
|
19
12
|
|
|
20
|
-
export type
|
|
13
|
+
export type GetBigIntegerValue<T extends Attribute.Attribute> = T extends BigInteger
|
|
21
14
|
? BigIntegerValue
|
|
22
15
|
: never;
|
|
@@ -1,20 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Attribute,
|
|
3
|
-
ConfigurableOption,
|
|
4
|
-
DefaultOption,
|
|
5
|
-
PrivateOption,
|
|
6
|
-
RequiredOption,
|
|
7
|
-
} from './base';
|
|
1
|
+
import type { Attribute } from '@strapi/strapi';
|
|
8
2
|
|
|
9
|
-
export type
|
|
3
|
+
export type Boolean = Attribute.OfType<'boolean'> &
|
|
10
4
|
// Options
|
|
11
|
-
ConfigurableOption &
|
|
12
|
-
DefaultOption<BooleanValue> &
|
|
13
|
-
PrivateOption &
|
|
14
|
-
RequiredOption;
|
|
5
|
+
Attribute.ConfigurableOption &
|
|
6
|
+
Attribute.DefaultOption<BooleanValue> &
|
|
7
|
+
Attribute.PrivateOption &
|
|
8
|
+
Attribute.RequiredOption;
|
|
15
9
|
|
|
16
10
|
export type BooleanValue = boolean;
|
|
17
11
|
|
|
18
|
-
export type
|
|
12
|
+
export type GetBooleanValue<T extends Attribute.Attribute> = T extends Boolean
|
|
19
13
|
? BooleanValue
|
|
20
14
|
: never;
|
|
@@ -2,47 +2,73 @@
|
|
|
2
2
|
* Strapi custom scalar types
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
import { StringAttribute } from './string';
|
|
7
|
-
|
|
8
|
-
export type JSON<T extends object = object> = T;
|
|
9
|
-
|
|
10
|
-
export type Media = any;
|
|
5
|
+
import { Attribute, Common } from '@strapi/strapi';
|
|
11
6
|
|
|
12
7
|
/**
|
|
13
8
|
* Setters for the attributes options
|
|
14
9
|
*/
|
|
15
10
|
|
|
16
11
|
// required
|
|
17
|
-
export type
|
|
18
|
-
export type
|
|
12
|
+
export type Required = { required: true };
|
|
13
|
+
export type NonRequired = { required: false };
|
|
19
14
|
|
|
20
15
|
// private
|
|
21
|
-
export type
|
|
22
|
-
export type
|
|
16
|
+
export type Private = { private: true };
|
|
17
|
+
export type NonPrivate = { private: false };
|
|
23
18
|
|
|
24
19
|
// unique
|
|
25
|
-
export type
|
|
26
|
-
export type
|
|
20
|
+
export type Unique = { unique: true };
|
|
21
|
+
export type NonUnique = { unique: false };
|
|
27
22
|
|
|
28
23
|
// configurable
|
|
29
|
-
export type
|
|
30
|
-
export type
|
|
24
|
+
export type Configurable = { configurable: true };
|
|
25
|
+
export type NonConfigurable = { configurable: false };
|
|
31
26
|
|
|
32
27
|
// custom field
|
|
33
|
-
export type CustomField<
|
|
34
|
-
customField:
|
|
35
|
-
options?:
|
|
28
|
+
export type CustomField<TKind extends string, TOptions extends object | undefined = undefined> = {
|
|
29
|
+
customField: TKind;
|
|
30
|
+
options?: TOptions;
|
|
36
31
|
};
|
|
37
32
|
|
|
38
33
|
// min/max
|
|
39
|
-
export type SetMinMax<
|
|
34
|
+
export type SetMinMax<TConfig extends Attribute.MinMaxOption<TType>, TType = number> = TConfig;
|
|
40
35
|
|
|
41
36
|
// minLength/maxLength
|
|
42
|
-
export type SetMinMaxLength<
|
|
37
|
+
export type SetMinMaxLength<TConfig extends Attribute.MinMaxLengthOption> = TConfig;
|
|
43
38
|
|
|
44
39
|
// pluginOptions
|
|
45
|
-
export type SetPluginOptions<
|
|
40
|
+
export type SetPluginOptions<TConfig extends object = object> = { pluginOptions?: TConfig };
|
|
46
41
|
|
|
47
42
|
// default
|
|
48
43
|
export type DefaultTo<T> = { default: T };
|
|
44
|
+
|
|
45
|
+
// Any Attribute
|
|
46
|
+
export type Any =
|
|
47
|
+
| Attribute.BigInteger
|
|
48
|
+
| Attribute.Boolean
|
|
49
|
+
| Attribute.Component<Common.UID.Component, boolean>
|
|
50
|
+
| Attribute.DateTime
|
|
51
|
+
| Attribute.Date
|
|
52
|
+
| Attribute.Decimal
|
|
53
|
+
| Attribute.DynamicZone
|
|
54
|
+
| Attribute.Email
|
|
55
|
+
| Attribute.Enumeration<string[]>
|
|
56
|
+
| Attribute.Float
|
|
57
|
+
| Attribute.Integer
|
|
58
|
+
| Attribute.JSON
|
|
59
|
+
| Attribute.Media<Attribute.MediaKind | undefined, boolean>
|
|
60
|
+
| Attribute.Password
|
|
61
|
+
| (
|
|
62
|
+
| Attribute.Relation<
|
|
63
|
+
Common.UID.Schema,
|
|
64
|
+
Attribute.RelationKind.BiDirectional,
|
|
65
|
+
Common.UID.Schema
|
|
66
|
+
>
|
|
67
|
+
| Attribute.Relation<Common.UID.Schema, Attribute.RelationKind.UniDirectional>
|
|
68
|
+
)
|
|
69
|
+
| Attribute.RichText
|
|
70
|
+
| Attribute.String
|
|
71
|
+
| Attribute.Text
|
|
72
|
+
| Attribute.Time
|
|
73
|
+
| Attribute.Timestamp
|
|
74
|
+
| Attribute.UID<Common.UID.Schema | undefined>;
|