@strapi/strapi 4.3.0-beta.1 → 4.3.1
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 +19 -1
- package/lib/Strapi.js +4 -2
- package/lib/commands/opt-in-telemetry.js +100 -0
- package/lib/commands/ts/generate-types.js +26 -0
- package/lib/core/app-configuration/config-loader.js +3 -1
- package/lib/core/domain/content-type/validator.js +29 -8
- package/lib/global.d.ts +61 -0
- package/lib/index.d.ts +2 -25
- package/lib/services/cron.js +7 -3
- package/lib/services/webhook-runner.js +1 -1
- package/lib/types/core/attributes/base.d.ts +74 -0
- package/lib/types/core/attributes/biginteger.d.ts +22 -0
- package/lib/types/core/attributes/boolean.d.ts +20 -0
- package/lib/types/core/attributes/common.d.ts +42 -0
- package/lib/types/core/attributes/component.d.ts +41 -0
- package/lib/types/core/attributes/date-time.d.ts +22 -0
- package/lib/types/core/attributes/date.d.ts +22 -0
- package/lib/types/core/attributes/decimal.d.ts +22 -0
- package/lib/types/core/attributes/dynamic-zone.d.ts +29 -0
- package/lib/types/core/attributes/email.d.ts +24 -0
- package/lib/types/core/attributes/enumeration.d.ts +28 -0
- package/lib/types/core/attributes/float.d.ts +22 -0
- package/lib/types/core/attributes/index.d.ts +26 -0
- package/lib/types/core/attributes/integer.d.ts +22 -0
- package/lib/types/core/attributes/json.d.ts +14 -0
- package/lib/types/core/attributes/media.d.ts +36 -0
- package/lib/types/core/attributes/password.d.ts +22 -0
- package/lib/types/core/attributes/relation.d.ts +66 -0
- package/lib/types/core/attributes/richtext.d.ts +22 -0
- package/lib/types/core/attributes/string.d.ts +30 -0
- package/lib/types/core/attributes/text.d.ts +30 -0
- package/lib/types/core/attributes/time.d.ts +22 -0
- package/lib/types/core/attributes/timestamp.d.ts +22 -0
- package/lib/types/core/attributes/uid.d.ts +57 -0
- package/lib/types/core/attributes/utils.d.ts +99 -0
- package/lib/types/core/index.d.ts +3 -0
- package/lib/types/core/schemas/index.d.ts +126 -0
- package/lib/types/{strapi.d.ts → core/strapi/index.d.ts} +21 -0
- package/lib/{factories.d.ts → types/factories.d.ts} +19 -11
- package/lib/types/index.d.ts +4 -0
- package/lib/types/utils.d.ts +95 -1
- package/lib/utils/machine-id.js +2 -2
- package/package.json +22 -22
package/bin/strapi.js
CHANGED
|
@@ -231,7 +231,25 @@ program
|
|
|
231
231
|
// `$ strapi opt-out-telemetry`
|
|
232
232
|
program
|
|
233
233
|
.command('telemetry:disable')
|
|
234
|
-
.description('
|
|
234
|
+
.description('Disable anonymous telemetry and metadata sending to Strapi analytics')
|
|
235
235
|
.action(getLocalScript('opt-out-telemetry'));
|
|
236
236
|
|
|
237
|
+
// `$ strapi opt-in-telemetry`
|
|
238
|
+
program
|
|
239
|
+
.command('telemetry:enable')
|
|
240
|
+
.description('Enable anonymous telemetry and metadata sending to Strapi analytics')
|
|
241
|
+
.action(getLocalScript('opt-in-telemetry'));
|
|
242
|
+
|
|
243
|
+
program
|
|
244
|
+
.command('ts:generate-types')
|
|
245
|
+
.description(`Generate TypeScript typings for your schemas`)
|
|
246
|
+
.option(
|
|
247
|
+
'-o, --out-dir <outDir>',
|
|
248
|
+
'Specify a relative directory in which the schemas definitions will be generated'
|
|
249
|
+
)
|
|
250
|
+
.option('-f, --file <file>', 'Specify a filename to store the schemas definitions')
|
|
251
|
+
.option('--verbose', `Display more information about the types generation`, false)
|
|
252
|
+
.option('-s, --silent', `Run the generation silently, without any output`, false)
|
|
253
|
+
.action(getLocalScript('ts/generate-types'));
|
|
254
|
+
|
|
237
255
|
program.parseAsync(process.argv);
|
package/lib/Strapi.js
CHANGED
|
@@ -405,8 +405,10 @@ class Strapi {
|
|
|
405
405
|
entityValidator: this.entityValidator,
|
|
406
406
|
});
|
|
407
407
|
|
|
408
|
-
|
|
409
|
-
|
|
408
|
+
if (strapi.config.get('server.cron.enabled', true)) {
|
|
409
|
+
const cronTasks = this.config.get('server.cron.tasks', {});
|
|
410
|
+
this.cron.add(cronTasks);
|
|
411
|
+
}
|
|
410
412
|
|
|
411
413
|
this.telemetry.bootstrap();
|
|
412
414
|
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { resolve } = require('path');
|
|
4
|
+
const fse = require('fs-extra');
|
|
5
|
+
const chalk = require('chalk');
|
|
6
|
+
const fetch = require('node-fetch');
|
|
7
|
+
const { v4: uuidv4 } = require('uuid');
|
|
8
|
+
const machineID = require('../utils/machine-id');
|
|
9
|
+
|
|
10
|
+
const readPackageJSON = async path => {
|
|
11
|
+
try {
|
|
12
|
+
const packageObj = await fse.readJson(path);
|
|
13
|
+
return packageObj;
|
|
14
|
+
} catch (err) {
|
|
15
|
+
console.error(`${chalk.red('Error')}: ${err.message}`);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const writePackageJSON = async (path, file, spacing) => {
|
|
20
|
+
try {
|
|
21
|
+
await fse.writeJson(path, file, { spaces: spacing });
|
|
22
|
+
return true;
|
|
23
|
+
} catch (err) {
|
|
24
|
+
console.error(`${chalk.red('Error')}: ${err.message}`);
|
|
25
|
+
console.log(
|
|
26
|
+
`${chalk.yellow(
|
|
27
|
+
'Warning'
|
|
28
|
+
)}: There has been an error, please set "telemetryDisabled": false in the "strapi" object of your package.json manually.`
|
|
29
|
+
);
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const generateNewPackageJSON = packageObj => {
|
|
35
|
+
if (!packageObj.strapi) {
|
|
36
|
+
return {
|
|
37
|
+
...packageObj,
|
|
38
|
+
strapi: {
|
|
39
|
+
uuid: uuidv4(),
|
|
40
|
+
telemetryDisabled: false,
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
} else {
|
|
44
|
+
return {
|
|
45
|
+
...packageObj,
|
|
46
|
+
strapi: {
|
|
47
|
+
...packageObj.strapi,
|
|
48
|
+
uuid: packageObj.strapi.uuid ? packageObj.strapi.uuid : uuidv4(),
|
|
49
|
+
telemetryDisabled: false,
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const sendEvent = async uuid => {
|
|
56
|
+
try {
|
|
57
|
+
await fetch('https://analytics.strapi.io/track', {
|
|
58
|
+
method: 'POST',
|
|
59
|
+
body: JSON.stringify({
|
|
60
|
+
event: 'didOptInTelemetry',
|
|
61
|
+
uuid,
|
|
62
|
+
deviceId: machineID(),
|
|
63
|
+
}),
|
|
64
|
+
headers: { 'Content-Type': 'application/json' },
|
|
65
|
+
});
|
|
66
|
+
} catch (e) {
|
|
67
|
+
//...
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
module.exports = async function optInTelemetry() {
|
|
72
|
+
const packageJSONPath = resolve(process.cwd(), 'package.json');
|
|
73
|
+
const exists = await fse.pathExists(packageJSONPath);
|
|
74
|
+
|
|
75
|
+
if (!exists) {
|
|
76
|
+
console.log(`${chalk.yellow('Warning')}: could not find package.json`);
|
|
77
|
+
process.exit(0);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const packageObj = await readPackageJSON(packageJSONPath);
|
|
81
|
+
|
|
82
|
+
if (packageObj.strapi && packageObj.strapi.uuid) {
|
|
83
|
+
if (packageObj.strapi.telemetryDisabled === false) {
|
|
84
|
+
console.log(`${chalk.yellow('Warning:')} telemetry is already enabled`);
|
|
85
|
+
process.exit(0);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const updatedPackageJSON = generateNewPackageJSON(packageObj);
|
|
90
|
+
|
|
91
|
+
const write = await writePackageJSON(packageJSONPath, updatedPackageJSON, 2);
|
|
92
|
+
|
|
93
|
+
if (!write) {
|
|
94
|
+
process.exit(0);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
await sendEvent(updatedPackageJSON.strapi.uuid);
|
|
98
|
+
console.log(`${chalk.green('Successfully opted into and enabled Strapi telemetry')}`);
|
|
99
|
+
process.exit(0);
|
|
100
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const tsUtils = require('@strapi/typescript-utils');
|
|
4
|
+
|
|
5
|
+
const strapi = require('../../index');
|
|
6
|
+
|
|
7
|
+
module.exports = async function({ outDir, file, verbose, silent }) {
|
|
8
|
+
if (verbose && silent) {
|
|
9
|
+
console.error('You cannot enable verbose and silent flags at the same time, exiting...');
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const appContext = await strapi.compile();
|
|
14
|
+
const app = await strapi(appContext).register();
|
|
15
|
+
|
|
16
|
+
await tsUtils.generators.generateSchemasDefinitions({
|
|
17
|
+
strapi: app,
|
|
18
|
+
outDir: outDir || appContext.appDir,
|
|
19
|
+
file,
|
|
20
|
+
dirs: appContext,
|
|
21
|
+
verbose,
|
|
22
|
+
silent,
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
app.destroy();
|
|
26
|
+
};
|
|
@@ -4,12 +4,14 @@ const path = require('path');
|
|
|
4
4
|
const fs = require('fs');
|
|
5
5
|
const loadFile = require('./load-config-file');
|
|
6
6
|
|
|
7
|
+
const VALID_EXTENSIONS = ['.js', '.json'];
|
|
8
|
+
|
|
7
9
|
module.exports = dir => {
|
|
8
10
|
if (!fs.existsSync(dir)) return {};
|
|
9
11
|
|
|
10
12
|
return fs
|
|
11
13
|
.readdirSync(dir, { withFileTypes: true })
|
|
12
|
-
.filter(file => file.isFile())
|
|
14
|
+
.filter(file => file.isFile() && VALID_EXTENSIONS.includes(path.extname(file.name)))
|
|
13
15
|
.reduce((acc, file) => {
|
|
14
16
|
const key = path.basename(file.name, path.extname(file.name));
|
|
15
17
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const _ = require('lodash');
|
|
4
|
-
const { yup, toRegressedEnumValue
|
|
4
|
+
const { yup, toRegressedEnumValue } = require('@strapi/utils');
|
|
5
5
|
|
|
6
6
|
const LIFECYCLES = [
|
|
7
7
|
'beforeCreate',
|
|
@@ -24,6 +24,20 @@ const LIFECYCLES = [
|
|
|
24
24
|
'afterDeleteMany',
|
|
25
25
|
];
|
|
26
26
|
|
|
27
|
+
/**
|
|
28
|
+
* For enumerations the least common denomiator is GraphQL, where
|
|
29
|
+
* values needs to match the secure name regex:
|
|
30
|
+
* GraphQL Spec https://spec.graphql.org/June2018/#sec-Names
|
|
31
|
+
*
|
|
32
|
+
* Therefore we need to make sure our users only use values, which
|
|
33
|
+
* can be returned by GraphQL, by checking the regressed values
|
|
34
|
+
* agains the GraphQL regex.
|
|
35
|
+
*
|
|
36
|
+
* TODO V5: check if we can avoid this coupling by moving this logic
|
|
37
|
+
* into the GraphQL plugin.
|
|
38
|
+
*/
|
|
39
|
+
const GRAPHQL_ENUM_REGEX = new RegExp('^[_A-Za-z][_0-9A-Za-z]*$');
|
|
40
|
+
|
|
27
41
|
const lifecyclesShape = _.mapValues(_.keyBy(LIFECYCLES), () =>
|
|
28
42
|
yup
|
|
29
43
|
.mixed()
|
|
@@ -54,22 +68,29 @@ const contentTypeSchemaValidator = yup.object().shape({
|
|
|
54
68
|
for (const attrName in attributes) {
|
|
55
69
|
const attr = attributes[attrName];
|
|
56
70
|
if (attr.type === 'enumeration') {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
71
|
+
const regressedValues = attr.enum.map(toRegressedEnumValue);
|
|
72
|
+
|
|
73
|
+
// should match the GraphQL regex
|
|
74
|
+
if (!regressedValues.every(value => GRAPHQL_ENUM_REGEX.test(value))) {
|
|
75
|
+
const message = `Invalid enumeration value. Values should have at least one alphabetical character preceeding the first occurence of a number. Update your enumeration '${attrName}'.`;
|
|
60
76
|
|
|
61
77
|
return this.createError({ message });
|
|
62
78
|
}
|
|
63
79
|
|
|
80
|
+
// should not contain empty values
|
|
81
|
+
if (regressedValues.some(value => value === '')) {
|
|
82
|
+
return this.createError({
|
|
83
|
+
message: `At least one value of the enumeration '${attrName}' appears to be empty. Only alphanumerical characters are taken into account.`,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
64
87
|
// should not collide
|
|
65
88
|
const duplicates = _.uniq(
|
|
66
|
-
|
|
67
|
-
.map(toRegressedEnumValue)
|
|
68
|
-
.filter((value, index, values) => values.indexOf(value) !== index)
|
|
89
|
+
regressedValues.filter((value, index, values) => values.indexOf(value) !== index)
|
|
69
90
|
);
|
|
70
91
|
|
|
71
92
|
if (duplicates.length) {
|
|
72
|
-
const message = `Some
|
|
93
|
+
const message = `Some enumeration values of the field '${attrName}' collide when normalized: ${duplicates.join(
|
|
73
94
|
', '
|
|
74
95
|
)}. Please modify your enumeration.`;
|
|
75
96
|
|
package/lib/global.d.ts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { Strapi as StrapiInterface } from './types/core';
|
|
2
|
+
import type { CollectionTypeSchema, SingleTypeSchema, ComponentSchema, ContentTypeSchema } from './types/core/schemas';
|
|
3
|
+
import type { KeysBy } from './types/utils';
|
|
4
|
+
|
|
5
|
+
declare global {
|
|
6
|
+
namespace Strapi {
|
|
7
|
+
/**
|
|
8
|
+
* Map of UID / schemas used as a schemas database for other types.
|
|
9
|
+
* It must be extended by the user application or plugins.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* declare global {
|
|
14
|
+
* namespace Strapi {
|
|
15
|
+
* interface Schemas {
|
|
16
|
+
* 'xxx::xxx.uid: ContentTypeSchema | ComponentSchema;
|
|
17
|
+
* }
|
|
18
|
+
* }
|
|
19
|
+
* }
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
interface Schemas {}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Literal union type of every content type registered in Strapi.Schemas
|
|
26
|
+
*/
|
|
27
|
+
type ContentTypeUIDs = KeysBy<Schemas, ContentTypeSchema>;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Literal union type of every collection type registered in Strapi.Schemas
|
|
31
|
+
*/
|
|
32
|
+
type CollectionTypeUIDs = KeysBy<Schemas, CollectionTypeSchema>;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Literal union type of every single type registered in Strapi.Schemas
|
|
36
|
+
*/
|
|
37
|
+
type SingleTypeUIDs = KeysBy<Schemas, SingleTypeSchema>;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Literal union type of every component registered in Strapi.Schemas
|
|
41
|
+
*/
|
|
42
|
+
type ComponentUIDs = KeysBy<Schemas, ComponentSchema>;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Global shorthand to access the `StrapiInterface` type
|
|
46
|
+
*/
|
|
47
|
+
type Strapi = StrapiInterface;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Strapi global variable definition
|
|
52
|
+
**/
|
|
53
|
+
export const strapi: StrapiInterface;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Adds the strapi global variable to the NodeJS Global interface
|
|
57
|
+
*/
|
|
58
|
+
export interface Global {
|
|
59
|
+
strapi: StrapiInterface;
|
|
60
|
+
}
|
|
61
|
+
}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,28 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { EntityService } from './services/entity-service';
|
|
1
|
+
import './global';
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
export * as factories from './factories';
|
|
6
|
-
|
|
7
|
-
export type { Core };
|
|
8
|
-
|
|
9
|
-
// Alias to resolve the Strapi global type easily
|
|
10
|
-
export type Strapi = Core.Strapi;
|
|
11
|
-
|
|
12
|
-
export interface StrapiInterface extends Core.Strapi {};
|
|
13
|
-
|
|
14
|
-
declare global {
|
|
15
|
-
interface AllTypes {}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
declare global {
|
|
19
|
-
export interface Global {
|
|
20
|
-
strapi: StrapiInterface;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export type Strapi = StrapiInterface;
|
|
24
|
-
|
|
25
|
-
const strapi: StrapiInterface;
|
|
26
|
-
}
|
|
3
|
+
export * from './types';
|
|
27
4
|
|
|
28
5
|
export default function(opts): Strapi;
|
package/lib/services/cron.js
CHANGED
|
@@ -5,6 +5,7 @@ const { isFunction } = require('lodash/fp');
|
|
|
5
5
|
|
|
6
6
|
const createCronService = () => {
|
|
7
7
|
let jobsSpecs = [];
|
|
8
|
+
let running = false;
|
|
8
9
|
|
|
9
10
|
return {
|
|
10
11
|
add(tasks = {}) {
|
|
@@ -29,18 +30,21 @@ const createCronService = () => {
|
|
|
29
30
|
|
|
30
31
|
const job = new Job(null, fnWithStrapi);
|
|
31
32
|
jobsSpecs.push({ job, options });
|
|
33
|
+
|
|
34
|
+
if (running) {
|
|
35
|
+
job.schedule(options);
|
|
36
|
+
}
|
|
32
37
|
}
|
|
33
38
|
return this;
|
|
34
39
|
},
|
|
35
40
|
start() {
|
|
36
|
-
if (!strapi.config.get('server.cron.enabled')) {
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
41
|
jobsSpecs.forEach(({ job, options }) => job.schedule(options));
|
|
42
|
+
running = true;
|
|
40
43
|
return this;
|
|
41
44
|
},
|
|
42
45
|
stop() {
|
|
43
46
|
jobsSpecs.forEach(({ job }) => job.cancel());
|
|
47
|
+
running = false;
|
|
44
48
|
return this;
|
|
45
49
|
},
|
|
46
50
|
destroy() {
|
|
@@ -29,7 +29,7 @@ class WebhookRunner {
|
|
|
29
29
|
|
|
30
30
|
this.config = _.merge(defaultConfiguration, configuration);
|
|
31
31
|
|
|
32
|
-
this.queue = new WorkerQueue({ logger,
|
|
32
|
+
this.queue = new WorkerQueue({ logger, concurrency: 5 });
|
|
33
33
|
this.queue.subscribe(this.executeListener.bind(this));
|
|
34
34
|
}
|
|
35
35
|
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { GetAttributeValue } from './utils';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* List of all the Strapi attribute types
|
|
5
|
+
*/
|
|
6
|
+
export type AttributeType =
|
|
7
|
+
| 'string'
|
|
8
|
+
| 'text'
|
|
9
|
+
| 'richtext'
|
|
10
|
+
| 'email'
|
|
11
|
+
| 'password'
|
|
12
|
+
| 'date'
|
|
13
|
+
| 'time'
|
|
14
|
+
| 'datetime'
|
|
15
|
+
| 'timestamp'
|
|
16
|
+
| 'integer'
|
|
17
|
+
| 'biginteger'
|
|
18
|
+
| 'float'
|
|
19
|
+
| 'decimal'
|
|
20
|
+
| 'uid'
|
|
21
|
+
| 'enumeration'
|
|
22
|
+
| 'boolean'
|
|
23
|
+
| 'json'
|
|
24
|
+
| 'media'
|
|
25
|
+
| 'relation'
|
|
26
|
+
| 'component'
|
|
27
|
+
| 'dynamiczone';
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Most basic shape of a schema attribute
|
|
31
|
+
*/
|
|
32
|
+
export interface Attribute<T extends AttributeType = AttributeType> {
|
|
33
|
+
/**
|
|
34
|
+
* Type of the attribute
|
|
35
|
+
*/
|
|
36
|
+
type: T;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Options defined and used by the plugins
|
|
40
|
+
*/
|
|
41
|
+
pluginOptions?: object;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Common attributes Options
|
|
45
|
+
|
|
46
|
+
export interface RequiredOption {
|
|
47
|
+
required?: boolean;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface PrivateOption {
|
|
51
|
+
private?: boolean;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface UniqueOption {
|
|
55
|
+
unique?: boolean;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface DefaultOption<T> {
|
|
59
|
+
default?: T;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface ConfigurableOption {
|
|
63
|
+
configurable?: boolean;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface MinMaxOption<T = number> {
|
|
67
|
+
min?: T;
|
|
68
|
+
max?: T;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface MinMaxLengthOption {
|
|
72
|
+
minLength?: number;
|
|
73
|
+
maxLength?: number;
|
|
74
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Attribute,
|
|
3
|
+
ConfigurableOption,
|
|
4
|
+
DefaultOption,
|
|
5
|
+
MinMaxOption,
|
|
6
|
+
PrivateOption,
|
|
7
|
+
RequiredOption,
|
|
8
|
+
} from './base';
|
|
9
|
+
|
|
10
|
+
export type BigIntegerAttribute = Attribute<'biginteger'> &
|
|
11
|
+
// Options
|
|
12
|
+
ConfigurableOption &
|
|
13
|
+
DefaultOption<BigIntegerValue> &
|
|
14
|
+
MinMaxOption<string> &
|
|
15
|
+
PrivateOption &
|
|
16
|
+
RequiredOption;
|
|
17
|
+
|
|
18
|
+
export type BigIntegerValue = string;
|
|
19
|
+
|
|
20
|
+
export type GetBigIntegerAttributeValue<T extends Attribute> = T extends BigIntegerAttribute
|
|
21
|
+
? BigIntegerValue
|
|
22
|
+
: never;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Attribute,
|
|
3
|
+
ConfigurableOption,
|
|
4
|
+
DefaultOption,
|
|
5
|
+
PrivateOption,
|
|
6
|
+
RequiredOption,
|
|
7
|
+
} from './base';
|
|
8
|
+
|
|
9
|
+
export type BooleanAttribute = Attribute<'boolean'> &
|
|
10
|
+
// Options
|
|
11
|
+
ConfigurableOption &
|
|
12
|
+
DefaultOption<BooleanValue> &
|
|
13
|
+
PrivateOption &
|
|
14
|
+
RequiredOption;
|
|
15
|
+
|
|
16
|
+
export type BooleanValue = boolean;
|
|
17
|
+
|
|
18
|
+
export type GetBooleanAttributeValue<T extends Attribute> = T extends BooleanAttribute
|
|
19
|
+
? BooleanValue
|
|
20
|
+
: never;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Strapi custom scalar types
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { MinMaxLengthOption, MinMaxOption } from './base';
|
|
6
|
+
import { StringAttribute } from './string';
|
|
7
|
+
|
|
8
|
+
export type JSON<T extends object = object> = T;
|
|
9
|
+
|
|
10
|
+
export type Media = any;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Setters for the attributes options
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
// required
|
|
17
|
+
export type RequiredAttribute = { required: true };
|
|
18
|
+
export type NonRequiredAttribute = { required: false };
|
|
19
|
+
|
|
20
|
+
// private
|
|
21
|
+
export type PrivateAttribute = { private: true };
|
|
22
|
+
export type NonPrivateAttribute = { private: false };
|
|
23
|
+
|
|
24
|
+
// unique
|
|
25
|
+
export type UniqueAttribute = { unique: true };
|
|
26
|
+
export type NonUniqueAttribute = { unique: false };
|
|
27
|
+
|
|
28
|
+
// configurable
|
|
29
|
+
export type ConfigurableAttribute = { configurable: true };
|
|
30
|
+
export type NonConfigurableAttribute = { configurable: false };
|
|
31
|
+
|
|
32
|
+
// min/max
|
|
33
|
+
export type SetMinMax<T extends MinMaxOption<U>, U = number> = T;
|
|
34
|
+
|
|
35
|
+
// minLength/maxLength
|
|
36
|
+
export type SetMinMaxLength<T extends MinMaxLengthOption> = T;
|
|
37
|
+
|
|
38
|
+
// pluginOptions
|
|
39
|
+
export type SetPluginOptions<T extends object = object> = { pluginOptions?: T };
|
|
40
|
+
|
|
41
|
+
// default
|
|
42
|
+
export type DefaultTo<T> = { default: T };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Attribute, ConfigurableOption, MinMaxOption, PrivateOption, RequiredOption } from './base';
|
|
2
|
+
import { GetAttributesValues } from './utils';
|
|
3
|
+
|
|
4
|
+
export interface ComponentAttributeProperties<
|
|
5
|
+
// Targeted component
|
|
6
|
+
T extends Strapi.ComponentUIDs,
|
|
7
|
+
// Repeatable
|
|
8
|
+
R extends boolean = false
|
|
9
|
+
> {
|
|
10
|
+
component: T;
|
|
11
|
+
repeatable?: R;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type ComponentAttribute<
|
|
15
|
+
// Targeted component
|
|
16
|
+
T extends Strapi.ComponentUIDs,
|
|
17
|
+
// Repeatable
|
|
18
|
+
R extends boolean = false
|
|
19
|
+
> = Attribute<'component'> &
|
|
20
|
+
// Component Properties
|
|
21
|
+
ComponentAttributeProperties<T, R> &
|
|
22
|
+
// Options
|
|
23
|
+
ConfigurableOption &
|
|
24
|
+
MinMaxOption &
|
|
25
|
+
PrivateOption &
|
|
26
|
+
RequiredOption;
|
|
27
|
+
|
|
28
|
+
export type ComponentValue<T extends Strapi.ComponentUIDs, R extends boolean> = GetAttributesValues<
|
|
29
|
+
T
|
|
30
|
+
> extends infer V
|
|
31
|
+
? R extends true
|
|
32
|
+
? V[]
|
|
33
|
+
: V
|
|
34
|
+
: never;
|
|
35
|
+
|
|
36
|
+
export type GetComponentAttributeValue<T extends Attribute> = T extends ComponentAttribute<
|
|
37
|
+
infer U,
|
|
38
|
+
infer R
|
|
39
|
+
>
|
|
40
|
+
? ComponentValue<U, R>
|
|
41
|
+
: never;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Attribute,
|
|
3
|
+
ConfigurableOption,
|
|
4
|
+
DefaultOption,
|
|
5
|
+
PrivateOption,
|
|
6
|
+
RequiredOption,
|
|
7
|
+
UniqueOption,
|
|
8
|
+
} from './base';
|
|
9
|
+
|
|
10
|
+
export type DateTimeAttribute = Attribute<'datetime'> &
|
|
11
|
+
// Options
|
|
12
|
+
ConfigurableOption &
|
|
13
|
+
DefaultOption<DateTimeValue> &
|
|
14
|
+
PrivateOption &
|
|
15
|
+
RequiredOption &
|
|
16
|
+
UniqueOption;
|
|
17
|
+
|
|
18
|
+
export type DateTimeValue = string;
|
|
19
|
+
|
|
20
|
+
export type GetDateTimeAttributeValue<T extends Attribute> = T extends DateTimeAttribute
|
|
21
|
+
? DateTimeValue
|
|
22
|
+
: never;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Attribute,
|
|
3
|
+
ConfigurableOption,
|
|
4
|
+
DefaultOption,
|
|
5
|
+
PrivateOption,
|
|
6
|
+
RequiredOption,
|
|
7
|
+
UniqueOption,
|
|
8
|
+
} from './base';
|
|
9
|
+
|
|
10
|
+
export type DateAttribute = Attribute<'date'> &
|
|
11
|
+
// Options
|
|
12
|
+
ConfigurableOption &
|
|
13
|
+
DefaultOption<DateValue> &
|
|
14
|
+
PrivateOption &
|
|
15
|
+
RequiredOption &
|
|
16
|
+
UniqueOption;
|
|
17
|
+
|
|
18
|
+
export type DateValue = Date;
|
|
19
|
+
|
|
20
|
+
export type GetDateAttributeValue<T extends Attribute> = T extends DateAttribute
|
|
21
|
+
? DateValue
|
|
22
|
+
: never;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Attribute,
|
|
3
|
+
ConfigurableOption,
|
|
4
|
+
DefaultOption,
|
|
5
|
+
MinMaxOption,
|
|
6
|
+
PrivateOption,
|
|
7
|
+
RequiredOption,
|
|
8
|
+
} from './base';
|
|
9
|
+
|
|
10
|
+
export type DecimalAttribute = Attribute<'decimal'> &
|
|
11
|
+
// Options
|
|
12
|
+
ConfigurableOption &
|
|
13
|
+
DefaultOption<DecimalValue> &
|
|
14
|
+
MinMaxOption &
|
|
15
|
+
PrivateOption &
|
|
16
|
+
RequiredOption;
|
|
17
|
+
|
|
18
|
+
export type DecimalValue = number;
|
|
19
|
+
|
|
20
|
+
export type GetDecimalAttributeValue<T extends Attribute> = T extends DecimalAttribute
|
|
21
|
+
? DecimalValue
|
|
22
|
+
: never;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { SchemaUID, GetArrayValues } from '../../utils';
|
|
2
|
+
import { Attribute, ConfigurableOption, MinMaxOption, RequiredOption } from './base';
|
|
3
|
+
import { GetAttributesValues } from './utils';
|
|
4
|
+
|
|
5
|
+
export interface DynamicZoneAttributeProperties<T extends Strapi.ComponentUIDs[] = []> {
|
|
6
|
+
components: T;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export type DynamicZoneAttribute<T extends Strapi.ComponentUIDs[] = []> = Attribute<'dynamiczone'> &
|
|
10
|
+
// Properties
|
|
11
|
+
DynamicZoneAttributeProperties<T> &
|
|
12
|
+
// Options
|
|
13
|
+
ConfigurableOption &
|
|
14
|
+
MinMaxOption &
|
|
15
|
+
RequiredOption;
|
|
16
|
+
|
|
17
|
+
type DynamicZoneValue<T extends Strapi.ComponentUIDs[]> = Array<
|
|
18
|
+
GetArrayValues<T> extends infer P
|
|
19
|
+
? P extends SchemaUID
|
|
20
|
+
? GetAttributesValues<P> & { __component: P }
|
|
21
|
+
: never
|
|
22
|
+
: never
|
|
23
|
+
>;
|
|
24
|
+
|
|
25
|
+
export type GetDynamicZoneAttributeValue<T extends Attribute> = T extends DynamicZoneAttribute<
|
|
26
|
+
infer U
|
|
27
|
+
>
|
|
28
|
+
? DynamicZoneValue<U>
|
|
29
|
+
: never;
|