@stackbit/sdk 0.3.15 → 0.3.16-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.
@@ -16,7 +16,8 @@ import {
16
16
  Field,
17
17
  FieldObjectProps,
18
18
  FieldGroupItem,
19
- FieldSpecificProps
19
+ FieldSpecificProps,
20
+ FieldCrossReferenceModel
20
21
  } from '@stackbit/types';
21
22
 
22
23
  import { CMS_NAMES, FIELD_TYPES, SSG_NAMES } from './config-consts';
@@ -75,6 +76,21 @@ const validReferenceModelNames = Joi.custom((value, { error, state }) => {
75
76
  errors: { wrap: { label: false } }
76
77
  });
77
78
 
79
+ const validCrossReferenceModelNames = Joi.object<FieldCrossReferenceModel>({
80
+ modelName: Joi.string().required(),
81
+ srcType: Joi.string(),
82
+ srcProjectId: Joi.string()
83
+ }).custom((allowedModels, { error, state }) => {
84
+ // TODO: implement custom validation logic that checks unambiguous model matching
85
+ // similar to how config models are matched to content-source models in content-store.ts
86
+ return allowedModels;
87
+ }).prefs({
88
+ messages: {
89
+ [documentModelNameErrorCode]: '{{#label}} must reference the name of an existing model of type "page" or "data", got "{{#value}}"'
90
+ },
91
+ errors: { wrap: { label: false } }
92
+ });
93
+
78
94
  const groupNotFoundErrorCode = 'group.not.found';
79
95
  const groupNotObjectModelErrorCode = 'group.not.object.model';
80
96
  const validModelFieldGroups = Joi.string()
@@ -152,7 +168,7 @@ const labelFieldSchema = Joi.custom((value, { error, state }) => {
152
168
  if (!field) {
153
169
  return error(labelFieldNotFoundError);
154
170
  }
155
- if (['object', 'model', 'reference', 'list'].includes(field.type)) {
171
+ if (['object', 'model', 'reference', 'cross-reference', 'list'].includes(field.type)) {
156
172
  return error(labelFieldNotSimple, { fieldType: field.type });
157
173
  }
158
174
  return value;
@@ -429,6 +445,11 @@ const referenceFieldPartialSchema = Joi.object({
429
445
  groups: Joi.array().items(validReferenceFieldGroups)
430
446
  });
431
447
 
448
+ const crossReferenceFieldPartialSchema = Joi.object({
449
+ type: Joi.string().valid('cross-reference').required(),
450
+ models: Joi.array().items(validCrossReferenceModelNames).required()
451
+ });
452
+
432
453
  const listItemsSchema = Joi.object({
433
454
  // 'style' and 'list' are not allowed inside lists
434
455
  type: Joi.string()
@@ -441,7 +462,8 @@ const listItemsSchema = Joi.object({
441
462
  { is: 'image', then: imageFieldPartialSchema },
442
463
  { is: 'object', then: objectFieldPartialSchema },
443
464
  { is: 'model', then: modelFieldPartialSchema },
444
- { is: 'reference', then: referenceFieldPartialSchema }
465
+ { is: 'reference', then: referenceFieldPartialSchema },
466
+ { is: 'cross-reference', then: crossReferenceFieldPartialSchema },
445
467
  ]
446
468
  });
447
469
 
@@ -467,6 +489,7 @@ const fieldSchema: Joi.ObjectSchema<Field> = fieldCommonPropsSchema.when('.type'
467
489
  { is: 'object', then: objectFieldPartialSchema },
468
490
  { is: 'model', then: modelFieldPartialSchema },
469
491
  { is: 'reference', then: referenceFieldPartialSchema },
492
+ { is: 'cross-reference', then: crossReferenceFieldPartialSchema },
470
493
  { is: 'style', then: styleFieldPartialSchema },
471
494
  { is: 'list', then: listFieldPartialSchema }
472
495
  ]
@@ -54,6 +54,7 @@ export {
54
54
  FieldGroupItem,
55
55
  FieldModelProps,
56
56
  FieldReferenceProps,
57
+ FieldCrossReferenceProps,
57
58
  StyleProps,
58
59
  FieldStyleProps,
59
60
  FieldListProps,
@@ -21,6 +21,7 @@ import {
21
21
  Model,
22
22
  StyleProps
23
23
  } from '../config/config-types';
24
+ import { FieldCrossReferenceProps } from '@stackbit/types';
24
25
 
25
26
  type FieldPath = (string | number)[];
26
27
 
@@ -147,6 +148,9 @@ function joiSchemaForField(field: Field | FieldListItems, config: Config, fieldP
147
148
  case 'reference':
148
149
  fieldSchema = referenceFieldValueSchema(field);
149
150
  break;
151
+ case 'cross-reference':
152
+ fieldSchema = crossReferenceFieldValueSchema(field);
153
+ break;
150
154
  case 'style':
151
155
  fieldSchema = styleFieldValueSchema(field);
152
156
  break;
@@ -250,6 +254,17 @@ function referenceFieldValueSchema(field: FieldReferenceProps): Joi.Schema {
250
254
  return Joi.string();
251
255
  }
252
256
 
257
+ function crossReferenceFieldValueSchema(field: FieldCrossReferenceProps): Joi.Schema {
258
+ return Joi.alternatives().try(
259
+ Joi.string(),
260
+ Joi.object({
261
+ srcType: Joi.string(),
262
+ srcProjectId: Joi.string(),
263
+ srcDocumentId: Joi.string()
264
+ })
265
+ );
266
+ }
267
+
253
268
  function listFieldValueSchema(field: FieldListProps, config: Config, fieldPath: FieldPath): Joi.Schema {
254
269
  if (field.items) {
255
270
  const childFieldPath = fieldPath.concat('items');
@@ -14,19 +14,16 @@ import {
14
14
  YamlDataModelList,
15
15
  Field,
16
16
  FieldSpecificProps,
17
- FieldEnum,
18
17
  FieldEnumProps,
19
18
  FieldList,
20
19
  FieldListItems,
21
20
  FieldListModel,
22
21
  FieldListObject,
23
22
  FieldListReference,
24
- FieldModel,
25
23
  FieldModelProps,
26
- FieldObject,
27
24
  FieldObjectProps,
28
- FieldReference,
29
25
  FieldReferenceProps,
26
+ FieldCrossReferenceProps,
30
27
  DataModelList,
31
28
  FieldListProps
32
29
  } from '../config/config-types';
@@ -78,6 +75,10 @@ export function isReferenceField(field: FieldSpecificProps): field is FieldRefer
78
75
  return field.type === 'reference';
79
76
  }
80
77
 
78
+ export function isCrossReferenceField(field: FieldSpecificProps): field is FieldCrossReferenceProps {
79
+ return field.type === 'cross-reference';
80
+ }
81
+
81
82
  export function isCustomModelField(field: FieldSpecificProps, modelsByName: Record<string, Model>) {
82
83
  // custom model field types are deprecated
83
84
  return !FIELD_TYPES.includes(field.type) && _.has(modelsByName, field.type);