@stackbit/sdk 0.2.33 → 0.2.36-alpha.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.
- package/dist/analyzer/analyze-schema-types.d.ts +1 -0
- package/dist/analyzer/analyze-schema-types.d.ts.map +1 -0
- package/dist/analyzer/analyzer-utils.d.ts +1 -0
- package/dist/analyzer/analyzer-utils.d.ts.map +1 -0
- package/dist/analyzer/cms-matcher.d.ts +1 -0
- package/dist/analyzer/cms-matcher.d.ts.map +1 -0
- package/dist/analyzer/file-browser.d.ts +1 -0
- package/dist/analyzer/file-browser.d.ts.map +1 -0
- package/dist/analyzer/schema-generator.d.ts +1 -0
- package/dist/analyzer/schema-generator.d.ts.map +1 -0
- package/dist/analyzer/site-analyzer.d.ts +1 -0
- package/dist/analyzer/site-analyzer.d.ts.map +1 -0
- package/dist/analyzer/ssg-matcher.d.ts +1 -0
- package/dist/analyzer/ssg-matcher.d.ts.map +1 -0
- package/dist/config/config-consts.d.ts +1 -0
- package/dist/config/config-consts.d.ts.map +1 -0
- package/dist/config/config-errors.d.ts +1 -0
- package/dist/config/config-errors.d.ts.map +1 -0
- package/dist/config/config-loader-esbuild.d.ts +1 -0
- package/dist/config/config-loader-esbuild.d.ts.map +1 -0
- package/dist/config/config-loader-esbuild.js +1 -1
- package/dist/config/config-loader-esbuild.js.map +1 -1
- package/dist/config/config-loader.d.ts +16 -1
- package/dist/config/config-loader.d.ts.map +1 -0
- package/dist/config/config-loader.js +14 -4
- package/dist/config/config-loader.js.map +1 -1
- package/dist/config/config-schema/style-field-schema.d.ts +1 -0
- package/dist/config/config-schema/style-field-schema.d.ts.map +1 -0
- package/dist/config/config-schema.d.ts +1 -0
- package/dist/config/config-schema.d.ts.map +1 -0
- package/dist/config/config-schema.js +11 -1
- package/dist/config/config-schema.js.map +1 -1
- package/dist/config/config-types.d.ts +11 -1
- package/dist/config/config-types.d.ts.map +1 -0
- package/dist/config/config-validator.d.ts +1 -0
- package/dist/config/config-validator.d.ts.map +1 -0
- package/dist/config/config-writer.d.ts +1 -0
- package/dist/config/config-writer.d.ts.map +1 -0
- package/dist/config/presets-loader.d.ts +1 -0
- package/dist/config/presets-loader.d.ts.map +1 -0
- package/dist/config/presets-loader.js +6 -5
- package/dist/config/presets-loader.js.map +1 -1
- package/dist/consts.d.ts +1 -0
- package/dist/consts.d.ts.map +1 -0
- package/dist/content/content-errors.d.ts +1 -0
- package/dist/content/content-errors.d.ts.map +1 -0
- package/dist/content/content-loader.d.ts +1 -0
- package/dist/content/content-loader.d.ts.map +1 -0
- package/dist/content/content-schema.d.ts +1 -0
- package/dist/content/content-schema.d.ts.map +1 -0
- package/dist/content/content-validator.d.ts +1 -0
- package/dist/content/content-validator.d.ts.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/utils/index.d.ts +2 -1
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/model-extender.d.ts +1 -0
- package/dist/utils/model-extender.d.ts.map +1 -0
- package/dist/utils/model-iterators.d.ts +20 -0
- package/dist/utils/model-iterators.d.ts.map +1 -0
- package/dist/utils/model-iterators.js +99 -1
- package/dist/utils/model-iterators.js.map +1 -1
- package/dist/utils/model-matcher.d.ts +1 -0
- package/dist/utils/model-matcher.d.ts.map +1 -0
- package/dist/utils/model-utils.d.ts +1 -0
- package/dist/utils/model-utils.d.ts.map +1 -0
- package/package.json +3 -3
- package/src/config/config-loader-esbuild.ts +1 -1
- package/src/config/config-loader.ts +31 -6
- package/src/config/config-schema.ts +11 -1
- package/src/config/config-types.ts +21 -1
- package/src/config/presets-loader.ts +21 -9
- package/src/index.ts +1 -1
- package/src/utils/index.ts +1 -1
- package/src/utils/model-iterators.ts +145 -0
|
@@ -3,7 +3,7 @@ import path from 'path';
|
|
|
3
3
|
import fse from 'fs-extra';
|
|
4
4
|
import { parseFile, append } from '@stackbit/utils';
|
|
5
5
|
|
|
6
|
-
import { Config } from './config-types';
|
|
6
|
+
import { Config, Preset } from './config-types';
|
|
7
7
|
import { ConfigPresetsError } from './config-errors';
|
|
8
8
|
|
|
9
9
|
export interface PresetsLoaderResult {
|
|
@@ -11,6 +11,17 @@ export interface PresetsLoaderResult {
|
|
|
11
11
|
errors: ConfigPresetsError[];
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
interface RawPresetData {
|
|
15
|
+
model: string;
|
|
16
|
+
presets: RawPreset[];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface RawPreset {
|
|
20
|
+
label: string;
|
|
21
|
+
thumbnail?: string;
|
|
22
|
+
data: Record<string, any>;
|
|
23
|
+
}
|
|
24
|
+
|
|
14
25
|
export async function loadPresets(dirPath: string, config: Config): Promise<PresetsLoaderResult> {
|
|
15
26
|
const presetFiles = [];
|
|
16
27
|
const presetsRelDirs = ['.stackbit/presets', 'node_modules/@stackbit/components/presets'];
|
|
@@ -26,14 +37,14 @@ export async function loadPresets(dirPath: string, config: Config): Promise<Pres
|
|
|
26
37
|
presetFiles.push(...files);
|
|
27
38
|
}
|
|
28
39
|
|
|
29
|
-
const presets: Record<string,
|
|
30
|
-
const presetsIdsByModel: Record<string,
|
|
40
|
+
const presets: Record<string, Preset> = {};
|
|
41
|
+
const presetsIdsByModel: Record<string, string[]> = {};
|
|
31
42
|
const errors: ConfigPresetsError[] = [];
|
|
32
43
|
|
|
33
44
|
for (const presetFile of presetFiles) {
|
|
34
45
|
const presetsRelDir = path.dirname(presetFile);
|
|
35
46
|
const presetPath = path.join(dirPath, presetFile);
|
|
36
|
-
let presetData:
|
|
47
|
+
let presetData: RawPresetData;
|
|
37
48
|
try {
|
|
38
49
|
presetData = await parseFile(presetPath);
|
|
39
50
|
} catch (err: any) {
|
|
@@ -42,11 +53,12 @@ export async function loadPresets(dirPath: string, config: Config): Promise<Pres
|
|
|
42
53
|
}
|
|
43
54
|
_.forEach(_.get(presetData, 'presets', []), (preset, i) => {
|
|
44
55
|
const presetId = `${presetFile}:presets[${i}]`;
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
56
|
+
const { thumbnail, ...rest } = preset;
|
|
57
|
+
presets[presetId] = {
|
|
58
|
+
...rest,
|
|
59
|
+
...(thumbnail ? { thumbnail: resolveThumbnailPath(thumbnail, presetsRelDir) } : null),
|
|
60
|
+
modelName: presetData.model
|
|
61
|
+
};
|
|
50
62
|
append(presetsIdsByModel, presetData.model, presetId);
|
|
51
63
|
});
|
|
52
64
|
}
|
package/src/index.ts
CHANGED
|
@@ -5,7 +5,7 @@ export * from './content/content-errors';
|
|
|
5
5
|
export * from './config/config-errors';
|
|
6
6
|
export * from './analyzer/file-browser';
|
|
7
7
|
export * from './utils';
|
|
8
|
-
export { loadConfig, ConfigLoaderOptions, ConfigLoaderResult } from './config/config-loader';
|
|
8
|
+
export { loadConfig, loadConfigFromDir, extendConfig, ConfigLoaderOptions, ConfigLoaderResult } from './config/config-loader';
|
|
9
9
|
export { writeConfig, WriteConfigOptions, convertToYamlConfig } from './config/config-writer';
|
|
10
10
|
export { loadContent, ContentItem, ContentLoaderOptions, ContentLoaderResult } from './content/content-loader';
|
|
11
11
|
export { matchSSG, SSGMatcherOptions, SSGMatchResult } from './analyzer/ssg-matcher';
|
package/src/utils/index.ts
CHANGED
|
@@ -9,7 +9,7 @@ type StricterUnionMember<T, Union, Keys extends string = UnionKeys<Union> extend
|
|
|
9
9
|
|
|
10
10
|
export type StricterUnion<Union, Union2 = Union> = Union2 extends any ? StricterUnionMember<Union2, Union> : never;
|
|
11
11
|
|
|
12
|
-
export type Logger = Pick<Console, 'log' | 'info' | 'warn' | 'error' | 'group' | 'groupEnd'>;
|
|
12
|
+
export type Logger = Pick<Console, 'log' | 'debug' | 'info' | 'warn' | 'error' | 'group' | 'groupEnd'>;
|
|
13
13
|
|
|
14
14
|
export * from './model-utils';
|
|
15
15
|
export * from './model-matcher';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import _ from 'lodash';
|
|
2
2
|
|
|
3
|
+
import { mapPromise, mapValuesPromise } from '@stackbit/utils';
|
|
3
4
|
import { getListFieldItems, isListDataModel, isListField, isObjectListItems, isModelField, isObjectField, isModelListItems } from './model-utils';
|
|
4
5
|
import { DataModel, Field, FieldList, FieldListItems, FieldModelProps, FieldObjectProps, Model } from '../config/config-types';
|
|
5
6
|
|
|
@@ -366,6 +367,150 @@ export function mapObjectFieldsWithModelRecursively(
|
|
|
366
367
|
});
|
|
367
368
|
}
|
|
368
369
|
|
|
370
|
+
export async function asyncMapObjectFieldsWithModelRecursively({
|
|
371
|
+
value,
|
|
372
|
+
model,
|
|
373
|
+
modelsByName,
|
|
374
|
+
iteratee,
|
|
375
|
+
pageLayoutKey = 'layout',
|
|
376
|
+
objectTypeKey = 'type',
|
|
377
|
+
valueId
|
|
378
|
+
}: {
|
|
379
|
+
value: any;
|
|
380
|
+
model: Model;
|
|
381
|
+
modelsByName: Record<string, Model>;
|
|
382
|
+
iteratee: (options: {
|
|
383
|
+
value: any;
|
|
384
|
+
model: Model | null;
|
|
385
|
+
field: Field | null;
|
|
386
|
+
fieldListItem: FieldListItems | null;
|
|
387
|
+
error: string | null;
|
|
388
|
+
valueKeyPath: (string | number)[];
|
|
389
|
+
modelKeyPath: string[];
|
|
390
|
+
objectStack: any[];
|
|
391
|
+
skipNested: () => void;
|
|
392
|
+
}) => Promise<any>;
|
|
393
|
+
pageLayoutKey?: string;
|
|
394
|
+
objectTypeKey?: string;
|
|
395
|
+
valueId?: string;
|
|
396
|
+
}): Promise<any> {
|
|
397
|
+
async function _mapDeep({
|
|
398
|
+
value,
|
|
399
|
+
model,
|
|
400
|
+
field,
|
|
401
|
+
fieldListItem,
|
|
402
|
+
valueKeyPath,
|
|
403
|
+
modelKeyPath,
|
|
404
|
+
objectStack
|
|
405
|
+
}: {
|
|
406
|
+
value: any;
|
|
407
|
+
model: Model | null;
|
|
408
|
+
field: Field | null;
|
|
409
|
+
fieldListItem: FieldListItems | null;
|
|
410
|
+
valueKeyPath: (string | number)[];
|
|
411
|
+
modelKeyPath: string[];
|
|
412
|
+
objectStack: any[];
|
|
413
|
+
}) {
|
|
414
|
+
let error: string | null = null;
|
|
415
|
+
let modelField: FieldModelProps | null = null;
|
|
416
|
+
|
|
417
|
+
if (!model && !field && !fieldListItem) {
|
|
418
|
+
error = `could not match model/field ${modelKeyPath.join('.')} to content at ${valueKeyPath.join('.')}`;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
if (field && isModelField(field)) {
|
|
422
|
+
modelField = field;
|
|
423
|
+
} else if (fieldListItem && isModelListItems(fieldListItem)) {
|
|
424
|
+
modelField = fieldListItem;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
if (modelField) {
|
|
428
|
+
const modelResult = getModelOfObject({
|
|
429
|
+
object: value,
|
|
430
|
+
field: modelField,
|
|
431
|
+
modelsByName,
|
|
432
|
+
pageLayoutKey,
|
|
433
|
+
objectTypeKey,
|
|
434
|
+
valueKeyPath,
|
|
435
|
+
modelKeyPath
|
|
436
|
+
});
|
|
437
|
+
if ('error' in modelResult) {
|
|
438
|
+
error = modelResult.error;
|
|
439
|
+
} else {
|
|
440
|
+
model = modelResult.model;
|
|
441
|
+
}
|
|
442
|
+
field = null;
|
|
443
|
+
fieldListItem = null;
|
|
444
|
+
modelKeyPath = model ? [model.name] : [];
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
let shouldSkipNested = false;
|
|
448
|
+
const skipNested = () => {
|
|
449
|
+
shouldSkipNested = true;
|
|
450
|
+
};
|
|
451
|
+
|
|
452
|
+
const res = await iteratee({ value, model, field, fieldListItem, error, valueKeyPath, modelKeyPath, objectStack, skipNested });
|
|
453
|
+
if (!_.isUndefined(res)) {
|
|
454
|
+
value = res;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
if (shouldSkipNested) {
|
|
458
|
+
return value;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
if (_.isPlainObject(value)) {
|
|
462
|
+
// if fields will not be resolved or the object will have a key that
|
|
463
|
+
// doesn't exist among fields, the nested calls to _iterateDeep will
|
|
464
|
+
// include an error.
|
|
465
|
+
const fields = getFieldsOfModelOrField(model, field, fieldListItem);
|
|
466
|
+
const fieldsByName = _.keyBy(fields, 'name');
|
|
467
|
+
modelKeyPath = _.concat(modelKeyPath, 'fields');
|
|
468
|
+
value = await mapValuesPromise(value, (val, key) => {
|
|
469
|
+
const field = _.get(fieldsByName, key, null);
|
|
470
|
+
return _mapDeep({
|
|
471
|
+
value: val,
|
|
472
|
+
model: null,
|
|
473
|
+
field: field,
|
|
474
|
+
fieldListItem: null,
|
|
475
|
+
valueKeyPath: _.concat(valueKeyPath, key),
|
|
476
|
+
modelKeyPath: _.concat(modelKeyPath, key),
|
|
477
|
+
objectStack: _.concat(objectStack, value)
|
|
478
|
+
});
|
|
479
|
+
});
|
|
480
|
+
} else if (_.isArray(value)) {
|
|
481
|
+
let fieldListItems: FieldListItems | null = null;
|
|
482
|
+
if (field && isListField(field)) {
|
|
483
|
+
fieldListItems = getListFieldItems(field);
|
|
484
|
+
} else if (model && isListDataModel(model)) {
|
|
485
|
+
fieldListItems = model.items;
|
|
486
|
+
}
|
|
487
|
+
value = await mapPromise(value, (val, idx) => {
|
|
488
|
+
return _mapDeep({
|
|
489
|
+
value: val,
|
|
490
|
+
model: null,
|
|
491
|
+
field: null,
|
|
492
|
+
fieldListItem: fieldListItems,
|
|
493
|
+
valueKeyPath: _.concat(valueKeyPath, idx),
|
|
494
|
+
modelKeyPath: _.concat(modelKeyPath, 'items'),
|
|
495
|
+
objectStack: _.concat(objectStack, value)
|
|
496
|
+
});
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
return value;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
return _mapDeep({
|
|
504
|
+
value: value,
|
|
505
|
+
model: model,
|
|
506
|
+
field: null,
|
|
507
|
+
fieldListItem: null,
|
|
508
|
+
valueKeyPath: valueId ? [valueId] : [],
|
|
509
|
+
modelKeyPath: [model.name],
|
|
510
|
+
objectStack: []
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
|
|
369
514
|
export function getModelOfObject({
|
|
370
515
|
object,
|
|
371
516
|
field,
|