@stackbit/sdk 0.2.39 → 0.3.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.
Files changed (65) hide show
  1. package/dist/analyzer/site-analyzer.d.ts.map +1 -1
  2. package/dist/analyzer/site-analyzer.js +3 -1
  3. package/dist/analyzer/site-analyzer.js.map +1 -1
  4. package/dist/config/config-errors.d.ts +3 -0
  5. package/dist/config/config-errors.d.ts.map +1 -1
  6. package/dist/config/config-errors.js +7 -2
  7. package/dist/config/config-errors.js.map +1 -1
  8. package/dist/config/config-loader-esbuild.d.ts +3 -14
  9. package/dist/config/config-loader-esbuild.d.ts.map +1 -1
  10. package/dist/config/config-loader-esbuild.js +19 -2
  11. package/dist/config/config-loader-esbuild.js.map +1 -1
  12. package/dist/config/config-loader-static.d.ts +14 -0
  13. package/dist/config/config-loader-static.d.ts.map +1 -0
  14. package/dist/config/config-loader-static.js +170 -0
  15. package/dist/config/config-loader-static.js.map +1 -0
  16. package/dist/config/config-loader-utils.d.ts +34 -0
  17. package/dist/config/config-loader-utils.d.ts.map +1 -0
  18. package/dist/config/config-loader-utils.js +211 -0
  19. package/dist/config/config-loader-utils.js.map +1 -0
  20. package/dist/config/config-loader.d.ts +13 -9
  21. package/dist/config/config-loader.d.ts.map +1 -1
  22. package/dist/config/config-loader.js +174 -198
  23. package/dist/config/config-loader.js.map +1 -1
  24. package/dist/config/config-schema/style-field-schema.d.ts.map +1 -1
  25. package/dist/config/config-schema/style-field-schema.js.map +1 -1
  26. package/dist/config/config-schema.d.ts +2 -2
  27. package/dist/config/config-schema.d.ts.map +1 -1
  28. package/dist/config/config-schema.js +5 -6
  29. package/dist/config/config-schema.js.map +1 -1
  30. package/dist/config/config-types.d.ts +32 -2
  31. package/dist/config/config-types.d.ts.map +1 -1
  32. package/dist/config/config-validator.d.ts +5 -3
  33. package/dist/config/config-validator.d.ts.map +1 -1
  34. package/dist/config/config-validator.js.map +1 -1
  35. package/dist/config/config-writer.d.ts +1 -4
  36. package/dist/config/config-writer.d.ts.map +1 -1
  37. package/dist/config/config-writer.js +3 -27
  38. package/dist/config/config-writer.js.map +1 -1
  39. package/dist/content/content-schema.js +5 -6
  40. package/dist/content/content-schema.js.map +1 -1
  41. package/dist/index.d.ts +4 -2
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js +6 -2
  44. package/dist/index.js.map +1 -1
  45. package/dist/utils/index.d.ts +1 -1
  46. package/dist/utils/index.d.ts.map +1 -1
  47. package/dist/utils/model-extender.d.ts +1 -1
  48. package/dist/utils/model-extender.d.ts.map +1 -1
  49. package/dist/utils/model-extender.js.map +1 -1
  50. package/package.json +4 -3
  51. package/src/analyzer/site-analyzer.ts +3 -1
  52. package/src/config/config-errors.ts +7 -1
  53. package/src/config/config-loader-esbuild.ts +24 -19
  54. package/src/config/config-loader-static.ts +210 -0
  55. package/src/config/config-loader-utils.ts +253 -0
  56. package/src/config/config-loader.ts +209 -236
  57. package/src/config/config-schema/style-field-schema.ts +1 -4
  58. package/src/config/config-schema.ts +17 -18
  59. package/src/config/config-types.ts +31 -2
  60. package/src/config/config-validator.ts +5 -3
  61. package/src/config/config-writer.ts +2 -30
  62. package/src/content/content-schema.ts +17 -18
  63. package/src/index.ts +4 -2
  64. package/src/utils/index.ts +1 -1
  65. package/src/utils/model-extender.ts +2 -2
@@ -25,28 +25,35 @@ Object.defineProperty(exports, "__esModule", { value: true });
25
25
  exports.loadConfigFromDir = exports.validateAndNormalizeConfig = exports.extendConfig = exports.loadConfig = void 0;
26
26
  const path_1 = __importDefault(require("path"));
27
27
  const fs_extra_1 = __importDefault(require("fs-extra"));
28
- const js_yaml_1 = __importDefault(require("js-yaml"));
28
+ const chokidar_1 = __importDefault(require("chokidar"));
29
29
  const semver_1 = __importDefault(require("semver"));
30
30
  const lodash_1 = __importDefault(require("lodash"));
31
+ const utils_1 = require("@stackbit/utils");
31
32
  const config_validator_1 = require("./config-validator");
32
33
  const config_errors_1 = require("./config-errors");
33
34
  const config_loader_esbuild_1 = require("./config-loader-esbuild");
34
- const utils_1 = require("../utils");
35
- const utils_2 = require("@stackbit/utils");
35
+ const utils_2 = require("../utils");
36
36
  const presets_loader_1 = require("./presets-loader");
37
- async function loadConfig({ dirPath, modelsSource, stackbitConfigESBuildOutDir, watchCallback }) {
37
+ const config_loader_utils_1 = require("./config-loader-utils");
38
+ async function loadConfig({ dirPath, modelsSource, stackbitConfigESBuildOutDir, watchCallback, logger }) {
39
+ let wrappedCallback;
40
+ if (watchCallback) {
41
+ wrappedCallback = async (rawConfigResult) => {
42
+ const configLoaderResult = await processConfigLoaderResult({ rawConfigResult, dirPath, modelsSource });
43
+ watchCallback(configLoaderResult);
44
+ };
45
+ }
38
46
  const rawConfigResult = await loadConfigFromDir({
39
47
  dirPath,
40
48
  stackbitConfigESBuildOutDir,
41
- watchCallback: watchCallback
42
- ? async (rawConfigResult) => {
43
- const configLoaderResult = await processConfigLoaderResult({ rawConfigResult, dirPath, modelsSource });
44
- watchCallback(configLoaderResult);
45
- }
46
- : undefined
49
+ watchCallback: wrappedCallback,
50
+ logger
47
51
  });
48
52
  const configLoaderResult = await processConfigLoaderResult({ rawConfigResult, dirPath, modelsSource });
49
- return Object.assign(configLoaderResult, { stop: rawConfigResult.stop });
53
+ return Object.assign(configLoaderResult, {
54
+ stop: rawConfigResult.stop,
55
+ reload: rawConfigResult.reload
56
+ });
50
57
  }
51
58
  exports.loadConfig = loadConfig;
52
59
  async function processConfigLoaderResult({ rawConfigResult, dirPath, modelsSource }) {
@@ -59,16 +66,16 @@ async function processConfigLoaderResult({ rawConfigResult, dirPath, modelsSourc
59
66
  };
60
67
  }
61
68
  const { models: externalModels, errors: externalModelsLoadErrors } = await loadModelsFromExternalSource(config, dirPath, modelsSource);
62
- const extendedConfig = await extendConfig({ dirPath, config, externalModels });
69
+ const extendedConfig = await extendConfig({ config, externalModels });
63
70
  return {
64
71
  valid: extendedConfig.valid,
65
72
  config: extendedConfig.config,
66
73
  errors: [...configLoadErrors, ...externalModelsLoadErrors, ...extendedConfig.errors]
67
74
  };
68
75
  }
69
- async function extendConfig({ dirPath, config, externalModels }) {
76
+ async function extendConfig({ config, externalModels }) {
70
77
  const normalizedResult = validateAndNormalizeConfig(config, externalModels);
71
- const presetsResult = await presets_loader_1.loadPresets(dirPath, normalizedResult.config);
78
+ const presetsResult = await presets_loader_1.loadPresets(config.dirPath, normalizedResult.config);
72
79
  return {
73
80
  valid: normalizedResult.valid,
74
81
  config: presetsResult.config,
@@ -80,7 +87,7 @@ function validateAndNormalizeConfig(config, externalModels) {
80
87
  // extend config models having the "extends" property
81
88
  // this must be done before any validation as some properties like
82
89
  // the labelField will not work when validating models without extending them first
83
- const { models: extendedModels, errors: extendModelErrors } = utils_1.extendModelMap(config.models);
90
+ const { models: extendedModels, errors: extendModelErrors } = utils_2.extendModelMap(config.models);
84
91
  const extendedConfig = {
85
92
  ...config,
86
93
  models: extendedModels
@@ -102,25 +109,71 @@ function validateAndNormalizeConfig(config, externalModels) {
102
109
  });
103
110
  }
104
111
  exports.validateAndNormalizeConfig = validateAndNormalizeConfig;
105
- async function loadConfigFromDir({ dirPath, stackbitConfigESBuildOutDir, watchCallback }) {
106
- var _a;
112
+ async function loadConfigFromDir({ dirPath, stackbitConfigESBuildOutDir, watchCallback, logger }) {
107
113
  // try to load stackbit config from YAML files
108
114
  try {
109
- const stackbitYamlPath = path_1.default.join(dirPath, 'stackbit.yaml');
110
- const stackbitYamlExists = await fs_extra_1.default.pathExists(stackbitYamlPath);
111
- if (stackbitYamlExists) {
112
- const stackbitYamlResult = await loadConfigFromStackbitYaml(stackbitYamlPath);
113
- if (stackbitYamlResult.error) {
114
- return { errors: [stackbitYamlResult.error] };
115
+ const stackbitYamlPath = await utils_1.getFirstExistingFile(config_loader_utils_1.STACKBIT_CONFIG_YAML_FILES, dirPath);
116
+ if (stackbitYamlPath) {
117
+ const { config, errors } = await config_loader_utils_1.loadConfigWithModelsFromDir(dirPath);
118
+ let close = async () => void 0;
119
+ let reload = () => void 0;
120
+ let stopped = false;
121
+ if (watchCallback) {
122
+ const watcher = chokidar_1.default.watch([...config_loader_utils_1.STACKBIT_CONFIG_YAML_FILES, '.stackbit'], {
123
+ cwd: dirPath,
124
+ persistent: true,
125
+ ignoreInitial: true
126
+ });
127
+ const throttledFileChange = lodash_1.default.throttle(async () => {
128
+ const { config, errors } = await config_loader_utils_1.loadConfigWithModelsFromDir(dirPath);
129
+ watchCallback({
130
+ config: config
131
+ ? {
132
+ ...config,
133
+ dirPath: dirPath,
134
+ filePath: stackbitYamlPath
135
+ }
136
+ : undefined,
137
+ errors
138
+ });
139
+ }, 1000);
140
+ const handleFileChange = (path) => {
141
+ logger === null || logger === void 0 ? void 0 : logger.debug(`identified change in stackbit config file: ${path}, reloading config...`);
142
+ throttledFileChange();
143
+ };
144
+ watcher.on('add', handleFileChange);
145
+ watcher.on('change', handleFileChange);
146
+ watcher.on('unlink', handleFileChange);
147
+ watcher.on('addDir', handleFileChange);
148
+ watcher.on('unlinkDir', handleFileChange);
149
+ watcher.on('error', (error) => {
150
+ watchCallback({
151
+ errors: [new config_errors_1.ConfigLoadError(`Error loading Stackbit configuration: ${error.message}`, { originalError: error })]
152
+ });
153
+ });
154
+ close = async () => {
155
+ if (stopped) {
156
+ return;
157
+ }
158
+ stopped = true;
159
+ throttledFileChange.cancel();
160
+ watcher.close();
161
+ };
162
+ reload = () => {
163
+ throttledFileChange();
164
+ };
115
165
  }
116
- const { models: modelsFromFiles, errors: fileModelsErrors } = await loadModelsFromFiles(dirPath, stackbitYamlResult.config);
117
- const mergedModels = mergeConfigModelsWithModelsFromFiles((_a = stackbitYamlResult.config.models) !== null && _a !== void 0 ? _a : {}, modelsFromFiles);
118
166
  return {
119
- config: {
120
- ...stackbitYamlResult.config,
121
- models: mergedModels
122
- },
123
- errors: fileModelsErrors
167
+ config: config
168
+ ? {
169
+ ...config,
170
+ dirPath: dirPath,
171
+ filePath: stackbitYamlPath
172
+ }
173
+ : undefined,
174
+ stop: close,
175
+ reload: reload,
176
+ errors: errors
124
177
  };
125
178
  }
126
179
  }
@@ -129,7 +182,7 @@ async function loadConfigFromDir({ dirPath, stackbitConfigESBuildOutDir, watchCa
129
182
  errors: [new config_errors_1.ConfigLoadError(`Error loading Stackbit configuration: ${error.message}`, { originalError: error })]
130
183
  };
131
184
  }
132
- function wrapResult(result) {
185
+ function wrapResult(result, configFilePath) {
133
186
  if (result.error) {
134
187
  return {
135
188
  errors: [result.error]
@@ -137,26 +190,31 @@ async function loadConfigFromDir({ dirPath, stackbitConfigESBuildOutDir, watchCa
137
190
  }
138
191
  else {
139
192
  return {
140
- config: result.config,
193
+ config: {
194
+ ...result.config,
195
+ dirPath: dirPath,
196
+ filePath: configFilePath
197
+ },
141
198
  errors: []
142
199
  };
143
200
  }
144
201
  }
145
202
  // try to load stackbit config from JavaScript files
146
203
  try {
147
- const configFilePath = await utils_2.getFirstExistingFile(['stackbit.config.js', 'stackbit.config.cjs', 'stackbit.config.mjs', 'stackbit.config.ts'], dirPath);
204
+ const configFilePath = await utils_1.getFirstExistingFile(config_loader_utils_1.STACKBIT_CONFIG_JS_FILES, dirPath);
148
205
  if (configFilePath) {
149
206
  const configResult = await config_loader_esbuild_1.loadStackbitConfigFromJs({
150
207
  configPath: configFilePath,
151
- outDir: stackbitConfigESBuildOutDir,
208
+ outDir: stackbitConfigESBuildOutDir !== null && stackbitConfigESBuildOutDir !== void 0 ? stackbitConfigESBuildOutDir : '.stackbit/cache',
152
209
  watch: !!watchCallback,
210
+ logger: logger,
153
211
  callback: watchCallback
154
212
  ? (result) => {
155
- watchCallback(wrapResult(result));
213
+ watchCallback(wrapResult(result, configFilePath));
156
214
  }
157
215
  : undefined
158
216
  });
159
- return Object.assign(wrapResult(configResult), { stop: configResult.stop });
217
+ return Object.assign(wrapResult(configResult, configFilePath), { stop: configResult.stop });
160
218
  }
161
219
  }
162
220
  catch (error) {
@@ -165,79 +223,15 @@ async function loadConfigFromDir({ dirPath, stackbitConfigESBuildOutDir, watchCa
165
223
  };
166
224
  }
167
225
  return {
168
- errors: [
169
- new config_errors_1.ConfigLoadError('stackbit.yaml or stackbit.config.js was not found, please refer Stackbit documentation: https://www.stackbit.com/docs/stackbit-yaml/')
170
- ]
226
+ errors: [new config_errors_1.ConfigLoadError(config_errors_1.STACKBIT_CONFIG_NOT_FOUND)]
171
227
  };
172
228
  }
173
229
  exports.loadConfigFromDir = loadConfigFromDir;
174
- async function loadConfigFromStackbitYaml(stackbitYamlPath) {
175
- const stackbitYaml = await fs_extra_1.default.readFile(stackbitYamlPath);
176
- const config = js_yaml_1.default.load(stackbitYaml.toString('utf8'), { schema: js_yaml_1.default.JSON_SCHEMA });
177
- if (!config || typeof config !== 'object') {
178
- return {
179
- error: new config_errors_1.ConfigLoadError('error parsing stackbit.yaml, please refer Stackbit documentation: https://www.stackbit.com/docs/stackbit-yaml/')
180
- };
181
- }
182
- return { config };
183
- }
184
- async function loadModelsFromFiles(dirPath, config) {
185
- const modelsSource = lodash_1.default.get(config, 'modelsSource', {});
186
- const sourceType = lodash_1.default.get(modelsSource, 'type', 'files');
187
- const defaultModelDirs = ['node_modules/@stackbit/components/models', '.stackbit/models'];
188
- const modelDirs = sourceType === 'files'
189
- ? lodash_1.default.castArray(lodash_1.default.get(modelsSource, 'modelDirs', defaultModelDirs)).map((modelDir) => lodash_1.default.trim(modelDir, '/'))
190
- : defaultModelDirs;
191
- const modelFiles = await utils_2.reducePromise(modelDirs, async (modelFiles, modelDir) => {
192
- const absModelsDir = path_1.default.join(dirPath, modelDir);
193
- const dirExists = await fs_extra_1.default.pathExists(absModelsDir);
194
- if (!dirExists) {
195
- return modelFiles;
196
- }
197
- const files = await readModelFilesFromDir(absModelsDir);
198
- return modelFiles.concat(files.map((filePath) => path_1.default.join(modelDir, filePath)));
199
- }, []);
200
- return utils_2.reducePromise(modelFiles, async (result, modelFile) => {
201
- let model;
202
- try {
203
- model = await utils_2.parseFile(path_1.default.join(dirPath, modelFile));
204
- }
205
- catch (error) {
206
- return {
207
- models: result.models,
208
- errors: result.errors.concat(new config_errors_1.ConfigLoadError(`error parsing model, file: ${modelFile}`))
209
- };
210
- }
211
- const modelName = model === null || model === void 0 ? void 0 : model.name;
212
- if (!modelName) {
213
- return {
214
- models: result.models,
215
- errors: result.errors.concat(new config_errors_1.ConfigLoadError(`model does not have a name, file: ${modelFile}`))
216
- };
217
- }
218
- result.models[modelName] = lodash_1.default.omit(model, 'name');
219
- result.models[modelName].__metadata = {
220
- filePath: modelFile
221
- };
222
- return result;
223
- }, { models: {}, errors: [] });
224
- }
225
- async function readModelFilesFromDir(modelsDir) {
226
- return await utils_2.readDirRecursively(modelsDir, {
227
- filter: (filePath, stats) => {
228
- if (stats.isDirectory()) {
229
- return true;
230
- }
231
- const extension = path_1.default.extname(filePath).substring(1);
232
- return stats.isFile() && ['yaml', 'yml'].includes(extension);
233
- }
234
- });
235
- }
236
230
  async function loadModelsFromExternalSource(config, dirPath, modelsSource) {
237
- modelsSource = lodash_1.default.assign({}, modelsSource, config.modelSource);
231
+ modelsSource = lodash_1.default.assign({}, modelsSource, config.modelsSource);
238
232
  const sourceType = lodash_1.default.get(modelsSource, 'type', 'files');
239
233
  if (sourceType === 'files') {
240
- // we already loaded models from files inside loadModelsFromFiles function
234
+ // we already loaded models from files inside loadConfigFromDir function
241
235
  return { models: [], errors: [] };
242
236
  }
243
237
  else if (sourceType === 'contentful') {
@@ -291,34 +285,6 @@ async function loadConfigFromDotStackbit(dirPath) {
291
285
  }
292
286
  return lodash_1.default.isEmpty(config) ? null : config;
293
287
  }
294
- function mergeConfigModelsWithModelsFromFiles(configModels, modelsFromFiles) {
295
- const mergedModels = lodash_1.default.mapValues(modelsFromFiles, (modelFromFile, modelName) => {
296
- var _a, _b, _c;
297
- // resolve thumbnails of models loaded from files
298
- const modelFilePath = (_a = modelFromFile.__metadata) === null || _a === void 0 ? void 0 : _a.filePath;
299
- resolveThumbnailPathForModel(modelFromFile, modelFilePath);
300
- utils_1.iterateModelFieldsRecursively(modelFromFile, (field) => {
301
- if (utils_1.isListField(field)) {
302
- field = utils_1.normalizeListFieldInPlace(field);
303
- field = field.items;
304
- }
305
- if (utils_1.isObjectField(field)) {
306
- resolveThumbnailPathForModel(field, modelFilePath);
307
- }
308
- else if (utils_1.isEnumField(field)) {
309
- resolveThumbnailPathForEnumField(field, modelFilePath);
310
- }
311
- });
312
- const configModel = lodash_1.default.get(configModels, modelName);
313
- if (!configModel) {
314
- return modelFromFile;
315
- }
316
- return lodash_1.default.assign({}, modelFromFile, configModel, {
317
- fields: lodash_1.default.unionBy((_b = configModel === null || configModel === void 0 ? void 0 : configModel.fields) !== null && _b !== void 0 ? _b : [], (_c = modelFromFile === null || modelFromFile === void 0 ? void 0 : modelFromFile.fields) !== null && _c !== void 0 ? _c : [], 'name')
318
- });
319
- });
320
- return Object.assign({}, configModels, mergedModels);
321
- }
322
288
  function mergeConfigWithExternalModels(config, externalModels) {
323
289
  var _a;
324
290
  if (!externalModels || externalModels.length === 0) {
@@ -341,12 +307,12 @@ function mergeConfigWithExternalModels(config, externalModels) {
341
307
  }
342
308
  const modelType = stackbitModel.type ? (stackbitModel.type === 'config' ? 'data' : stackbitModel.type) : (_a = externalModel.type) !== null && _a !== void 0 ? _a : 'object';
343
309
  const urlPath = modelType === 'page' ? (_b = stackbitModel === null || stackbitModel === void 0 ? void 0 : stackbitModel.urlPath) !== null && _b !== void 0 ? _b : '/{slug}' : null;
344
- externalModel = Object.assign({}, externalModel, lodash_1.default.pick(stackbitModel, ['__metadata', 'label', 'description', 'thumbnail', 'singleInstance', 'readOnly', 'labelField', 'fieldGroups']), utils_2.omitByNil({
310
+ externalModel = Object.assign({}, externalModel, lodash_1.default.pick(stackbitModel, ['__metadata', 'label', 'description', 'thumbnail', 'singleInstance', 'readOnly', 'labelField', 'fieldGroups']), utils_1.omitByNil({
345
311
  type: modelType,
346
312
  urlPath
347
313
  }));
348
- externalModel = utils_1.mapModelFieldsRecursively(externalModel, (externalField, modelKeyPath) => {
349
- const stackbitField = utils_1.getModelFieldForModelKeyPath(stackbitModel, modelKeyPath);
314
+ externalModel = utils_2.mapModelFieldsRecursively(externalModel, (externalField, modelKeyPath) => {
315
+ const stackbitField = utils_2.getModelFieldForModelKeyPath(stackbitModel, modelKeyPath);
350
316
  if (!stackbitField) {
351
317
  return externalField;
352
318
  }
@@ -384,8 +350,12 @@ function normalizeConfig(config) {
384
350
  const stackbitYamlVersion = String(lodash_1.default.get(config, 'stackbitVersion', ''));
385
351
  const ver = semver_1.default.coerce(stackbitYamlVersion);
386
352
  const isStackbitYamlV2 = ver ? semver_1.default.satisfies(ver, '<0.3.0') : false;
353
+ const isStackbitYamlV5 = ver ? semver_1.default.satisfies(ver, '>=0.5.0') : false;
387
354
  const models = (config === null || config === void 0 ? void 0 : config.models) || {};
388
355
  const gitCMS = isGitCMS(config);
356
+ utils_1.rename(config, 'logicFields', 'noEncodeFields');
357
+ config.hcrHandled = !stackbitYamlVersion || lodash_1.default.get(config, 'customContentReload', lodash_1.default.get(config, 'hcrHandled', !isStackbitYamlV5));
358
+ config.internalStackbitRunnerOptions = getInternalStackbitRunnerOptions(config);
389
359
  lodash_1.default.forEach(models, (model, modelName) => {
390
360
  if (!model) {
391
361
  return;
@@ -400,54 +370,54 @@ function normalizeConfig(config) {
400
370
  if (lodash_1.default.has(model, 'fields') && !Array.isArray(model.fields)) {
401
371
  model.fields = [];
402
372
  }
403
- if (utils_1.isPageModel(model)) {
373
+ if (utils_2.isPageModel(model)) {
404
374
  // rename old 'template' property to 'layout'
405
- utils_2.rename(model, 'template', 'layout');
375
+ utils_1.rename(model, 'template', 'layout');
406
376
  updatePageUrlPath(model);
407
377
  if (gitCMS) {
408
378
  updatePageFilePath(model, config);
409
379
  addMarkdownContentField(model);
410
380
  }
411
381
  }
412
- else if (utils_1.isDataModel(model) && gitCMS) {
382
+ else if (utils_2.isDataModel(model) && gitCMS) {
413
383
  updateDataFilePath(model, config);
414
384
  }
415
385
  if (gitCMS) {
416
386
  // TODO: do not add pageLayoutKey and objectTypeKey fields to models,
417
387
  // The content validator should always assume these fields.
418
388
  // And when new objects created from UI, it should add these fields automatically.
419
- if (utils_1.isPageModel(model)) {
389
+ if (utils_2.isPageModel(model)) {
420
390
  addLayoutFieldToPageModel(model, pageLayoutKey, modelName);
421
391
  }
422
- else if (utils_1.isDataModel(model) && !utils_1.isListDataModel(model)) {
392
+ else if (utils_2.isDataModel(model) && !utils_2.isListDataModel(model)) {
423
393
  addObjectTypeKeyField(model, objectTypeKey, modelName);
424
394
  }
425
395
  }
426
- if (utils_1.isListDataModel(model)) {
396
+ if (utils_2.isListDataModel(model)) {
427
397
  // 'items.type' of list model defaults to 'string', set it explicitly
428
398
  if (!lodash_1.default.has(model, 'items.type')) {
429
399
  lodash_1.default.set(model, 'items.type', 'string');
430
400
  }
431
- if (utils_1.isObjectListItems(model.items)) {
432
- utils_1.assignLabelFieldIfNeeded(model.items);
401
+ if (utils_2.isObjectListItems(model.items)) {
402
+ utils_2.assignLabelFieldIfNeeded(model.items);
433
403
  }
434
404
  }
435
405
  else if (!lodash_1.default.has(model, 'labelField')) {
436
- utils_1.assignLabelFieldIfNeeded(model);
406
+ utils_2.assignLabelFieldIfNeeded(model);
437
407
  }
438
- utils_1.iterateModelFieldsRecursively(model, (field) => {
408
+ utils_2.iterateModelFieldsRecursively(model, (field) => {
439
409
  // add field label if label is not set
440
410
  if (!lodash_1.default.has(field, 'label')) {
441
411
  field.label = lodash_1.default.startCase(field.name);
442
412
  }
443
- if (utils_1.isListField(field)) {
444
- field = utils_1.normalizeListFieldInPlace(field);
413
+ if (utils_2.isListField(field)) {
414
+ field = utils_2.normalizeListFieldInPlace(field);
445
415
  field = field.items;
446
416
  }
447
- if (utils_1.isObjectField(field)) {
448
- utils_1.assignLabelFieldIfNeeded(field);
417
+ if (utils_2.isObjectField(field)) {
418
+ utils_2.assignLabelFieldIfNeeded(field);
449
419
  }
450
- else if (utils_1.isCustomModelField(field, models)) {
420
+ else if (utils_2.isCustomModelField(field, models)) {
451
421
  // stackbit v0.2.0 compatibility
452
422
  // convert the old custom model field type: { type: 'action' }
453
423
  // to the new 'model' field type: { type: 'model', models: ['action'] }
@@ -470,7 +440,7 @@ function normalizeConfig(config) {
470
440
  }
471
441
  if (isStackbitYamlV2) {
472
442
  // in stackbit.yaml v0.2.x, the 'reference' field was what we have today as 'model' field:
473
- if (utils_1.isReferenceField(field)) {
443
+ if (utils_2.isReferenceField(field)) {
474
444
  field = field;
475
445
  field.type = 'model';
476
446
  field.models = lodash_1.default.get(field, 'models', []);
@@ -540,7 +510,7 @@ function addMarkdownContentField(model) {
540
510
  if (hasMarkdownContent) {
541
511
  return;
542
512
  }
543
- utils_2.append(model, 'fields', {
513
+ utils_1.append(model, 'fields', {
544
514
  type: 'markdown',
545
515
  name: 'markdown_content',
546
516
  label: 'Content',
@@ -559,7 +529,7 @@ function addLayoutFieldToPageModel(model, pageLayoutKey, modelName) {
559
529
  if (hasLayoutField) {
560
530
  return;
561
531
  }
562
- utils_2.prepend(model, 'fields', {
532
+ utils_1.prepend(model, 'fields', {
563
533
  type: 'string',
564
534
  name: pageLayoutKey,
565
535
  label: lodash_1.default.startCase(pageLayoutKey),
@@ -572,7 +542,7 @@ function addObjectTypeKeyField(model, objectTypeKey, modelName) {
572
542
  if (hasObjectTypeField) {
573
543
  return;
574
544
  }
575
- utils_2.prepend(model, 'fields', {
545
+ utils_1.prepend(model, 'fields', {
576
546
  type: 'string',
577
547
  name: objectTypeKey,
578
548
  label: 'Object Type',
@@ -581,37 +551,6 @@ function addObjectTypeKeyField(model, objectTypeKey, modelName) {
581
551
  hidden: true
582
552
  });
583
553
  }
584
- function resolveThumbnailPathForModel(modelOrField, modelFilePath) {
585
- if (modelOrField.thumbnail && modelFilePath) {
586
- const modelDirPath = path_1.default.dirname(modelFilePath);
587
- modelOrField.thumbnail = resolveThumbnailPath(modelOrField.thumbnail, modelDirPath);
588
- }
589
- }
590
- function resolveThumbnailPathForEnumField(enumField, modelFilePath) {
591
- if (enumField.controlType === 'thumbnails' && modelFilePath) {
592
- const modelDirPath = path_1.default.dirname(modelFilePath);
593
- lodash_1.default.forEach(enumField.options, (option) => {
594
- if (option.thumbnail) {
595
- option.thumbnail = resolveThumbnailPath(option.thumbnail, modelDirPath);
596
- }
597
- });
598
- }
599
- }
600
- function resolveThumbnailPath(thumbnail, modelDirPath) {
601
- if (thumbnail.startsWith('//') || /https?:\/\//.test(thumbnail)) {
602
- return thumbnail;
603
- }
604
- if (thumbnail.startsWith('/')) {
605
- if (modelDirPath.endsWith('@stackbit/components/models')) {
606
- modelDirPath = modelDirPath.replace(/\/models$/, '');
607
- }
608
- else {
609
- modelDirPath = '';
610
- }
611
- thumbnail = thumbnail.replace(/^\//, '');
612
- }
613
- return path_1.default.join(modelDirPath, thumbnail);
614
- }
615
554
  /**
616
555
  * Returns model names referenced by polymorphic 'model' and 'reference' fields.
617
556
  * That is, fields that can hold objects of different types.
@@ -620,19 +559,19 @@ function resolveThumbnailPath(thumbnail, modelDirPath) {
620
559
  */
621
560
  function getReferencedModelNames(field) {
622
561
  var _a, _b;
623
- if (utils_1.isListField(field)) {
624
- field = utils_1.getListFieldItems(field);
562
+ if (utils_2.isListField(field)) {
563
+ field = utils_2.getListFieldItems(field);
625
564
  }
626
565
  // TODO: add type field to model fields inside container update/create object logic rather adding type to schema
627
566
  // 'object' models referenced by 'model' fields should have 'type' field
628
567
  // if these fields have than 1 model.
629
568
  // 'data' models referenced by 'reference' fields should always have 'type' field.
630
569
  let referencedModelNames = [];
631
- if (utils_1.isModelField(field) && ((_a = field.models) === null || _a === void 0 ? void 0 : _a.length) > 1) {
570
+ if (utils_2.isModelField(field) && ((_a = field.models) === null || _a === void 0 ? void 0 : _a.length) > 1) {
632
571
  const modelNames = field.models;
633
572
  referencedModelNames = lodash_1.default.union(referencedModelNames, modelNames);
634
573
  }
635
- else if (utils_1.isReferenceField(field) && ((_b = field.models) === null || _b === void 0 ? void 0 : _b.length) > 0) {
574
+ else if (utils_2.isReferenceField(field) && ((_b = field.models) === null || _b === void 0 ? void 0 : _b.length) > 0) {
636
575
  const modelNames = field.models;
637
576
  referencedModelNames = lodash_1.default.union(referencedModelNames, modelNames);
638
577
  }
@@ -702,7 +641,7 @@ function normalizeValidationResult(validationResult) {
702
641
  return convertModelsToArray(validationResult);
703
642
  }
704
643
  function filterAndOrderConfigFields(validationResult) {
705
- // TODO: see if we move filtering and sorting to Joi
644
+ // TODO: check if we can move filtering and sorting to Joi
706
645
  return {
707
646
  ...validationResult,
708
647
  value: lodash_1.default.pick(validationResult.value, [
@@ -714,6 +653,9 @@ function filterAndOrderConfigFields(validationResult) {
714
653
  'buildCommand',
715
654
  'publishDir',
716
655
  'nodeVersion',
656
+ 'postGitCloneCommand',
657
+ 'preInstallCommand',
658
+ 'postInstallCommand',
717
659
  'devCommand',
718
660
  'staticDir',
719
661
  'uploadDir',
@@ -728,11 +670,29 @@ function filterAndOrderConfigFields(validationResult) {
728
670
  'contentModels',
729
671
  'presetSource',
730
672
  'modelsSource',
673
+ 'mapModels',
674
+ 'presetReferenceBehavior',
675
+ 'nonDuplicatableModels',
676
+ 'duplicatableModels',
677
+ 'contentSources',
678
+ 'hcrHandled',
679
+ 'internalStackbitRunnerOptions',
680
+ 'dirPath',
681
+ 'filePath',
731
682
  'models',
732
- 'presets'
683
+ 'presets',
684
+ 'pageData',
685
+ 'pageModels',
686
+ 'encodedFieldTypes',
687
+ 'noEncodeFields',
688
+ 'omitFields' // obsolete, left for backward compatibility
733
689
  ])
734
690
  };
735
691
  }
692
+ /**
693
+ * Collects models groups and injects them into the `models` array of the
694
+ * `reference` and `model` field types
695
+ */
736
696
  function convertModelGroupsToModelList(validationResult) {
737
697
  var _a, _b;
738
698
  const models = (_b = (_a = validationResult.value) === null || _a === void 0 ? void 0 : _a.models) !== null && _b !== void 0 ? _b : {};
@@ -742,7 +702,7 @@ function convertModelGroupsToModelList(validationResult) {
742
702
  }
743
703
  const key = (model === null || model === void 0 ? void 0 : model.type) === 'object' ? 'objectModels' : 'documentModels';
744
704
  lodash_1.default.forEach(model.groups, (groupName) => {
745
- utils_2.append(groupMap, [groupName, key], modelName);
705
+ utils_1.append(groupMap, [groupName, key], modelName);
746
706
  });
747
707
  delete model.groups;
748
708
  return groupMap;
@@ -754,16 +714,16 @@ function convertModelGroupsToModelList(validationResult) {
754
714
  });
755
715
  });
756
716
  lodash_1.default.forEach(models, (model) => {
757
- utils_1.iterateModelFieldsRecursively(model, (field) => {
758
- if (utils_1.isListField(field)) {
717
+ utils_2.iterateModelFieldsRecursively(model, (field) => {
718
+ if (utils_2.isListField(field)) {
759
719
  field = field.items;
760
720
  }
761
721
  if (field.groups) {
762
722
  let key = null;
763
- if (utils_1.isModelField(field)) {
723
+ if (utils_2.isModelField(field)) {
764
724
  key = 'objectModels';
765
725
  }
766
- else if (utils_1.isReferenceField(field)) {
726
+ else if (utils_2.isReferenceField(field)) {
767
727
  key = 'documentModels';
768
728
  }
769
729
  if (key) {
@@ -778,12 +738,12 @@ function convertModelGroupsToModelList(validationResult) {
778
738
  });
779
739
  }
780
740
  function convertModelsToArray(validationResult) {
781
- var _a;
782
741
  const config = validationResult.value;
742
+ const { stackbitVersion = config_loader_utils_1.LATEST_STACKBIT_VERSION, models, ...rest } = config;
783
743
  // in stackbit.yaml 'models' are defined as object where keys are the model names,
784
744
  // convert 'models' to array of objects and set their 'name' property to the
785
745
  // model name
786
- const modelMap = (_a = config.models) !== null && _a !== void 0 ? _a : {};
746
+ const modelMap = models !== null && models !== void 0 ? models : {};
787
747
  const modelArray = lodash_1.default.map(modelMap, (yamlModel, modelName) => {
788
748
  return {
789
749
  name: modelName,
@@ -806,7 +766,8 @@ function convertModelsToArray(validationResult) {
806
766
  return {
807
767
  valid: validationResult.valid,
808
768
  config: {
809
- ...config,
769
+ stackbitVersion,
770
+ ...rest,
810
771
  models: modelArray
811
772
  },
812
773
  errors: convertedErrors
@@ -827,4 +788,19 @@ function addImageModel(models) {
827
788
  function isGitCMS(config) {
828
789
  return !config.cmsName || config.cmsName === 'git';
829
790
  }
791
+ function getInternalStackbitRunnerOptions(config) {
792
+ const experimentalSsgData = lodash_1.default.get(config, 'experimental.ssg');
793
+ if (!experimentalSsgData) {
794
+ return lodash_1.default.get(config, '__unsafe_internal_stackbitRunnerOptions');
795
+ }
796
+ const doneStart = lodash_1.default.get(experimentalSsgData, 'logPatterns.up');
797
+ return {
798
+ displayName: experimentalSsgData.name || 'ssg',
799
+ triggerInstallFiles: lodash_1.default.get(experimentalSsgData, 'watch.reinstallPackages', ['package.json', 'package-lock.json']),
800
+ directPaths: experimentalSsgData.passthrough || [],
801
+ patterns: {
802
+ doneStart: lodash_1.default.isEmpty(doneStart) || lodash_1.default.isArray(doneStart) ? doneStart : [doneStart]
803
+ }
804
+ };
805
+ }
830
806
  //# sourceMappingURL=config-loader.js.map