@contentstack/cli-audit 1.0.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.
@@ -0,0 +1,242 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const chalk_1 = tslib_1.__importDefault(require("chalk"));
5
+ const csv = tslib_1.__importStar(require("fast-csv"));
6
+ const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
7
+ const path_1 = require("path");
8
+ const cli_utilities_1 = require("@contentstack/cli-utilities");
9
+ const fs_1 = require("fs");
10
+ const config_1 = tslib_1.__importDefault(require("../../../../config"));
11
+ const log_1 = require("../../../../util/log");
12
+ const messages_1 = require("../../../../messages");
13
+ const base_command_1 = require("../../../../base-command");
14
+ const modules_1 = require("../../../../modules");
15
+ const types_1 = require("../../../../types");
16
+ class Audit extends base_command_1.BaseCommand {
17
+ /**
18
+ * The `run` function is an asynchronous function that performs an audit on different modules
19
+ * (content-types, global-fields, entries) and generates a report.
20
+ */
21
+ async run() {
22
+ try {
23
+ await this.promptQueue();
24
+ const reportPath = this.flags['report-path'] || process.cwd();
25
+ this.sharedConfig.reportPath = (0, path_1.resolve)(reportPath, 'audit-report');
26
+ let { ctSchema, gfSchema } = this.getCtAndGfSchema();
27
+ let missingCtRefs, missingGfRefs, missingEntryRefs;
28
+ for (const module of this.sharedConfig.flags.modules || this.sharedConfig.modules) {
29
+ cli_utilities_1.ux.action.start(this.$t(this.messages.AUDIT_START_SPINNER, { module }));
30
+ switch (module) {
31
+ case 'content-types':
32
+ missingCtRefs = await new modules_1.ContentType({
33
+ ctSchema,
34
+ gfSchema,
35
+ log: this.log,
36
+ moduleName: module,
37
+ config: this.sharedConfig,
38
+ }).run();
39
+ await this.prepareReport(module, missingCtRefs);
40
+ break;
41
+ case 'global-fields':
42
+ missingGfRefs = await new modules_1.GlobalField({
43
+ ctSchema,
44
+ gfSchema,
45
+ log: this.log,
46
+ moduleName: module,
47
+ config: this.sharedConfig,
48
+ }).run();
49
+ await this.prepareReport(module, missingGfRefs);
50
+ break;
51
+ case 'entries':
52
+ missingEntryRefs = await new modules_1.Entries({
53
+ ctSchema,
54
+ gfSchema,
55
+ log: this.log,
56
+ moduleName: module,
57
+ config: this.sharedConfig,
58
+ }).run();
59
+ await this.prepareReport(module, missingEntryRefs);
60
+ break;
61
+ }
62
+ cli_utilities_1.ux.action.stop();
63
+ }
64
+ this.showOutputOnScreen([
65
+ { module: 'Content types', missingRefs: missingCtRefs },
66
+ { module: 'Global Fields', missingRefs: missingGfRefs },
67
+ { module: 'Entries', missingRefs: missingEntryRefs },
68
+ ]);
69
+ if (!(0, isEmpty_1.default)(missingCtRefs) || !(0, isEmpty_1.default)(missingGfRefs) || !(0, isEmpty_1.default)(missingEntryRefs)) {
70
+ this.log(this.$t(messages_1.auditMsg.FINAL_REPORT_PATH, { path: this.sharedConfig.reportPath }), 'warn');
71
+ }
72
+ else {
73
+ this.log(this.messages.NO_MISSING_REF_FOUND, 'info');
74
+ this.log('');
75
+ }
76
+ }
77
+ catch (error) {
78
+ this.log(error instanceof Error ? error.message : error, 'error');
79
+ console.trace(error);
80
+ cli_utilities_1.ux.action.stop('Process failed.!');
81
+ this.exit(1);
82
+ }
83
+ }
84
+ /**
85
+ * The `promptQueue` function prompts the user to enter a data directory path if the `data-dir` flag
86
+ * is missing, and sets the `basePath` property of the `sharedConfig` object to the entered path.
87
+ */
88
+ async promptQueue() {
89
+ // NOTE get content path if data-dir flag is missing
90
+ this.sharedConfig.basePath =
91
+ this.flags['data-dir'] ||
92
+ (await cli_utilities_1.cliux.inquire({
93
+ type: 'input',
94
+ name: 'data-dir',
95
+ message: this.messages.DATA_DIR,
96
+ }));
97
+ }
98
+ /**
99
+ * The function `getCtAndGfSchema` reads and parses JSON files containing content type and global
100
+ * field schemas, and returns them as an object.
101
+ * @returns The function `getCtAndGfSchema()` returns an object with two properties: `ctSchema` and
102
+ * `gfSchema`. The values of these properties are the parsed JSON data from two different files.
103
+ */
104
+ getCtAndGfSchema() {
105
+ const ctPath = (0, path_1.join)(this.sharedConfig.basePath, this.sharedConfig.moduleConfig['content-types'].dirName, this.sharedConfig.moduleConfig['content-types'].fileName);
106
+ const gfPath = (0, path_1.join)(this.sharedConfig.basePath, this.sharedConfig.moduleConfig['global-fields'].dirName, this.sharedConfig.moduleConfig['global-fields'].fileName);
107
+ let ctSchema = (0, fs_1.existsSync)(ctPath) ? JSON.parse((0, fs_1.readFileSync)(ctPath, 'utf-8')) : [];
108
+ let gfSchema = (0, fs_1.existsSync)(gfPath) ? JSON.parse((0, fs_1.readFileSync)(gfPath, 'utf-8')) : [];
109
+ return { ctSchema, gfSchema };
110
+ }
111
+ /**
112
+ * The function `showOutputOnScreen` displays missing references on the terminal screen if the
113
+ * `showTerminalOutput` flag is set to true.
114
+ * @param {{ module: string; missingRefs?: Record<string, any> }[]} allMissingRefs - An array of
115
+ * objects, where each object has two properties:
116
+ */
117
+ showOutputOnScreen(allMissingRefs) {
118
+ if (this.sharedConfig.showTerminalOutput) {
119
+ this.log(''); // NOTE adding new line
120
+ for (const { module, missingRefs } of allMissingRefs) {
121
+ if (!(0, isEmpty_1.default)(missingRefs)) {
122
+ (0, log_1.print)([
123
+ {
124
+ bold: true,
125
+ color: 'cyan',
126
+ message: ` ${module}`,
127
+ },
128
+ ]);
129
+ cli_utilities_1.ux.table(Object.values(missingRefs).flat(), {
130
+ name: {
131
+ minWidth: 7,
132
+ header: 'Title',
133
+ },
134
+ display_name: {
135
+ minWidth: 7,
136
+ header: 'Field name',
137
+ },
138
+ data_type: {
139
+ minWidth: 7,
140
+ header: 'Field type',
141
+ },
142
+ missingRefs: {
143
+ minWidth: 7,
144
+ header: 'Missing references',
145
+ get: (row) => {
146
+ return chalk_1.default.red(typeof row.missingRefs === 'object' ? JSON.stringify(row.missingRefs) : row.missingRefs);
147
+ },
148
+ },
149
+ treeStr: {
150
+ minWidth: 7,
151
+ header: 'Path',
152
+ },
153
+ }, Object.assign({}, this.flags));
154
+ this.log(''); // NOTE adding new line
155
+ }
156
+ }
157
+ }
158
+ }
159
+ /**
160
+ * The function prepares a report by writing a JSON file and a CSV file with a list of missing
161
+ * references for a given module.
162
+ * @param moduleName - The `moduleName` parameter is a string that represents the name of a module.
163
+ * It is used to generate the filename for the report.
164
+ * @param listOfMissingRefs - The `listOfMissingRefs` parameter is a record object that contains
165
+ * information about missing references. It is a key-value pair where the key represents the
166
+ * reference name and the value represents additional information about the missing reference.
167
+ * @returns The function `prepareReport` returns a Promise that resolves to `void`.
168
+ */
169
+ prepareReport(moduleName, listOfMissingRefs) {
170
+ if ((0, isEmpty_1.default)(listOfMissingRefs))
171
+ return Promise.resolve(void 0);
172
+ if (!(0, fs_1.existsSync)(this.sharedConfig.reportPath)) {
173
+ (0, fs_1.mkdirSync)(this.sharedConfig.reportPath, { recursive: true });
174
+ }
175
+ // NOTE write int json
176
+ (0, fs_1.writeFileSync)((0, path_1.join)(this.sharedConfig.reportPath, `${moduleName}.json`), JSON.stringify(listOfMissingRefs));
177
+ // NOTE write into CSV
178
+ return this.prepareCSV(moduleName, listOfMissingRefs);
179
+ }
180
+ /**
181
+ * The function `prepareCSV` takes a module name and a list of missing references, and generates a
182
+ * CSV file with the specified columns and filtered rows.
183
+ * @param moduleName - The `moduleName` parameter is a string that represents the name of a module.
184
+ * It is used to generate the name of the CSV file that will be created.
185
+ * @param listOfMissingRefs - The `listOfMissingRefs` parameter is a record object that contains
186
+ * information about missing references. Each key in the record represents a reference, and the
187
+ * corresponding value is an array of objects that contain details about the missing reference.
188
+ * @returns The function `prepareCSV` returns a Promise that resolves to `void`.
189
+ */
190
+ prepareCSV(moduleName, listOfMissingRefs) {
191
+ const csvStream = csv.format({ headers: true });
192
+ const csvPath = (0, path_1.join)(this.sharedConfig.reportPath, `${moduleName}.csv`);
193
+ const assetFileStream = (0, fs_1.createWriteStream)(csvPath);
194
+ assetFileStream.on('error', (error) => {
195
+ throw error;
196
+ });
197
+ return new Promise((resolve, reject) => {
198
+ csvStream.pipe(assetFileStream).on('close', resolve).on('error', reject);
199
+ const defaultColumns = Object.keys(types_1.OutputColumn);
200
+ const userDefinedColumns = this.sharedConfig.flags.columns ? this.sharedConfig.flags.columns.split(',') : null;
201
+ let missingRefs = Object.values(listOfMissingRefs).flat();
202
+ const columns = userDefinedColumns
203
+ ? [...userDefinedColumns, ...defaultColumns.filter((val) => !userDefinedColumns.includes(val))]
204
+ : defaultColumns;
205
+ if (this.sharedConfig.flags.filter) {
206
+ const [column, value] = this.sharedConfig.flags.filter.split('=');
207
+ missingRefs = missingRefs.filter((row) => row[types_1.OutputColumn[column]] === value);
208
+ }
209
+ for (const issue of missingRefs) {
210
+ let row = {};
211
+ for (const column of columns) {
212
+ row[column] = issue[types_1.OutputColumn[column]];
213
+ row[column] = typeof row[column] === 'object' ? JSON.stringify(row[column]) : row[column];
214
+ }
215
+ csvStream.write(row);
216
+ }
217
+ csvStream.end();
218
+ });
219
+ }
220
+ }
221
+ exports.default = Audit;
222
+ Audit.aliases = ['cm:stacks:audit'];
223
+ Audit.description = 'Perform audits and find possible errors in the exported Contentstack data';
224
+ Audit.examples = [
225
+ '$ <%= config.bin %> <%= command.id %>',
226
+ '$ <%= config.bin %> <%= command.id %> --report-path=<path>',
227
+ '$ <%= config.bin %> <%= command.id %> --report-path=<path> --csv',
228
+ '$ <%= config.bin %> <%= command.id %> --report-path=<path> --filter="name=<filter-value>"',
229
+ '$ <%= config.bin %> <%= command.id %> --report-path=<path> --modules=content-types --filter="name="<filter-value>"',
230
+ ];
231
+ Audit.flags = Object.assign({ 'report-path': cli_utilities_1.Flags.string({
232
+ description: messages_1.auditMsg.REPORT_PATH,
233
+ }), 'reference-only': cli_utilities_1.Flags.boolean({
234
+ hidden: true,
235
+ description: messages_1.auditMsg.REFERENCE_ONLY,
236
+ }), modules: cli_utilities_1.Flags.string({
237
+ multiple: true,
238
+ options: config_1.default.modules,
239
+ description: messages_1.auditMsg.MODULES,
240
+ }) }, cli_utilities_1.ux.table.flags({
241
+ only: ['columns', 'sort', 'filter', 'csv', 'no-truncate'],
242
+ }));
@@ -0,0 +1,28 @@
1
+ declare const config: {
2
+ showTerminalOutput: boolean;
3
+ skipRefs: string[];
4
+ modules: string[];
5
+ moduleConfig: {
6
+ 'content-types': {
7
+ name: string;
8
+ fileName: string;
9
+ dirName: string;
10
+ };
11
+ 'global-fields': {
12
+ name: string;
13
+ dirName: string;
14
+ fileName: string;
15
+ };
16
+ entries: {
17
+ name: string;
18
+ dirName: string;
19
+ fileName: string;
20
+ };
21
+ locales: {
22
+ name: string;
23
+ dirName: string;
24
+ fileName: string;
25
+ };
26
+ };
27
+ };
28
+ export default config;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const config = {
4
+ showTerminalOutput: true,
5
+ skipRefs: ['sys_assets'],
6
+ modules: ['content-types', 'global-fields', 'entries'],
7
+ moduleConfig: {
8
+ 'content-types': {
9
+ name: 'content type',
10
+ fileName: 'schema.json',
11
+ dirName: 'content_types',
12
+ },
13
+ 'global-fields': {
14
+ name: 'global field',
15
+ dirName: 'global_fields',
16
+ fileName: 'globalfields.json',
17
+ },
18
+ entries: {
19
+ name: 'entries',
20
+ dirName: 'entries',
21
+ fileName: 'entries.json',
22
+ },
23
+ locales: {
24
+ name: 'locales',
25
+ dirName: 'locales',
26
+ fileName: 'locales.json',
27
+ },
28
+ },
29
+ };
30
+ exports.default = config;
package/lib/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ declare const _default: {};
2
+ export default _default;
package/lib/index.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = {};
@@ -0,0 +1,33 @@
1
+ declare const errors: {
2
+ NOT_EMPTY: string;
3
+ };
4
+ declare const commonMsg: {
5
+ CONFIG: string;
6
+ CURRENT_WORKING_DIR: string;
7
+ DATA_DIR: string;
8
+ };
9
+ declare const auditMsg: {
10
+ REPORT_PATH: string;
11
+ MODULES: string;
12
+ AUDIT_START_SPINNER: string;
13
+ PREPARING_ENTRY_METADATA: string;
14
+ REFERENCE_ONLY: string;
15
+ NOT_VALID_PATH: string;
16
+ NO_MISSING_REF_FOUND: string;
17
+ FINAL_REPORT_PATH: string;
18
+ SCAN_CT_SUCCESS_MSG: string;
19
+ SCAN_ENTRY_SUCCESS_MSG: string;
20
+ };
21
+ declare const messages: typeof errors & typeof commonMsg & typeof auditMsg;
22
+ /**
23
+ * The function `$t` is a TypeScript function that replaces placeholders in a string with corresponding
24
+ * values from an object.
25
+ * @param {string} msg - The `msg` parameter is a string that represents a message or a template with
26
+ * placeholders. These placeholders are enclosed in curly braces, such as `{key}`.
27
+ * @param args - The `args` parameter is an object that contains key-value pairs. The keys represent
28
+ * placeholders in the `msg` string, and the values are the replacements for those placeholders.
29
+ * @returns a string.
30
+ */
31
+ declare function $t(msg: string, args: Record<string, string>): string;
32
+ export default messages;
33
+ export { $t, errors, commonMsg, auditMsg };
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.auditMsg = exports.commonMsg = exports.errors = exports.$t = void 0;
4
+ const errors = {
5
+ NOT_EMPTY: '{value} cannot be empty.',
6
+ };
7
+ exports.errors = errors;
8
+ const commonMsg = {
9
+ CONFIG: 'Path of the external config.',
10
+ CURRENT_WORKING_DIR: 'Current working directory.',
11
+ DATA_DIR: 'Path where the data is stored.',
12
+ };
13
+ exports.commonMsg = commonMsg;
14
+ const auditMsg = {
15
+ REPORT_PATH: 'Path to store the audit reports.',
16
+ MODULES: 'Provide the list of modules to be audited.',
17
+ AUDIT_START_SPINNER: '{module} scanning...',
18
+ PREPARING_ENTRY_METADATA: 'Creating entry metadata...',
19
+ REFERENCE_ONLY: 'Checks only for missing references.',
20
+ NOT_VALID_PATH: "Provided path '{path}' is not valid.",
21
+ NO_MISSING_REF_FOUND: 'No missing references found.',
22
+ FINAL_REPORT_PATH: "Reports ready. Please find the reports at '{path}'.",
23
+ SCAN_CT_SUCCESS_MSG: "Successfully completed the scanning of {module} '{title}'.",
24
+ SCAN_ENTRY_SUCCESS_MSG: "Successfully completed the scanning of {module} ({local}) '{title}'.",
25
+ };
26
+ exports.auditMsg = auditMsg;
27
+ const messages = Object.assign(Object.assign(Object.assign({}, errors), commonMsg), auditMsg);
28
+ /**
29
+ * The function `$t` is a TypeScript function that replaces placeholders in a string with corresponding
30
+ * values from an object.
31
+ * @param {string} msg - The `msg` parameter is a string that represents a message or a template with
32
+ * placeholders. These placeholders are enclosed in curly braces, such as `{key}`.
33
+ * @param args - The `args` parameter is an object that contains key-value pairs. The keys represent
34
+ * placeholders in the `msg` string, and the values are the replacements for those placeholders.
35
+ * @returns a string.
36
+ */
37
+ function $t(msg, args) {
38
+ if (!msg)
39
+ return '';
40
+ for (const key of Object.keys(args)) {
41
+ msg = msg.replace(new RegExp(`{${key}}`, 'g'), args[key]);
42
+ }
43
+ return msg;
44
+ }
45
+ exports.$t = $t;
46
+ exports.default = messages;
@@ -0,0 +1,96 @@
1
+ import { LogFn, ConfigType, ModularBlockType, ContentTypeStruct, GroupFieldDataType, RefErrorReturnType, CtConstructorParam, GlobalFieldDataType, JsonRTEFieldDataType, ModularBlocksDataType, ModuleConstructorParam, ReferenceFieldDataType } from '../types';
2
+ import auditConfig from '../config';
3
+ export default class ContentType {
4
+ log: LogFn;
5
+ fileName: string;
6
+ config: ConfigType;
7
+ folderPath: string;
8
+ currentUid: string;
9
+ currentTitle: string;
10
+ gfSchema: ContentTypeStruct[];
11
+ ctSchema: ContentTypeStruct[];
12
+ protected schema: ContentTypeStruct[];
13
+ protected missingRefs: Record<string, any>;
14
+ moduleName: keyof typeof auditConfig.moduleConfig;
15
+ constructor({ log, config, moduleName, ctSchema, gfSchema }: ModuleConstructorParam & CtConstructorParam);
16
+ /**
17
+ * The `run` function checks if a folder path exists, sets the schema based on the module name,
18
+ * iterates over the schema and looks for references, and returns a list of missing references.
19
+ * @returns the `missingRefs` object.
20
+ */
21
+ run(): Promise<Record<string, any>>;
22
+ /**
23
+ * The function `lookForReference` iterates through a given schema and performs validation checks
24
+ * based on the data type of each field.
25
+ * @param {Record<string, unknown>[]} tree - An array of objects representing the tree structure of
26
+ * the content type or field being validated. Each object in the array should have a "uid" property
27
+ * representing the unique identifier of the content type or field, and a "name" property
28
+ * representing the display name of the content type or field.
29
+ * @param {ContentTypeStruct | GlobalFieldDataType | ModularBlockType | GroupFieldDataType} - -
30
+ * `tree`: An array of objects representing the tree structure of the content type or field. Each
31
+ * object in the array should have a `uid` and `name` property.
32
+ */
33
+ lookForReference(tree: Record<string, unknown>[], { schema }: ContentTypeStruct | GlobalFieldDataType | ModularBlockType | GroupFieldDataType): Promise<void>;
34
+ /**
35
+ * The function validates a reference field in a tree data structure.
36
+ * @param {Record<string, unknown>[]} tree - The "tree" parameter is an array of objects, where each
37
+ * object represents a node in a tree-like structure. Each object can have multiple properties, and
38
+ * the structure of the tree is defined by the relationships between these properties.
39
+ * @param {ReferenceFieldDataType} field - The `field` parameter is of type `ReferenceFieldDataType`.
40
+ * @returns an array of RefErrorReturnType.
41
+ */
42
+ validateReferenceField(tree: Record<string, unknown>[], field: ReferenceFieldDataType): RefErrorReturnType[];
43
+ /**
44
+ * The function "validateGlobalField" asynchronously validates a global field by looking for a
45
+ * reference in a tree data structure.
46
+ * @param {Record<string, unknown>[]} tree - The `tree` parameter is an array of objects. Each object
47
+ * represents a node in a tree structure. The tree structure can be represented as a hierarchical
48
+ * structure where each object can have child nodes.
49
+ * @param {GlobalFieldDataType} field - The `field` parameter is of type `GlobalFieldDataType`. It
50
+ * represents the field that needs to be validated.
51
+ */
52
+ validateGlobalField(tree: Record<string, unknown>[], field: GlobalFieldDataType): Promise<void>;
53
+ /**
54
+ * The function validates the reference to values in a JSON RTE field.
55
+ * @param {Record<string, unknown>[]} tree - The "tree" parameter is an array of objects where each
56
+ * object represents a node in a tree-like structure. Each object can have multiple key-value pairs,
57
+ * where the key is a string and the value can be of any type.
58
+ * @param {JsonRTEFieldDataType} field - The `field` parameter is of type `JsonRTEFieldDataType`.
59
+ * @returns The function `validateJsonRTEFields` is returning an array of `RefErrorReturnType`
60
+ * objects.
61
+ */
62
+ validateJsonRTEFields(tree: Record<string, unknown>[], field: JsonRTEFieldDataType): RefErrorReturnType[];
63
+ /**
64
+ * The function validates the modular blocks field by traversing each module and looking for
65
+ * references.
66
+ * @param {Record<string, unknown>[]} tree - An array of objects representing the tree structure of
67
+ * the modular blocks. Each object in the array represents a node in the tree and contains properties
68
+ * like "uid" and "name".
69
+ * @param {ModularBlocksDataType} field - The `field` parameter is of type `ModularBlocksDataType`.
70
+ * It represents a modular blocks field and contains an array of blocks. Each block has properties
71
+ * like `uid` and `title`.
72
+ */
73
+ validateModularBlocksField(tree: Record<string, unknown>[], field: ModularBlocksDataType): Promise<void>;
74
+ /**
75
+ * The function `validateGroupField` is an asynchronous function that validates a group field by
76
+ * looking for a reference in a tree data structure.
77
+ * @param {Record<string, unknown>[]} tree - The `tree` parameter is an array of objects that
78
+ * represents a tree structure. Each object in the array represents a node in the tree, and it
79
+ * contains key-value pairs where the keys are field names and the values are the corresponding field
80
+ * values.
81
+ * @param {GroupFieldDataType} field - The `field` parameter is of type `GroupFieldDataType`. It
82
+ * represents the group field that needs to be validated.
83
+ */
84
+ validateGroupField(tree: Record<string, unknown>[], field: GroupFieldDataType): Promise<void>;
85
+ /**
86
+ * The function `validateReferenceToValues` checks if all the references specified in a field exist
87
+ * in a given tree of records and returns any missing references.
88
+ * @param {Record<string, unknown>[]} tree - An array of objects representing a tree structure. Each
89
+ * object in the array should have a "name" property.
90
+ * @param {ReferenceFieldDataType | JsonRTEFieldDataType} field - The `field` parameter is an object
91
+ * that represents a reference field in a content type. It has the following properties:
92
+ * @returns The function `validateReferenceToValues` returns an array of `RefErrorReturnType`
93
+ * objects.
94
+ */
95
+ validateReferenceToValues(tree: Record<string, unknown>[], field: ReferenceFieldDataType | JsonRTEFieldDataType): RefErrorReturnType[];
96
+ }