@stackbit/sdk 0.3.5 → 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
|
@@ -22,7 +22,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
22
22
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
23
23
|
};
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
-
exports.loadConfigFromDir = exports.validateAndNormalizeConfig = exports.
|
|
25
|
+
exports.mergeConfigModelsWithExternalModels = exports.loadConfigFromDir = exports.validateAndNormalizeConfig = exports.loadAndMergeModelsFromFiles = exports.loadConfig = exports.loadConfigWithModels = exports.loadConfigWithModelsPresetsAndValidate = void 0;
|
|
26
26
|
const path_1 = __importDefault(require("path"));
|
|
27
27
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
28
28
|
const chokidar_1 = __importDefault(require("chokidar"));
|
|
@@ -35,29 +35,91 @@ const config_loader_esbuild_1 = require("./config-loader-esbuild");
|
|
|
35
35
|
const utils_2 = require("../utils");
|
|
36
36
|
const presets_loader_1 = require("./presets-loader");
|
|
37
37
|
const config_loader_utils_1 = require("./config-loader-utils");
|
|
38
|
-
async function
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
async function loadConfigWithModelsPresetsAndValidate({ dirPath, modelsSource, stackbitConfigESBuildOutDir, watchCallback, logger }) {
|
|
39
|
+
const configResult = await loadConfigWithModels({
|
|
40
|
+
dirPath,
|
|
41
|
+
stackbitConfigESBuildOutDir,
|
|
42
|
+
watchCallback: watchCallback
|
|
43
|
+
? async (configResult) => {
|
|
44
|
+
const configLoaderResult = await processConfigLoaderResult({ configResult, dirPath, modelsSource });
|
|
45
|
+
watchCallback(configLoaderResult);
|
|
46
|
+
}
|
|
47
|
+
: undefined,
|
|
48
|
+
logger
|
|
49
|
+
});
|
|
50
|
+
const configLoaderResult = await processConfigLoaderResult({ configResult, dirPath, modelsSource });
|
|
51
|
+
return {
|
|
52
|
+
...configLoaderResult,
|
|
53
|
+
stop: configResult.stop,
|
|
54
|
+
reload: configResult.reload
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
exports.loadConfigWithModelsPresetsAndValidate = loadConfigWithModelsPresetsAndValidate;
|
|
58
|
+
async function loadConfigWithModels({ dirPath, stackbitConfigESBuildOutDir, watchCallback, logger }) {
|
|
59
|
+
const wrapConfigResult = async (configResult) => {
|
|
60
|
+
if (!configResult.config) {
|
|
61
|
+
return {
|
|
62
|
+
config: null,
|
|
63
|
+
errors: configResult.errors
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
return await loadAndMergeModelsFromFiles(configResult.config);
|
|
67
|
+
};
|
|
68
|
+
const rawConfigResult = await loadConfig({
|
|
69
|
+
dirPath,
|
|
70
|
+
stackbitConfigESBuildOutDir,
|
|
71
|
+
logger,
|
|
72
|
+
watchCallback: watchCallback
|
|
73
|
+
? async (configResult) => {
|
|
74
|
+
const wrappedResult = await wrapConfigResult(configResult);
|
|
75
|
+
watchCallback(wrappedResult);
|
|
76
|
+
}
|
|
77
|
+
: undefined
|
|
78
|
+
});
|
|
79
|
+
const wrappedResult = await wrapConfigResult(rawConfigResult);
|
|
80
|
+
return {
|
|
81
|
+
...wrappedResult,
|
|
82
|
+
stop: rawConfigResult.stop,
|
|
83
|
+
reload: rawConfigResult.reload
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
exports.loadConfigWithModels = loadConfigWithModels;
|
|
87
|
+
async function loadConfig({ dirPath, stackbitConfigESBuildOutDir, watchCallback, logger }) {
|
|
88
|
+
const normalizeConfigResult = (rawConfigResult) => {
|
|
89
|
+
if (!rawConfigResult.config) {
|
|
90
|
+
return {
|
|
91
|
+
config: null,
|
|
92
|
+
errors: [rawConfigResult.error]
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
// TODO: validate config base properties after normalizing and return validation errors
|
|
96
|
+
const config = normalizeConfig(rawConfigResult.config);
|
|
97
|
+
return {
|
|
98
|
+
config: config,
|
|
99
|
+
errors: []
|
|
44
100
|
};
|
|
45
|
-
}
|
|
101
|
+
};
|
|
46
102
|
const rawConfigResult = await loadConfigFromDir({
|
|
47
103
|
dirPath,
|
|
48
104
|
stackbitConfigESBuildOutDir,
|
|
49
|
-
watchCallback:
|
|
105
|
+
watchCallback: watchCallback
|
|
106
|
+
? async (rawConfigResult) => {
|
|
107
|
+
const normalizedResult = await normalizeConfigResult(rawConfigResult);
|
|
108
|
+
watchCallback(normalizedResult);
|
|
109
|
+
}
|
|
110
|
+
: undefined,
|
|
50
111
|
logger
|
|
51
112
|
});
|
|
52
|
-
const
|
|
53
|
-
return
|
|
113
|
+
const normalizedResult = await normalizeConfigResult(rawConfigResult);
|
|
114
|
+
return {
|
|
115
|
+
...normalizedResult,
|
|
54
116
|
stop: rawConfigResult.stop,
|
|
55
117
|
reload: rawConfigResult.reload
|
|
56
|
-
}
|
|
118
|
+
};
|
|
57
119
|
}
|
|
58
120
|
exports.loadConfig = loadConfig;
|
|
59
|
-
async function processConfigLoaderResult({
|
|
60
|
-
const { config, errors: configLoadErrors } =
|
|
121
|
+
async function processConfigLoaderResult({ configResult, dirPath, modelsSource }) {
|
|
122
|
+
const { config, errors: configLoadErrors } = configResult;
|
|
61
123
|
if (!config) {
|
|
62
124
|
return {
|
|
63
125
|
valid: false,
|
|
@@ -66,76 +128,95 @@ async function processConfigLoaderResult({ rawConfigResult, dirPath, modelsSourc
|
|
|
66
128
|
};
|
|
67
129
|
}
|
|
68
130
|
const { models: externalModels, errors: externalModelsLoadErrors } = await loadModelsFromExternalSource(config, dirPath, modelsSource);
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
131
|
+
const mergedModels = mergeConfigModelsWithExternalModels({ configModels: config.models, externalModels });
|
|
132
|
+
const mergedConfig = {
|
|
133
|
+
...config,
|
|
134
|
+
models: mergedModels
|
|
135
|
+
};
|
|
136
|
+
const normalizedResult = validateAndNormalizeConfig(mergedConfig);
|
|
137
|
+
const presetsResult = await presets_loader_1.loadPresets({ config: normalizedResult.config });
|
|
138
|
+
const modelsWithPresetIds = presets_loader_1.extendModelsWithPresetsIds({
|
|
139
|
+
models: normalizedResult.config.models,
|
|
140
|
+
presets: presetsResult.presets
|
|
141
|
+
});
|
|
142
|
+
const configWithPresets = {
|
|
143
|
+
...normalizedResult.config,
|
|
144
|
+
models: modelsWithPresetIds,
|
|
145
|
+
presets: presetsResult.presets
|
|
74
146
|
};
|
|
75
|
-
}
|
|
76
|
-
async function extendConfig({ config, externalModels }) {
|
|
77
|
-
const normalizedResult = validateAndNormalizeConfig(config, externalModels);
|
|
78
|
-
const presetsResult = await presets_loader_1.loadPresets(config.dirPath, normalizedResult.config);
|
|
79
147
|
return {
|
|
80
148
|
valid: normalizedResult.valid,
|
|
81
|
-
config:
|
|
82
|
-
errors: [...normalizedResult.errors, ...presetsResult.errors]
|
|
149
|
+
config: configWithPresets,
|
|
150
|
+
errors: [...configLoadErrors, ...externalModelsLoadErrors, ...normalizedResult.errors, ...presetsResult.errors]
|
|
83
151
|
};
|
|
84
152
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
// this must be done before any validation as some properties like
|
|
89
|
-
// the labelField will not work when validating models without extending them first
|
|
90
|
-
const { models: extendedModels, errors: extendModelErrors } = utils_2.extendModelMap(config.models);
|
|
153
|
+
async function loadAndMergeModelsFromFiles(config) {
|
|
154
|
+
const { models: modelsFromFiles, errors: fileModelsErrors } = await config_loader_utils_1.loadYamlModelsFromFiles(config);
|
|
155
|
+
const { models: mergedModels, errors: mergeModelErrors } = config_loader_utils_1.mergeConfigModelsWithModelsFromFiles(config.models, modelsFromFiles);
|
|
91
156
|
const extendedConfig = {
|
|
92
157
|
...config,
|
|
93
|
-
models:
|
|
158
|
+
models: mergedModels
|
|
159
|
+
};
|
|
160
|
+
return {
|
|
161
|
+
config: extendedConfig,
|
|
162
|
+
errors: [...fileModelsErrors, ...mergeModelErrors]
|
|
94
163
|
};
|
|
95
|
-
|
|
164
|
+
}
|
|
165
|
+
exports.loadAndMergeModelsFromFiles = loadAndMergeModelsFromFiles;
|
|
166
|
+
function validateAndNormalizeConfig(config) {
|
|
96
167
|
// validate the "contentModels" and extend config models with "contentModels"
|
|
97
168
|
// this must be done before main config validation to make it independent of "contentModels".
|
|
98
|
-
const {
|
|
169
|
+
const { config: configWithContentModels, errors: contentModelsErrors } = validateAndExtendContentModels(config);
|
|
99
170
|
// normalize config - backward compatibility updates, adding extra fields like "markdown_content", "type" and "layout",
|
|
100
171
|
// and setting other default values.
|
|
101
|
-
const
|
|
172
|
+
const configWithNormalizedModels = normalizeModels(configWithContentModels);
|
|
102
173
|
// validate config
|
|
103
|
-
const {
|
|
104
|
-
const errors = [...
|
|
174
|
+
const { config: validatedConfig, errors: validationErrors } = config_validator_1.validateConfig(configWithNormalizedModels);
|
|
175
|
+
const errors = [...contentModelsErrors, ...validationErrors];
|
|
105
176
|
return normalizeValidationResult({
|
|
106
177
|
valid: lodash_1.default.isEmpty(errors),
|
|
107
|
-
|
|
178
|
+
config: validatedConfig,
|
|
108
179
|
errors: errors
|
|
109
180
|
});
|
|
110
181
|
}
|
|
111
182
|
exports.validateAndNormalizeConfig = validateAndNormalizeConfig;
|
|
112
183
|
async function loadConfigFromDir({ dirPath, stackbitConfigESBuildOutDir, watchCallback, logger }) {
|
|
184
|
+
function wrapResult(result, configFilePath) {
|
|
185
|
+
if (result.error) {
|
|
186
|
+
return {
|
|
187
|
+
config: null,
|
|
188
|
+
error: result.error
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
return {
|
|
193
|
+
config: {
|
|
194
|
+
...result.config,
|
|
195
|
+
dirPath: dirPath,
|
|
196
|
+
filePath: configFilePath
|
|
197
|
+
},
|
|
198
|
+
error: null
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
}
|
|
113
202
|
// try to load stackbit config from YAML files
|
|
114
203
|
try {
|
|
115
204
|
const stackbitYamlPath = await utils_1.getFirstExistingFile(config_loader_utils_1.STACKBIT_CONFIG_YAML_FILES, dirPath);
|
|
116
205
|
if (stackbitYamlPath) {
|
|
117
|
-
|
|
206
|
+
logger === null || logger === void 0 ? void 0 : logger.debug(`loading Stackbit configuration from ${stackbitYamlPath}`);
|
|
207
|
+
const result = await config_loader_utils_1.loadStackbitYamlFromDir(dirPath);
|
|
118
208
|
let close = async () => void 0;
|
|
119
209
|
let reload = () => void 0;
|
|
120
210
|
let stopped = false;
|
|
121
211
|
if (watchCallback) {
|
|
122
|
-
const watcher = chokidar_1.default.watch([...config_loader_utils_1.STACKBIT_CONFIG_YAML_FILES
|
|
212
|
+
const watcher = chokidar_1.default.watch([...config_loader_utils_1.STACKBIT_CONFIG_YAML_FILES], {
|
|
123
213
|
cwd: dirPath,
|
|
124
214
|
persistent: true,
|
|
125
215
|
ignoreInitial: true
|
|
126
216
|
});
|
|
127
217
|
const throttledFileChange = lodash_1.default.throttle(async () => {
|
|
128
|
-
const
|
|
129
|
-
watchCallback(
|
|
130
|
-
config: config
|
|
131
|
-
? {
|
|
132
|
-
...config,
|
|
133
|
-
dirPath: dirPath,
|
|
134
|
-
filePath: stackbitYamlPath
|
|
135
|
-
}
|
|
136
|
-
: undefined,
|
|
137
|
-
errors
|
|
138
|
-
});
|
|
218
|
+
const result = await config_loader_utils_1.loadStackbitYamlFromDir(dirPath);
|
|
219
|
+
watchCallback(wrapResult(result, stackbitYamlPath));
|
|
139
220
|
}, 1000);
|
|
140
221
|
const handleFileChange = (path) => {
|
|
141
222
|
logger === null || logger === void 0 ? void 0 : logger.debug(`identified change in stackbit config file: ${path}, reloading config...`);
|
|
@@ -148,7 +229,8 @@ async function loadConfigFromDir({ dirPath, stackbitConfigESBuildOutDir, watchCa
|
|
|
148
229
|
watcher.on('unlinkDir', handleFileChange);
|
|
149
230
|
watcher.on('error', (error) => {
|
|
150
231
|
watchCallback({
|
|
151
|
-
|
|
232
|
+
config: null,
|
|
233
|
+
error: new config_errors_1.ConfigLoadError(`Error loading Stackbit configuration: ${error.message}`, { originalError: error })
|
|
152
234
|
});
|
|
153
235
|
});
|
|
154
236
|
close = async () => {
|
|
@@ -164,45 +246,23 @@ async function loadConfigFromDir({ dirPath, stackbitConfigESBuildOutDir, watchCa
|
|
|
164
246
|
};
|
|
165
247
|
}
|
|
166
248
|
return {
|
|
167
|
-
|
|
168
|
-
? {
|
|
169
|
-
...config,
|
|
170
|
-
dirPath: dirPath,
|
|
171
|
-
filePath: stackbitYamlPath
|
|
172
|
-
}
|
|
173
|
-
: undefined,
|
|
249
|
+
...wrapResult(result, stackbitYamlPath),
|
|
174
250
|
stop: close,
|
|
175
|
-
reload: reload
|
|
176
|
-
errors: errors
|
|
251
|
+
reload: reload
|
|
177
252
|
};
|
|
178
253
|
}
|
|
179
254
|
}
|
|
180
255
|
catch (error) {
|
|
181
256
|
return {
|
|
182
|
-
|
|
257
|
+
config: null,
|
|
258
|
+
error: new config_errors_1.ConfigLoadError(`Error loading Stackbit configuration: ${error.message}`, { originalError: error })
|
|
183
259
|
};
|
|
184
260
|
}
|
|
185
|
-
function wrapResult(result, configFilePath) {
|
|
186
|
-
if (result.error) {
|
|
187
|
-
return {
|
|
188
|
-
errors: [result.error]
|
|
189
|
-
};
|
|
190
|
-
}
|
|
191
|
-
else {
|
|
192
|
-
return {
|
|
193
|
-
config: {
|
|
194
|
-
...result.config,
|
|
195
|
-
dirPath: dirPath,
|
|
196
|
-
filePath: configFilePath
|
|
197
|
-
},
|
|
198
|
-
errors: []
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
261
|
// try to load stackbit config from JavaScript files
|
|
203
262
|
try {
|
|
204
263
|
const configFilePath = await utils_1.getFirstExistingFile(config_loader_utils_1.STACKBIT_CONFIG_JS_FILES, dirPath);
|
|
205
264
|
if (configFilePath) {
|
|
265
|
+
logger === null || logger === void 0 ? void 0 : logger.debug(`loading Stackbit configuration from: ${configFilePath}`);
|
|
206
266
|
const configResult = await config_loader_esbuild_1.loadStackbitConfigFromJs({
|
|
207
267
|
configPath: configFilePath,
|
|
208
268
|
outDir: stackbitConfigESBuildOutDir !== null && stackbitConfigESBuildOutDir !== void 0 ? stackbitConfigESBuildOutDir : '.stackbit/cache',
|
|
@@ -219,11 +279,13 @@ async function loadConfigFromDir({ dirPath, stackbitConfigESBuildOutDir, watchCa
|
|
|
219
279
|
}
|
|
220
280
|
catch (error) {
|
|
221
281
|
return {
|
|
222
|
-
|
|
282
|
+
config: null,
|
|
283
|
+
error: new config_errors_1.ConfigLoadError(`Error loading Stackbit configuration: ${error.message}`, { originalError: error })
|
|
223
284
|
};
|
|
224
285
|
}
|
|
225
286
|
return {
|
|
226
|
-
|
|
287
|
+
config: null,
|
|
288
|
+
error: new config_errors_1.ConfigLoadError(config_errors_1.STACKBIT_CONFIG_NOT_FOUND)
|
|
227
289
|
};
|
|
228
290
|
}
|
|
229
291
|
exports.loadConfigFromDir = loadConfigFromDir;
|
|
@@ -285,34 +347,27 @@ async function loadConfigFromDotStackbit(dirPath) {
|
|
|
285
347
|
}
|
|
286
348
|
return lodash_1.default.isEmpty(config) ? null : config;
|
|
287
349
|
}
|
|
288
|
-
function
|
|
350
|
+
function mergeConfigModelsWithExternalModels({ configModels, externalModels }) {
|
|
289
351
|
var _a;
|
|
290
|
-
if (
|
|
291
|
-
return
|
|
292
|
-
config,
|
|
293
|
-
errors: []
|
|
294
|
-
};
|
|
352
|
+
if (externalModels.length === 0) {
|
|
353
|
+
return configModels;
|
|
295
354
|
}
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
lodash_1.default.forEach(stackbitModels, (stackbitModel, modelName) => {
|
|
303
|
-
var _a, _b;
|
|
304
|
-
let externalModel = models[modelName];
|
|
355
|
+
if (configModels.length === 0) {
|
|
356
|
+
return externalModels;
|
|
357
|
+
}
|
|
358
|
+
const mergedModelsByName = lodash_1.default.keyBy(externalModels, 'name');
|
|
359
|
+
for (const configModel of configModels) {
|
|
360
|
+
const externalModel = mergedModelsByName[configModel.name];
|
|
305
361
|
if (!externalModel) {
|
|
306
|
-
|
|
362
|
+
continue;
|
|
363
|
+
}
|
|
364
|
+
const modelType = configModel.type ? (configModel.type === 'config' ? 'data' : configModel.type) : (_a = externalModel.type) !== null && _a !== void 0 ? _a : 'object';
|
|
365
|
+
let mergedModel = Object.assign({}, externalModel, lodash_1.default.pick(configModel, ['__metadata', 'urlPath', 'label', 'description', 'thumbnail', 'singleInstance', 'readOnly', 'labelField', 'fieldGroups']), { type: modelType });
|
|
366
|
+
if (mergedModel.type === 'page' && !mergedModel.urlPath) {
|
|
367
|
+
mergedModel.urlPath = '/{slug}';
|
|
307
368
|
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
externalModel = Object.assign({}, externalModel, lodash_1.default.pick(stackbitModel, ['__metadata', 'label', 'description', 'thumbnail', 'singleInstance', 'readOnly', 'labelField', 'fieldGroups']), utils_1.omitByNil({
|
|
311
|
-
type: modelType,
|
|
312
|
-
urlPath
|
|
313
|
-
}));
|
|
314
|
-
externalModel = utils_2.mapModelFieldsRecursively(externalModel, (externalField, modelKeyPath) => {
|
|
315
|
-
const stackbitField = utils_2.getModelFieldForModelKeyPath(stackbitModel, modelKeyPath);
|
|
369
|
+
mergedModel = utils_2.mapModelFieldsRecursively(mergedModel, (externalField, modelKeyPath) => {
|
|
370
|
+
const stackbitField = utils_2.getModelFieldForModelKeyPath(configModel, modelKeyPath);
|
|
316
371
|
if (!stackbitField) {
|
|
317
372
|
return externalField;
|
|
318
373
|
}
|
|
@@ -332,40 +387,52 @@ function mergeConfigWithExternalModels(config, externalModels) {
|
|
|
332
387
|
else if (externalField.type === 'object') {
|
|
333
388
|
override = lodash_1.default.pick(stackbitField, ['labelField', 'thumbnail', 'fieldGroups']);
|
|
334
389
|
}
|
|
390
|
+
else if (externalField.type === 'reference' || externalField.type === 'model') {
|
|
391
|
+
override = lodash_1.default.pick(stackbitField, ['models']);
|
|
392
|
+
}
|
|
335
393
|
return Object.assign({}, externalField, lodash_1.default.pick(stackbitField, ['label', 'description', 'required', 'default', 'group', 'const', 'hidden', 'readOnly', 'controlType']), override);
|
|
336
394
|
});
|
|
337
|
-
|
|
338
|
-
}
|
|
395
|
+
mergedModelsByName[configModel.name] = mergedModel;
|
|
396
|
+
}
|
|
397
|
+
return Object.values(mergedModelsByName);
|
|
398
|
+
}
|
|
399
|
+
exports.mergeConfigModelsWithExternalModels = mergeConfigModelsWithExternalModels;
|
|
400
|
+
function normalizeConfig(rawConfig) {
|
|
401
|
+
const stackbitVersion = String(lodash_1.default.get(rawConfig, 'stackbitVersion', config_loader_utils_1.LATEST_STACKBIT_VERSION));
|
|
402
|
+
const ver = semver_1.default.coerce(stackbitVersion);
|
|
403
|
+
const isGTEStackbitYamlV5 = ver ? semver_1.default.satisfies(ver, '>=0.5.0') : false;
|
|
404
|
+
const { logicFields, models: modelMap, ...restConfig } = rawConfig;
|
|
405
|
+
// in stackbit.yaml 'models' are defined as object where keys are the model names,
|
|
406
|
+
// convert 'models' to array of objects and set their 'name' property to the model name
|
|
407
|
+
const models = lodash_1.default.reduce(modelMap, (accum, model, modelName) => accum.concat(Object.assign({ name: modelName }, model)), []);
|
|
339
408
|
return {
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
409
|
+
...restConfig,
|
|
410
|
+
stackbitVersion: stackbitVersion,
|
|
411
|
+
models: models,
|
|
412
|
+
noEncodeFields: logicFields,
|
|
413
|
+
hcrHandled: !stackbitVersion || lodash_1.default.get(rawConfig, 'customContentReload', lodash_1.default.get(rawConfig, 'hcrHandled', !isGTEStackbitYamlV5)),
|
|
414
|
+
internalStackbitRunnerOptions: getInternalStackbitRunnerOptions(rawConfig)
|
|
345
415
|
};
|
|
346
416
|
}
|
|
347
|
-
function
|
|
348
|
-
|
|
349
|
-
const
|
|
350
|
-
const
|
|
417
|
+
function normalizeModels(config) {
|
|
418
|
+
var _a, _b, _c;
|
|
419
|
+
const pageLayoutKey = (_a = config.pageLayoutKey) !== null && _a !== void 0 ? _a : 'layout';
|
|
420
|
+
const objectTypeKey = (_b = config.objectTypeKey) !== null && _b !== void 0 ? _b : 'type';
|
|
421
|
+
const stackbitYamlVersion = String((_c = config.stackbitVersion) !== null && _c !== void 0 ? _c : '');
|
|
351
422
|
const ver = semver_1.default.coerce(stackbitYamlVersion);
|
|
352
423
|
const isStackbitYamlV2 = ver ? semver_1.default.satisfies(ver, '<0.3.0') : false;
|
|
353
|
-
const
|
|
354
|
-
const
|
|
424
|
+
const models = config.models;
|
|
425
|
+
const modelsByName = lodash_1.default.keyBy(models, 'name');
|
|
355
426
|
const gitCMS = isGitCMS(config);
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
lodash_1.default.forEach(models, (model, modelName) => {
|
|
360
|
-
if (!model) {
|
|
361
|
-
return;
|
|
362
|
-
}
|
|
427
|
+
const mappedModels = models.map((model) => {
|
|
428
|
+
// create shallow copy of the model to prevent mutation of original models
|
|
429
|
+
model = { ...model };
|
|
363
430
|
if (!lodash_1.default.has(model, 'type')) {
|
|
364
431
|
model.type = 'object';
|
|
365
432
|
}
|
|
366
433
|
// add model label if not set
|
|
367
434
|
if (!lodash_1.default.has(model, 'label')) {
|
|
368
|
-
model.label = lodash_1.default.startCase(
|
|
435
|
+
model.label = lodash_1.default.startCase(model.name);
|
|
369
436
|
}
|
|
370
437
|
if (lodash_1.default.has(model, 'fields') && !Array.isArray(model.fields)) {
|
|
371
438
|
model.fields = [];
|
|
@@ -387,17 +454,15 @@ function normalizeConfig(config) {
|
|
|
387
454
|
// The content validator should always assume these fields.
|
|
388
455
|
// And when new objects created from UI, it should add these fields automatically.
|
|
389
456
|
if (utils_2.isPageModel(model)) {
|
|
390
|
-
addLayoutFieldToPageModel(model, pageLayoutKey,
|
|
457
|
+
addLayoutFieldToPageModel(model, pageLayoutKey, model.name);
|
|
391
458
|
}
|
|
392
459
|
else if (utils_2.isDataModel(model) && !utils_2.isListDataModel(model)) {
|
|
393
|
-
addObjectTypeKeyField(model, objectTypeKey,
|
|
460
|
+
addObjectTypeKeyField(model, objectTypeKey, model.name);
|
|
394
461
|
}
|
|
395
462
|
}
|
|
396
463
|
if (utils_2.isListDataModel(model)) {
|
|
397
464
|
// 'items.type' of list model defaults to 'string', set it explicitly
|
|
398
|
-
|
|
399
|
-
lodash_1.default.set(model, 'items.type', 'string');
|
|
400
|
-
}
|
|
465
|
+
utils_2.normalizeListFieldInPlace(model);
|
|
401
466
|
if (utils_2.isObjectListItems(model.items)) {
|
|
402
467
|
utils_2.assignLabelFieldIfNeeded(model.items);
|
|
403
468
|
}
|
|
@@ -405,50 +470,65 @@ function normalizeConfig(config) {
|
|
|
405
470
|
else if (!lodash_1.default.has(model, 'labelField')) {
|
|
406
471
|
utils_2.assignLabelFieldIfNeeded(model);
|
|
407
472
|
}
|
|
408
|
-
utils_2.
|
|
473
|
+
return utils_2.mapModelFieldsRecursively(model, (field) => {
|
|
474
|
+
// create shallow copy of the field to prevent mutation of original field
|
|
475
|
+
field = { ...field };
|
|
409
476
|
// add field label if label is not set
|
|
410
477
|
if (!lodash_1.default.has(field, 'label')) {
|
|
411
478
|
field.label = lodash_1.default.startCase(field.name);
|
|
412
479
|
}
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
}
|
|
417
|
-
if (utils_2.isObjectField(field)) {
|
|
418
|
-
utils_2.assignLabelFieldIfNeeded(field);
|
|
419
|
-
}
|
|
420
|
-
else if (utils_2.isCustomModelField(field, models)) {
|
|
421
|
-
// stackbit v0.2.0 compatibility
|
|
422
|
-
// convert the old custom model field type: { type: 'action' }
|
|
423
|
-
// to the new 'model' field type: { type: 'model', models: ['action'] }
|
|
424
|
-
field.models = [field.type];
|
|
425
|
-
field.type = 'model';
|
|
426
|
-
}
|
|
427
|
-
else if (field.type === 'models') {
|
|
428
|
-
// stackbit v0.2.0 compatibility
|
|
429
|
-
// convert the old 'models' field type: { type: 'models', models: ['link', 'button'] }
|
|
430
|
-
// to the new 'model' field type: { type: 'model', models: ['link', 'button'] }
|
|
431
|
-
field.type = 'model';
|
|
432
|
-
field.models = lodash_1.default.get(field, 'models', []);
|
|
433
|
-
}
|
|
434
|
-
else if (field.type === 'model' && lodash_1.default.has(field, 'model')) {
|
|
435
|
-
// stackbit v0.2.0 compatibility
|
|
436
|
-
// convert the old 'model' field type: { type: 'model', model: 'link' }
|
|
437
|
-
// to the new 'model' field type: { type: 'model', models: ['link'] }
|
|
438
|
-
field.models = [field.model];
|
|
439
|
-
delete field.model;
|
|
440
|
-
}
|
|
441
|
-
if (isStackbitYamlV2) {
|
|
442
|
-
// in stackbit.yaml v0.2.x, the 'reference' field was what we have today as 'model' field:
|
|
443
|
-
if (utils_2.isReferenceField(field)) {
|
|
444
|
-
field = field;
|
|
445
|
-
field.type = 'model';
|
|
446
|
-
field.models = lodash_1.default.get(field, 'models', []);
|
|
480
|
+
return utils_2.mapListItemsPropsOrSelfSpecificProps(field, (fieldSpecificProps) => {
|
|
481
|
+
if (utils_2.isObjectField(fieldSpecificProps)) {
|
|
482
|
+
utils_2.assignLabelFieldIfNeeded(fieldSpecificProps);
|
|
447
483
|
}
|
|
448
|
-
|
|
484
|
+
else if (utils_2.isCustomModelField(fieldSpecificProps, modelsByName)) {
|
|
485
|
+
// stackbit v0.2.0 compatibility
|
|
486
|
+
// convert the old custom model field type: { type: 'action' }
|
|
487
|
+
// to the new 'model' field type: { type: 'model', models: ['action'] }
|
|
488
|
+
fieldSpecificProps = {
|
|
489
|
+
...fieldSpecificProps,
|
|
490
|
+
type: 'model',
|
|
491
|
+
models: [fieldSpecificProps.type]
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
else if (fieldSpecificProps.type === 'models') {
|
|
495
|
+
// stackbit v0.2.0 compatibility
|
|
496
|
+
// convert the old 'models' field type: { type: 'models', models: ['link', 'button'] }
|
|
497
|
+
// to the new 'model' field type: { type: 'model', models: ['link', 'button'] }
|
|
498
|
+
fieldSpecificProps = {
|
|
499
|
+
...fieldSpecificProps,
|
|
500
|
+
type: 'model',
|
|
501
|
+
models: lodash_1.default.get(fieldSpecificProps, 'models', [])
|
|
502
|
+
};
|
|
503
|
+
}
|
|
504
|
+
else if (fieldSpecificProps.type === 'model' && lodash_1.default.has(fieldSpecificProps, 'model')) {
|
|
505
|
+
// stackbit v0.2.0 compatibility
|
|
506
|
+
// convert the old 'model' field type: { type: 'model', model: 'link' }
|
|
507
|
+
// to the new 'model' field type: { type: 'model', models: ['link'] }
|
|
508
|
+
const { model, ...rest } = fieldSpecificProps;
|
|
509
|
+
fieldSpecificProps = {
|
|
510
|
+
...rest,
|
|
511
|
+
models: [model]
|
|
512
|
+
};
|
|
513
|
+
}
|
|
514
|
+
if (isStackbitYamlV2) {
|
|
515
|
+
// in stackbit.yaml v0.2.x, the 'reference' field was what we have today as 'model' field:
|
|
516
|
+
if (utils_2.isReferenceField(fieldSpecificProps)) {
|
|
517
|
+
fieldSpecificProps = {
|
|
518
|
+
...fieldSpecificProps,
|
|
519
|
+
type: 'model',
|
|
520
|
+
models: lodash_1.default.get(fieldSpecificProps, 'models', [])
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
return fieldSpecificProps;
|
|
525
|
+
});
|
|
449
526
|
});
|
|
450
527
|
});
|
|
451
|
-
return
|
|
528
|
+
return {
|
|
529
|
+
...config,
|
|
530
|
+
models: mappedModels
|
|
531
|
+
};
|
|
452
532
|
}
|
|
453
533
|
function updatePageUrlPath(model) {
|
|
454
534
|
// set default urlPath if not set
|
|
@@ -553,26 +633,23 @@ function addObjectTypeKeyField(model, objectTypeKey, modelName) {
|
|
|
553
633
|
}
|
|
554
634
|
/**
|
|
555
635
|
* Returns model names referenced by polymorphic 'model' and 'reference' fields.
|
|
556
|
-
* That is, fields that can hold objects of different types.
|
|
557
636
|
*
|
|
558
637
|
* @param field
|
|
559
638
|
*/
|
|
560
639
|
function getReferencedModelNames(field) {
|
|
561
640
|
var _a, _b;
|
|
562
|
-
|
|
563
|
-
field = utils_2.getListFieldItems(field);
|
|
564
|
-
}
|
|
641
|
+
const fieldSpecificProps = utils_2.getListItemsOrSelf(field);
|
|
565
642
|
// TODO: add type field to model fields inside container update/create object logic rather adding type to schema
|
|
566
643
|
// 'object' models referenced by 'model' fields should have 'type' field
|
|
567
644
|
// if these fields have than 1 model.
|
|
568
645
|
// 'data' models referenced by 'reference' fields should always have 'type' field.
|
|
569
646
|
let referencedModelNames = [];
|
|
570
|
-
if (utils_2.isModelField(
|
|
571
|
-
const modelNames =
|
|
647
|
+
if (utils_2.isModelField(fieldSpecificProps) && ((_a = fieldSpecificProps.models) === null || _a === void 0 ? void 0 : _a.length) > 1) {
|
|
648
|
+
const modelNames = fieldSpecificProps.models;
|
|
572
649
|
referencedModelNames = lodash_1.default.union(referencedModelNames, modelNames);
|
|
573
650
|
}
|
|
574
|
-
else if (utils_2.isReferenceField(
|
|
575
|
-
const modelNames =
|
|
651
|
+
else if (utils_2.isReferenceField(fieldSpecificProps) && ((_b = fieldSpecificProps.models) === null || _b === void 0 ? void 0 : _b.length) > 0) {
|
|
652
|
+
const modelNames = fieldSpecificProps.models;
|
|
576
653
|
referencedModelNames = lodash_1.default.union(referencedModelNames, modelNames);
|
|
577
654
|
}
|
|
578
655
|
return referencedModelNames;
|
|
@@ -580,46 +657,47 @@ function getReferencedModelNames(field) {
|
|
|
580
657
|
function validateAndExtendContentModels(config) {
|
|
581
658
|
var _a, _b;
|
|
582
659
|
const contentModels = (_a = config.contentModels) !== null && _a !== void 0 ? _a : {};
|
|
583
|
-
const models = (_b = config.models) !== null && _b !== void 0 ? _b :
|
|
660
|
+
const models = (_b = config.models) !== null && _b !== void 0 ? _b : [];
|
|
661
|
+
// external models already merged in mergeConfigModelsWithExternalModels function
|
|
584
662
|
const externalModels = !isGitCMS(config);
|
|
585
663
|
const emptyContentModels = lodash_1.default.isEmpty(contentModels);
|
|
586
664
|
if (externalModels || emptyContentModels) {
|
|
587
665
|
return {
|
|
588
|
-
|
|
589
|
-
value: config,
|
|
666
|
+
config: config,
|
|
590
667
|
errors: []
|
|
591
668
|
};
|
|
592
669
|
}
|
|
593
670
|
const validationResult = config_validator_1.validateContentModels(contentModels, models);
|
|
594
671
|
if (lodash_1.default.isEmpty(models)) {
|
|
595
672
|
return {
|
|
596
|
-
|
|
597
|
-
value: config,
|
|
673
|
+
config: config,
|
|
598
674
|
errors: validationResult.errors
|
|
599
675
|
};
|
|
600
676
|
}
|
|
601
|
-
const extendedModels =
|
|
602
|
-
const contentModel = validationResult.
|
|
677
|
+
const extendedModels = models.map((model) => {
|
|
678
|
+
const contentModel = validationResult.contentModels[model.name];
|
|
603
679
|
if (!contentModel) {
|
|
604
680
|
return model;
|
|
605
681
|
}
|
|
606
682
|
if (lodash_1.default.get(contentModel, '__metadata.invalid')) {
|
|
607
683
|
return model;
|
|
608
684
|
}
|
|
609
|
-
|
|
685
|
+
const { isPage, newFilePath, ...restContentModel } = contentModel;
|
|
686
|
+
const { type, ...restModel } = model;
|
|
687
|
+
if (isPage && (!type || ['object', 'page'].includes(type))) {
|
|
610
688
|
return {
|
|
611
689
|
type: 'page',
|
|
612
|
-
...(
|
|
613
|
-
...
|
|
614
|
-
...
|
|
690
|
+
...(newFilePath ? { filePath: newFilePath } : {}),
|
|
691
|
+
...restContentModel,
|
|
692
|
+
...restModel
|
|
615
693
|
};
|
|
616
694
|
}
|
|
617
|
-
else if (!
|
|
695
|
+
else if (!isPage && (!type || ['object', 'data'].includes(type))) {
|
|
618
696
|
return {
|
|
619
697
|
type: 'data',
|
|
620
|
-
...(
|
|
621
|
-
...
|
|
622
|
-
...
|
|
698
|
+
...(newFilePath ? { filePath: newFilePath } : {}),
|
|
699
|
+
...restContentModel,
|
|
700
|
+
...restModel
|
|
623
701
|
};
|
|
624
702
|
}
|
|
625
703
|
else {
|
|
@@ -627,8 +705,7 @@ function validateAndExtendContentModels(config) {
|
|
|
627
705
|
}
|
|
628
706
|
});
|
|
629
707
|
return {
|
|
630
|
-
|
|
631
|
-
value: {
|
|
708
|
+
config: {
|
|
632
709
|
...config,
|
|
633
710
|
models: extendedModels
|
|
634
711
|
},
|
|
@@ -637,14 +714,13 @@ function validateAndExtendContentModels(config) {
|
|
|
637
714
|
}
|
|
638
715
|
function normalizeValidationResult(validationResult) {
|
|
639
716
|
validationResult = filterAndOrderConfigFields(validationResult);
|
|
640
|
-
|
|
641
|
-
return convertModelsToArray(validationResult);
|
|
717
|
+
return convertModelGroupsToModelListInPlace(validationResult);
|
|
642
718
|
}
|
|
643
719
|
function filterAndOrderConfigFields(validationResult) {
|
|
644
720
|
// TODO: check if we can move filtering and sorting to Joi
|
|
645
721
|
return {
|
|
646
722
|
...validationResult,
|
|
647
|
-
|
|
723
|
+
config: lodash_1.default.pick(validationResult.config, [
|
|
648
724
|
'stackbitVersion',
|
|
649
725
|
'ssgName',
|
|
650
726
|
'ssgVersion',
|
|
@@ -694,16 +770,16 @@ function filterAndOrderConfigFields(validationResult) {
|
|
|
694
770
|
* Collects models groups and injects them into the `models` array of the
|
|
695
771
|
* `reference` and `model` field types
|
|
696
772
|
*/
|
|
697
|
-
function
|
|
773
|
+
function convertModelGroupsToModelListInPlace(validationResult) {
|
|
698
774
|
var _a, _b;
|
|
699
|
-
const models = (_b = (_a = validationResult.
|
|
700
|
-
const groupMap = lodash_1.default.reduce(models, (groupMap, model
|
|
775
|
+
const models = (_b = (_a = validationResult.config) === null || _a === void 0 ? void 0 : _a.models) !== null && _b !== void 0 ? _b : [];
|
|
776
|
+
const groupMap = lodash_1.default.reduce(models, (groupMap, model) => {
|
|
701
777
|
if (!model.groups) {
|
|
702
778
|
return groupMap;
|
|
703
779
|
}
|
|
704
780
|
const key = (model === null || model === void 0 ? void 0 : model.type) === 'object' ? 'objectModels' : 'documentModels';
|
|
705
781
|
lodash_1.default.forEach(model.groups, (groupName) => {
|
|
706
|
-
utils_1.append(groupMap, [groupName, key],
|
|
782
|
+
utils_1.append(groupMap, [groupName, key], model.name);
|
|
707
783
|
});
|
|
708
784
|
delete model.groups;
|
|
709
785
|
return groupMap;
|
|
@@ -714,78 +790,31 @@ function convertModelGroupsToModelList(validationResult) {
|
|
|
714
790
|
lodash_1.default.set(group, key, lodash_1.default.uniq(modelGroup));
|
|
715
791
|
});
|
|
716
792
|
});
|
|
717
|
-
|
|
718
|
-
utils_2.
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
if (field.groups) {
|
|
723
|
-
let key = null;
|
|
724
|
-
if (utils_2.isModelField(field)) {
|
|
725
|
-
key = 'objectModels';
|
|
726
|
-
}
|
|
727
|
-
else if (utils_2.isReferenceField(field)) {
|
|
728
|
-
key = 'documentModels';
|
|
793
|
+
const mappedModels = models.map((model) => {
|
|
794
|
+
return utils_2.mapModelFieldsRecursively(model, (field) => {
|
|
795
|
+
return utils_2.mapListItemsPropsOrSelfSpecificProps(field, (fieldSpecificProps) => {
|
|
796
|
+
if (!utils_2.isModelField(fieldSpecificProps) && !utils_2.isReferenceField(fieldSpecificProps)) {
|
|
797
|
+
return fieldSpecificProps;
|
|
729
798
|
}
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
}
|
|
736
|
-
delete
|
|
737
|
-
|
|
799
|
+
const { ...cloned } = fieldSpecificProps;
|
|
800
|
+
const key = utils_2.isModelField(fieldSpecificProps) ? 'objectModels' : 'documentModels';
|
|
801
|
+
const modelNames = lodash_1.default.reduce(cloned.groups, (modelNames, groupName) => {
|
|
802
|
+
const objectModelNames = lodash_1.default.get(groupMap, [groupName, key], []);
|
|
803
|
+
return lodash_1.default.uniq(modelNames.concat(objectModelNames));
|
|
804
|
+
}, fieldSpecificProps.models || []);
|
|
805
|
+
delete cloned.groups;
|
|
806
|
+
return Object.assign(cloned, { models: modelNames });
|
|
807
|
+
});
|
|
738
808
|
});
|
|
739
809
|
});
|
|
740
|
-
}
|
|
741
|
-
function convertModelsToArray(validationResult) {
|
|
742
|
-
const config = validationResult.value;
|
|
743
|
-
const { stackbitVersion = config_loader_utils_1.LATEST_STACKBIT_VERSION, models, ...rest } = config;
|
|
744
|
-
// in stackbit.yaml 'models' are defined as object where keys are the model names,
|
|
745
|
-
// convert 'models' to array of objects and set their 'name' property to the
|
|
746
|
-
// model name
|
|
747
|
-
const modelMap = models !== null && models !== void 0 ? models : {};
|
|
748
|
-
const modelArray = lodash_1.default.map(modelMap, (yamlModel, modelName) => {
|
|
749
|
-
return {
|
|
750
|
-
name: modelName,
|
|
751
|
-
...yamlModel
|
|
752
|
-
};
|
|
753
|
-
});
|
|
754
|
-
if (!isGitCMS(config)) {
|
|
755
|
-
addImageModel(modelArray);
|
|
756
|
-
}
|
|
757
|
-
const convertedErrors = lodash_1.default.map(validationResult.errors, (error) => {
|
|
758
|
-
if (error.fieldPath[0] === 'models' && typeof error.fieldPath[1] == 'string') {
|
|
759
|
-
const modelName = error.fieldPath[1];
|
|
760
|
-
const modelIndex = lodash_1.default.findIndex(modelArray, { name: modelName });
|
|
761
|
-
const normFieldPath = error.fieldPath.slice();
|
|
762
|
-
normFieldPath[1] = modelIndex;
|
|
763
|
-
error.normFieldPath = normFieldPath;
|
|
764
|
-
}
|
|
765
|
-
return error;
|
|
766
|
-
});
|
|
767
810
|
return {
|
|
768
|
-
|
|
811
|
+
...validationResult,
|
|
769
812
|
config: {
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
},
|
|
774
|
-
errors: convertedErrors
|
|
813
|
+
...validationResult.config,
|
|
814
|
+
models: mappedModels
|
|
815
|
+
}
|
|
775
816
|
};
|
|
776
817
|
}
|
|
777
|
-
function addImageModel(models) {
|
|
778
|
-
models.push({
|
|
779
|
-
type: 'image',
|
|
780
|
-
name: '__image_model',
|
|
781
|
-
label: 'Image',
|
|
782
|
-
labelField: 'title',
|
|
783
|
-
fields: [
|
|
784
|
-
{ name: 'title', type: 'string' },
|
|
785
|
-
{ name: 'url', type: 'string' }
|
|
786
|
-
]
|
|
787
|
-
});
|
|
788
|
-
}
|
|
789
818
|
function isGitCMS(config) {
|
|
790
819
|
return !config.contentSources && (!config.cmsName || config.cmsName === 'git');
|
|
791
820
|
}
|