@stackbit/sdk 0.3.4 → 0.3.6
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/dist/config/config-loader-static.js +1 -1
- package/dist/config/config-loader-static.js.map +1 -1
- package/dist/config/config-loader-utils.d.ts +12 -7
- package/dist/config/config-loader-utils.d.ts.map +1 -1
- package/dist/config/config-loader-utils.js +104 -68
- package/dist/config/config-loader-utils.js.map +1 -1
- package/dist/config/config-loader.d.ts +46 -27
- package/dist/config/config-loader.d.ts.map +1 -1
- package/dist/config/config-loader.js +294 -265
- package/dist/config/config-loader.js.map +1 -1
- package/dist/config/config-schema.d.ts +2 -2
- package/dist/config/config-schema.d.ts.map +1 -1
- package/dist/config/config-schema.js +123 -55
- package/dist/config/config-schema.js.map +1 -1
- package/dist/config/config-types.d.ts +4 -3
- package/dist/config/config-types.d.ts.map +1 -1
- package/dist/config/config-validator.d.ts +9 -5
- package/dist/config/config-validator.d.ts.map +1 -1
- package/dist/config/config-validator.js +42 -23
- package/dist/config/config-validator.js.map +1 -1
- package/dist/config/presets-loader.d.ts +13 -4
- package/dist/config/presets-loader.d.ts.map +1 -1
- package/dist/config/presets-loader.js +49 -23
- package/dist/config/presets-loader.js.map +1 -1
- package/dist/content/content-schema.js +1 -1
- package/dist/content/content-schema.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -2
- package/dist/index.js.map +1 -1
- package/dist/utils/index.d.ts +1 -8
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/model-extender.js +1 -1
- package/dist/utils/model-extender.js.map +1 -1
- package/dist/utils/model-iterators.d.ts +3 -2
- package/dist/utils/model-iterators.d.ts.map +1 -1
- package/dist/utils/model-iterators.js.map +1 -1
- package/dist/utils/model-utils.d.ts +9 -8
- package/dist/utils/model-utils.d.ts.map +1 -1
- package/dist/utils/model-utils.js +26 -9
- package/dist/utils/model-utils.js.map +1 -1
- package/package.json +3 -3
- package/src/config/config-loader-static.ts +1 -1
- package/src/config/config-loader-utils.ts +111 -78
- package/src/config/config-loader.ts +457 -394
- package/src/config/config-schema.ts +150 -81
- package/src/config/config-types.ts +6 -3
- package/src/config/config-validator.ts +51 -29
- package/src/config/presets-loader.ts +59 -30
- package/src/content/content-schema.ts +1 -1
- package/src/index.ts +21 -2
- package/src/utils/index.ts +1 -13
- package/src/utils/model-extender.ts +1 -1
- package/src/utils/model-iterators.ts +6 -5
- package/src/utils/model-utils.ts +38 -16
|
@@ -2,15 +2,11 @@ import _ from 'lodash';
|
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import fse from 'fs-extra';
|
|
4
4
|
import { parseFile, append } from '@stackbit/utils';
|
|
5
|
+
import { ModelWithSource } from '@stackbit/types';
|
|
5
6
|
|
|
6
|
-
import { Config, Preset } from './config-types';
|
|
7
|
+
import { Config, Model, Preset } from './config-types';
|
|
7
8
|
import { ConfigPresetsError } from './config-errors';
|
|
8
9
|
|
|
9
|
-
export interface PresetsLoaderResult {
|
|
10
|
-
config: Config;
|
|
11
|
-
errors: ConfigPresetsError[];
|
|
12
|
-
}
|
|
13
|
-
|
|
14
10
|
interface RawPresetData {
|
|
15
11
|
model: string;
|
|
16
12
|
srcType: string;
|
|
@@ -24,16 +20,23 @@ interface RawPreset {
|
|
|
24
20
|
data: Record<string, any>;
|
|
25
21
|
}
|
|
26
22
|
|
|
27
|
-
export async function loadPresets(
|
|
23
|
+
export async function loadPresets({
|
|
24
|
+
config,
|
|
25
|
+
fallbackSrcType,
|
|
26
|
+
fallbackSrcProjectId
|
|
27
|
+
}: {
|
|
28
|
+
config: Config;
|
|
29
|
+
fallbackSrcType?: string;
|
|
30
|
+
fallbackSrcProjectId?: string;
|
|
31
|
+
}): Promise<{
|
|
32
|
+
presets: Record<string, Preset>;
|
|
33
|
+
errors: ConfigPresetsError[];
|
|
34
|
+
}> {
|
|
28
35
|
const presetFiles = [];
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if (config.presetSource?.type === 'files' && config.presetSource?.presetDirs) {
|
|
32
|
-
presetsRelDirs = [...new Set([...presetsRelDirs, ...config.presetSource.presetDirs])];
|
|
33
|
-
}
|
|
36
|
+
const presetsRelDirs = getPresetDirs(config);
|
|
34
37
|
|
|
35
38
|
for (const presetsRelDir of presetsRelDirs) {
|
|
36
|
-
const presetsDir = path.join(dirPath, presetsRelDir);
|
|
39
|
+
const presetsDir = path.join(config.dirPath, presetsRelDir);
|
|
37
40
|
if (!(await fse.pathExists(presetsDir))) {
|
|
38
41
|
continue;
|
|
39
42
|
}
|
|
@@ -44,12 +47,11 @@ export async function loadPresets(dirPath: string, config: Config): Promise<Pres
|
|
|
44
47
|
}
|
|
45
48
|
|
|
46
49
|
const presets: Record<string, Preset> = {};
|
|
47
|
-
const presetsIdsByModel: Record<string, string[]> = {};
|
|
48
50
|
const errors: ConfigPresetsError[] = [];
|
|
49
51
|
|
|
50
52
|
for (const presetFile of presetFiles) {
|
|
51
53
|
const presetsRelDir = path.dirname(presetFile);
|
|
52
|
-
const presetPath = path.join(dirPath, presetFile);
|
|
54
|
+
const presetPath = path.join(config.dirPath, presetFile);
|
|
53
55
|
let presetData: RawPresetData;
|
|
54
56
|
try {
|
|
55
57
|
presetData = await parseFile(presetPath);
|
|
@@ -57,6 +59,8 @@ export async function loadPresets(dirPath: string, config: Config): Promise<Pres
|
|
|
57
59
|
errors.push(new ConfigPresetsError(`Error parsing ${presetFile} (${err?.message})`));
|
|
58
60
|
continue;
|
|
59
61
|
}
|
|
62
|
+
const srcType = presetData.srcType ?? fallbackSrcType;
|
|
63
|
+
const srcProjectId = presetData.srcProjectId ?? fallbackSrcProjectId;
|
|
60
64
|
_.forEach(_.get(presetData, 'presets', []), (preset, i) => {
|
|
61
65
|
const presetId = `${presetFile}:presets[${i}]`;
|
|
62
66
|
const { thumbnail, ...rest } = preset;
|
|
@@ -64,29 +68,54 @@ export async function loadPresets(dirPath: string, config: Config): Promise<Pres
|
|
|
64
68
|
...rest,
|
|
65
69
|
...(thumbnail ? { thumbnail: resolveThumbnailPath(thumbnail, presetsRelDir) } : null),
|
|
66
70
|
modelName: presetData.model,
|
|
67
|
-
srcType:
|
|
68
|
-
srcProjectId:
|
|
69
|
-
};
|
|
70
|
-
append(presetsIdsByModel, presetData.model, presetId);
|
|
71
|
+
...(srcType ? { srcType } : null),
|
|
72
|
+
...(srcProjectId ? { srcProjectId } : null),
|
|
73
|
+
} as Preset;
|
|
71
74
|
});
|
|
72
75
|
}
|
|
73
76
|
|
|
77
|
+
return {
|
|
78
|
+
presets,
|
|
79
|
+
errors
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function getPresetDirs(config: Config): string[] {
|
|
84
|
+
const defaultPresetsDirs = ['.stackbit/presets', 'node_modules/@stackbit/components/presets'];
|
|
85
|
+
if (config.presetSource?.type === 'files' && config.presetSource?.presetDirs) {
|
|
86
|
+
return [...new Set([...defaultPresetsDirs, ...config.presetSource.presetDirs])];
|
|
87
|
+
}
|
|
88
|
+
return defaultPresetsDirs;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function extendModelsWithPresetsIds<T extends Model | ModelWithSource>({ models, presets }: { models: T[]; presets: Record<string, Preset> }): T[] {
|
|
92
|
+
// for older projects that pass the Model, we assume that all presets belong to the same content-source
|
|
93
|
+
const presetsIdsByContentSourceAndModel: Record<string, Record<string, Record<string, string[]>>> = {};
|
|
94
|
+
const presetsIdsByModel_deprecated: Record<string, string[]> = {};
|
|
95
|
+
for (const [presetId, preset] of Object.entries(presets)) {
|
|
96
|
+
append(presetsIdsByContentSourceAndModel, [preset.srcType, preset.srcProjectId, preset.modelName], presetId);
|
|
97
|
+
append(presetsIdsByModel_deprecated, preset.modelName, presetId);
|
|
98
|
+
}
|
|
99
|
+
|
|
74
100
|
// update models with presets IDs
|
|
75
|
-
|
|
76
|
-
|
|
101
|
+
return models.map((model) => {
|
|
102
|
+
let presetIdsForModel: string[] | undefined;
|
|
103
|
+
if ('srcType' in model && 'srcProjectId' in model) {
|
|
104
|
+
// "as" can be removed in typescript 4.3.5 and above
|
|
105
|
+
const srcType = (model as ModelWithSource).srcType;
|
|
106
|
+
const srcProjectId = (model as ModelWithSource).srcProjectId;
|
|
107
|
+
presetIdsForModel = presetsIdsByContentSourceAndModel[srcType]?.[srcProjectId]?.[model.name];
|
|
108
|
+
} else {
|
|
109
|
+
presetIdsForModel = presetsIdsByModel_deprecated[model.name];
|
|
110
|
+
}
|
|
77
111
|
if (!presetIdsForModel) {
|
|
78
112
|
return model;
|
|
79
113
|
}
|
|
80
|
-
return {
|
|
114
|
+
return {
|
|
115
|
+
...model,
|
|
116
|
+
presets: presetIdsForModel
|
|
117
|
+
};
|
|
81
118
|
});
|
|
82
|
-
|
|
83
|
-
return {
|
|
84
|
-
config: Object.assign({}, config, {
|
|
85
|
-
models,
|
|
86
|
-
presets
|
|
87
|
-
}),
|
|
88
|
-
errors
|
|
89
|
-
};
|
|
90
119
|
}
|
|
91
120
|
|
|
92
121
|
function resolveThumbnailPath(thumbnail: string, dir: string) {
|
|
@@ -37,7 +37,7 @@ export function joiSchemasForModels(config: Config) {
|
|
|
37
37
|
config.models,
|
|
38
38
|
(modelSchemas: ModelSchemaMap, model: Model) => {
|
|
39
39
|
let joiSchema: Joi.ObjectSchema;
|
|
40
|
-
if (model.
|
|
40
|
+
if (model.__metadata?.invalid) {
|
|
41
41
|
// if root model is invalid, replace the label with "file" otherwise joi outputs "value" which is not descriptive
|
|
42
42
|
let objectLabel = '{{#label}}';
|
|
43
43
|
if (isDataModel(model) || isPageModel(model)) {
|
package/src/index.ts
CHANGED
|
@@ -6,8 +6,27 @@ export * from './config/config-errors';
|
|
|
6
6
|
export * from './analyzer/file-browser';
|
|
7
7
|
export * from './utils';
|
|
8
8
|
export * from './config/config-loader-static';
|
|
9
|
-
export {
|
|
10
|
-
export {
|
|
9
|
+
export { loadPresets, getPresetDirs, extendModelsWithPresetsIds } from './config/presets-loader';
|
|
10
|
+
export {
|
|
11
|
+
RawConfigWithPaths,
|
|
12
|
+
StopConfigWatch,
|
|
13
|
+
findStackbitConfigFile,
|
|
14
|
+
isStackbitYamlFile,
|
|
15
|
+
convertToYamlConfig,
|
|
16
|
+
getYamlModelDirs,
|
|
17
|
+
loadYamlModelsFromFiles,
|
|
18
|
+
mergeConfigModelsWithModelsFromFiles
|
|
19
|
+
} from './config/config-loader-utils';
|
|
20
|
+
export {
|
|
21
|
+
loadConfig,
|
|
22
|
+
LoadConfigResult,
|
|
23
|
+
loadConfigWithModelsPresetsAndValidate,
|
|
24
|
+
ConfigWithModelsPresetsResult,
|
|
25
|
+
loadConfigFromDir,
|
|
26
|
+
RawConfigLoaderResult,
|
|
27
|
+
mergeConfigModelsWithExternalModels
|
|
28
|
+
} from './config/config-loader';
|
|
29
|
+
export { validateConfig } from './config/config-validator';
|
|
11
30
|
export { writeConfig, WriteConfigOptions } from './config/config-writer';
|
|
12
31
|
export { loadContent, ContentItem, ContentLoaderOptions, ContentLoaderResult } from './content/content-loader';
|
|
13
32
|
export { matchSSG, SSGMatcherOptions, SSGMatchResult } from './analyzer/ssg-matcher';
|
package/src/utils/index.ts
CHANGED
|
@@ -1,16 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
type ForbiddenPropertiesOfUnionMember<T, Union, Keys extends string = UnionKeys<Union> extends string ? UnionKeys<Union> : never> = {
|
|
4
|
-
[k in Exclude<Keys, keyof T>]?: undefined;
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
type StricterUnionMember<T, Union, Keys extends string = UnionKeys<Union> extends string ? UnionKeys<Union> : never> = T &
|
|
8
|
-
ForbiddenPropertiesOfUnionMember<T, Union, Keys>;
|
|
9
|
-
|
|
10
|
-
export type StricterUnion<Union, Union2 = Union> = Union2 extends any ? StricterUnionMember<Union2, Union> : never;
|
|
11
|
-
|
|
12
|
-
export type Logger = Pick<Console, 'debug' | 'info' | 'warn' | 'error'>;
|
|
13
|
-
|
|
1
|
+
export { Logger } from '@stackbit/types';
|
|
14
2
|
export * from './model-utils';
|
|
15
3
|
export * from './model-matcher';
|
|
16
4
|
export * from './model-extender';
|
|
@@ -95,7 +95,7 @@ function extendModel<T extends Model | YamlModel>(
|
|
|
95
95
|
copyIfNotSet(extendedSuperModel, 'singleInstance', model, 'singleInstance');
|
|
96
96
|
copyIfNotSet(extendedSuperModel, 'labelField', model, 'labelField');
|
|
97
97
|
copyIfNotSet(extendedSuperModel, 'variantField', model, 'variantField');
|
|
98
|
-
if (
|
|
98
|
+
if (Array.isArray(extendedSuperModel.fieldGroups) && extendedSuperModel.fieldGroups.length > 0) {
|
|
99
99
|
_.set(model, 'fieldGroups', _.uniqBy(_.concat(extendedSuperModel.fieldGroups, _.get(model, 'fieldGroups', [])), 'name'));
|
|
100
100
|
}
|
|
101
101
|
let idx = 0;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import _ from 'lodash';
|
|
2
|
-
|
|
3
2
|
import { mapPromise, mapValuesPromise } from '@stackbit/utils';
|
|
3
|
+
import { Field, FieldList, FieldListItems, FieldModelProps, FieldObjectProps } from '@stackbit/types';
|
|
4
|
+
|
|
4
5
|
import { getListFieldItems, isListDataModel, isListField, isObjectListItems, isModelField, isObjectField, isModelListItems } from './model-utils';
|
|
5
|
-
import { Model, YamlModel, DataModel
|
|
6
|
+
import { Model, YamlModel, DataModel } from '../config/config-types';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* This function invokes the `iteratee` function for every field of the `model`.
|
|
@@ -76,7 +77,7 @@ export function iterateModelFieldsRecursively(model: Model | YamlModel, iteratee
|
|
|
76
77
|
}
|
|
77
78
|
}
|
|
78
79
|
|
|
79
|
-
export function mapModelFieldsRecursively(model:
|
|
80
|
+
export function mapModelFieldsRecursively<T extends Model>(model: T, iteratee: (field: Field, modelKeyPath: string[]) => Field): T {
|
|
80
81
|
function _mapField(field: Field, modelKeyPath: string[]): Field {
|
|
81
82
|
if (!field) {
|
|
82
83
|
return field;
|
|
@@ -92,7 +93,7 @@ export function mapModelFieldsRecursively(model: Model, iteratee: (field: Field,
|
|
|
92
93
|
}
|
|
93
94
|
}
|
|
94
95
|
|
|
95
|
-
function _mapObjectField<
|
|
96
|
+
function _mapObjectField<Y extends FieldObjectProps | T>(field: Y, modelKeyPath: string[]): Y {
|
|
96
97
|
const fields = field.fields;
|
|
97
98
|
if (!fields) {
|
|
98
99
|
return field;
|
|
@@ -104,7 +105,7 @@ export function mapModelFieldsRecursively(model: Model, iteratee: (field: Field,
|
|
|
104
105
|
};
|
|
105
106
|
}
|
|
106
107
|
|
|
107
|
-
function _mapListField<
|
|
108
|
+
function _mapListField<Y extends FieldList | (T & { type: 'data'; isList: true })>(field: Y, modelKeyPath: string[]): Y {
|
|
108
109
|
const items = field.items;
|
|
109
110
|
if (!items || !isObjectListItems(items)) {
|
|
110
111
|
return field;
|
package/src/utils/model-utils.ts
CHANGED
|
@@ -7,14 +7,15 @@ import {
|
|
|
7
7
|
DataModel,
|
|
8
8
|
PageModel,
|
|
9
9
|
ConfigModel,
|
|
10
|
-
ImageModel,
|
|
11
10
|
YamlModel,
|
|
12
11
|
YamlObjectModel,
|
|
13
12
|
YamlPageModel,
|
|
14
13
|
YamlDataModel,
|
|
15
14
|
YamlDataModelList,
|
|
16
15
|
Field,
|
|
16
|
+
FieldSpecificProps,
|
|
17
17
|
FieldEnum,
|
|
18
|
+
FieldEnumProps,
|
|
18
19
|
FieldList,
|
|
19
20
|
FieldListItems,
|
|
20
21
|
FieldListModel,
|
|
@@ -26,7 +27,8 @@ import {
|
|
|
26
27
|
FieldObjectProps,
|
|
27
28
|
FieldReference,
|
|
28
29
|
FieldReferenceProps,
|
|
29
|
-
DataModelList
|
|
30
|
+
DataModelList,
|
|
31
|
+
FieldListProps
|
|
30
32
|
} from '../config/config-types';
|
|
31
33
|
|
|
32
34
|
export function getModelByName(models: Model[], modelName: string): Model | undefined {
|
|
@@ -53,10 +55,6 @@ export function isObjectModel(model: Model | YamlModel): model is ObjectModel |
|
|
|
53
55
|
return model.type === 'object';
|
|
54
56
|
}
|
|
55
57
|
|
|
56
|
-
export function isImageModel(model: Model): model is ImageModel {
|
|
57
|
-
return model.type === 'image';
|
|
58
|
-
}
|
|
59
|
-
|
|
60
58
|
export function isSingleInstanceModel(model: Model | YamlModel): boolean {
|
|
61
59
|
if (model.type === 'config') {
|
|
62
60
|
return true;
|
|
@@ -68,24 +66,24 @@ export function isSingleInstanceModel(model: Model | YamlModel): boolean {
|
|
|
68
66
|
return false;
|
|
69
67
|
}
|
|
70
68
|
|
|
71
|
-
export function isObjectField(field:
|
|
69
|
+
export function isObjectField(field: FieldSpecificProps): field is FieldObjectProps {
|
|
72
70
|
return field.type === 'object';
|
|
73
71
|
}
|
|
74
72
|
|
|
75
|
-
export function isModelField(field:
|
|
73
|
+
export function isModelField(field: FieldSpecificProps): field is FieldModelProps {
|
|
76
74
|
return field.type === 'model';
|
|
77
75
|
}
|
|
78
76
|
|
|
79
|
-
export function isReferenceField(field:
|
|
77
|
+
export function isReferenceField(field: FieldSpecificProps): field is FieldReferenceProps {
|
|
80
78
|
return field.type === 'reference';
|
|
81
79
|
}
|
|
82
80
|
|
|
83
|
-
export function isCustomModelField(field:
|
|
81
|
+
export function isCustomModelField(field: FieldSpecificProps, modelsByName: Record<string, Model>) {
|
|
84
82
|
// custom model field types are deprecated
|
|
85
83
|
return !FIELD_TYPES.includes(field.type) && _.has(modelsByName, field.type);
|
|
86
84
|
}
|
|
87
85
|
|
|
88
|
-
export function isEnumField(field:
|
|
86
|
+
export function isEnumField(field: FieldSpecificProps): field is FieldEnumProps {
|
|
89
87
|
return field.type === 'enum';
|
|
90
88
|
}
|
|
91
89
|
|
|
@@ -157,19 +155,21 @@ export function getListFieldItems(field: FieldList): FieldListItems {
|
|
|
157
155
|
}
|
|
158
156
|
|
|
159
157
|
export function normalizeListField(field: FieldList): FieldList {
|
|
160
|
-
|
|
158
|
+
// in older versions, the list 'items' were optional and when weren't
|
|
159
|
+
// specified a default list of strings was used.
|
|
160
|
+
if (_.get(field, 'items.type')) {
|
|
161
161
|
return field;
|
|
162
162
|
}
|
|
163
163
|
return {
|
|
164
164
|
...field,
|
|
165
165
|
items: {
|
|
166
|
-
|
|
167
|
-
|
|
166
|
+
...(field.items ?? {}),
|
|
167
|
+
type: 'string'
|
|
168
168
|
}
|
|
169
|
-
};
|
|
169
|
+
} as FieldList;
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
-
export function normalizeListFieldInPlace(field: FieldList): FieldList {
|
|
172
|
+
export function normalizeListFieldInPlace(field: FieldList | DataModelList): FieldList | DataModelList {
|
|
173
173
|
// 'items.type' of list field default to 'string', set it explicitly
|
|
174
174
|
if (!_.has(field, 'items.type')) {
|
|
175
175
|
_.set(field, 'items.type', 'string');
|
|
@@ -177,6 +177,28 @@ export function normalizeListFieldInPlace(field: FieldList): FieldList {
|
|
|
177
177
|
return field;
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
+
export function getListItemsOrSelf(field: Field): Exclude<FieldSpecificProps, FieldListProps> {
|
|
181
|
+
if (isListField(field)) {
|
|
182
|
+
return normalizeListField(field).items;
|
|
183
|
+
}
|
|
184
|
+
return field;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
export function mapListItemsPropsOrSelfSpecificProps(
|
|
188
|
+
field: Field,
|
|
189
|
+
func: <T extends Exclude<FieldSpecificProps, FieldListProps>>(listItemsPropsOrField: T) => T
|
|
190
|
+
): Field {
|
|
191
|
+
if (isListField(field)) {
|
|
192
|
+
const listItems = normalizeListField(field).items;
|
|
193
|
+
const mappedListItems = func(listItems);
|
|
194
|
+
return {
|
|
195
|
+
...field,
|
|
196
|
+
items: mappedListItems
|
|
197
|
+
} as FieldList;
|
|
198
|
+
}
|
|
199
|
+
return func(field);
|
|
200
|
+
}
|
|
201
|
+
|
|
180
202
|
export function assignLabelFieldIfNeeded(modelOrField: Model | FieldObjectProps) {
|
|
181
203
|
if (modelOrField.labelField) {
|
|
182
204
|
return;
|