@webiny/api-headless-cms 0.0.0-unstable.c2780f51fe → 0.0.0-unstable.d13302545b

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 (90) hide show
  1. package/crud/contentEntry/referenceFieldsMapping.js +34 -5
  2. package/crud/contentEntry/referenceFieldsMapping.js.map +1 -1
  3. package/crud/contentEntry.crud.d.ts +4 -4
  4. package/crud/contentEntry.crud.js +183 -18
  5. package/crud/contentEntry.crud.js.map +1 -1
  6. package/crud/contentModelGroup.crud.js +1 -7
  7. package/crud/contentModelGroup.crud.js.map +1 -1
  8. package/graphql/schema/baseSchema.js +15 -0
  9. package/graphql/schema/baseSchema.js.map +1 -1
  10. package/graphql/schema/createFieldResolvers.d.ts +1 -1
  11. package/graphql/schema/createFieldResolvers.js +6 -12
  12. package/graphql/schema/createFieldResolvers.js.map +1 -1
  13. package/graphql/schema/createFieldTypePluginRecords.d.ts +3 -0
  14. package/graphql/schema/createFieldTypePluginRecords.js +13 -0
  15. package/graphql/schema/createFieldTypePluginRecords.js.map +1 -0
  16. package/graphql/schema/createManageResolvers.js +4 -0
  17. package/graphql/schema/createManageResolvers.js.map +1 -1
  18. package/graphql/schema/createManageSDL.js +34 -26
  19. package/graphql/schema/createManageSDL.js.map +1 -1
  20. package/graphql/schema/createReadSDL.js +22 -19
  21. package/graphql/schema/createReadSDL.js.map +1 -1
  22. package/graphql/schema/resolvers/manage/resolveDelete.d.ts +2 -1
  23. package/graphql/schema/resolvers/manage/resolveDelete.js +13 -3
  24. package/graphql/schema/resolvers/manage/resolveDelete.js.map +1 -1
  25. package/graphql/schema/resolvers/manage/resolveDeleteMultiple.d.ts +7 -0
  26. package/graphql/schema/resolvers/manage/resolveDeleteMultiple.js +20 -0
  27. package/graphql/schema/resolvers/manage/resolveDeleteMultiple.js.map +1 -0
  28. package/graphql/schema/resolvers/manage/resolveGetUniqueFieldValues.d.ts +4 -0
  29. package/graphql/schema/resolvers/manage/resolveGetUniqueFieldValues.js +18 -0
  30. package/graphql/schema/resolvers/manage/resolveGetUniqueFieldValues.js.map +1 -0
  31. package/graphql/schema/schemaPlugins.js +2 -11
  32. package/graphql/schema/schemaPlugins.js.map +1 -1
  33. package/graphqlFields/dynamicZone/dynamicZoneField.js +43 -28
  34. package/graphqlFields/dynamicZone/dynamicZoneField.js.map +1 -1
  35. package/graphqlFields/object.js.map +1 -1
  36. package/package.json +35 -35
  37. package/plugins/CmsModelPlugin.d.ts +3 -1
  38. package/plugins/CmsModelPlugin.js.map +1 -1
  39. package/types.d.ts +82 -31
  40. package/types.js +11 -0
  41. package/types.js.map +1 -1
  42. package/utils/converters/valueKeyStorageConverter.js +5 -2
  43. package/utils/converters/valueKeyStorageConverter.js.map +1 -1
  44. package/utils/getBaseFieldType.d.ts +1 -3
  45. package/utils/getBaseFieldType.js.map +1 -1
  46. package/utils/getEntryDescription.d.ts +1 -1
  47. package/utils/getEntryDescription.js.map +1 -1
  48. package/utils/getEntryImage.d.ts +1 -1
  49. package/utils/getEntryImage.js.map +1 -1
  50. package/utils/getEntryTitle.d.ts +1 -1
  51. package/utils/getEntryTitle.js.map +1 -1
  52. package/utils/renderFields.d.ts +2 -1
  53. package/utils/renderFields.js +2 -1
  54. package/utils/renderFields.js.map +1 -1
  55. package/utils/renderGetFilterFields.d.ts +2 -2
  56. package/utils/renderGetFilterFields.js +7 -20
  57. package/utils/renderGetFilterFields.js.map +1 -1
  58. package/utils/renderInputFields.d.ts +2 -1
  59. package/utils/renderInputFields.js +14 -6
  60. package/utils/renderInputFields.js.map +1 -1
  61. package/utils/renderListFilterFields.d.ts +2 -1
  62. package/utils/renderListFilterFields.js +9 -20
  63. package/utils/renderListFilterFields.js.map +1 -1
  64. package/utils/renderSortEnum.d.ts +2 -1
  65. package/utils/renderSortEnum.js +2 -1
  66. package/utils/renderSortEnum.js.map +1 -1
  67. package/crud/contentModel/createFieldModels.d.ts +0 -2
  68. package/crud/contentModel/createFieldModels.js +0 -26
  69. package/crud/contentModel/createFieldModels.js.map +0 -1
  70. package/crud/contentModel/fieldIdValidation.d.ts +0 -1
  71. package/crud/contentModel/fieldIdValidation.js +0 -25
  72. package/crud/contentModel/fieldIdValidation.js.map +0 -1
  73. package/crud/contentModel/idValidation.d.ts +0 -1
  74. package/crud/contentModel/idValidation.js +0 -22
  75. package/crud/contentModel/idValidation.js.map +0 -1
  76. package/crud/contentModel/models.d.ts +0 -4
  77. package/crud/contentModel/models.js +0 -192
  78. package/crud/contentModel/models.js.map +0 -1
  79. package/crud/contentModel/systemFields.d.ts +0 -1
  80. package/crud/contentModel/systemFields.js +0 -8
  81. package/crud/contentModel/systemFields.js.map +0 -1
  82. package/upgrades/5.33.0/index.d.ts +0 -3
  83. package/upgrades/5.33.0/index.js +0 -182
  84. package/upgrades/5.33.0/index.js.map +0 -1
  85. package/upgrades/index.d.ts +0 -1
  86. package/upgrades/index.js +0 -12
  87. package/upgrades/index.js.map +0 -1
  88. package/utils/pluralizedTypeName.d.ts +0 -1
  89. package/utils/pluralizedTypeName.js +0 -26
  90. package/utils/pluralizedTypeName.js.map +0 -1
@@ -18,8 +18,8 @@ const buildReferenceFieldPaths = params => {
18
18
  } = params;
19
19
  const parentPaths = [...initialParentPaths];
20
20
  const isMultipleValues = Array.isArray(input);
21
- return fields.filter(field => ["object", "ref"].includes((0, _getBaseFieldType.getBaseFieldType)(field))).reduce((collection, field) => {
22
- var _field$settings2;
21
+ return fields.filter(field => ["object", "ref", "dynamicZone"].includes((0, _getBaseFieldType.getBaseFieldType)(field))).reduce((collection, field) => {
22
+ var _field$settings3;
23
23
  /**
24
24
  * First we check the ref field
25
25
  */
@@ -47,6 +47,35 @@ const buildReferenceFieldPaths = params => {
47
47
  collection.push(`${parentPathsValue}${field.fieldId}`);
48
48
  return collection;
49
49
  }
50
+ if (baseType === "dynamicZone") {
51
+ var _field$settings;
52
+ const templates = ((_field$settings = field.settings) === null || _field$settings === void 0 ? void 0 : _field$settings.templates) || [];
53
+ for (const template of templates) {
54
+ if (field.multipleValues) {
55
+ const inputValue = _dotProp.default.get(input, `${field.fieldId}`, []);
56
+ if (Array.isArray(inputValue) === false) {
57
+ return collection;
58
+ }
59
+ for (const key in inputValue) {
60
+ const result = buildReferenceFieldPaths({
61
+ fields: template.fields,
62
+ input: inputValue[key],
63
+ parentPaths: parentPaths.concat([field.fieldId, key, template.gqlTypeName])
64
+ });
65
+ collection.push(...result);
66
+ }
67
+ continue;
68
+ }
69
+ const result = buildReferenceFieldPaths({
70
+ fields: template.fields,
71
+ input,
72
+ parentPaths: parentPaths.concat([field.fieldId, template.gqlTypeName])
73
+ });
74
+ collection.push(...result);
75
+ }
76
+ return collection;
77
+ }
78
+
50
79
  /**
51
80
  * Then we move onto the object field
52
81
  */
@@ -72,9 +101,9 @@ const buildReferenceFieldPaths = params => {
72
101
  return collection;
73
102
  }
74
103
  for (const key in objFieldInputValue) {
75
- var _field$settings;
104
+ var _field$settings2;
76
105
  const result = buildReferenceFieldPaths({
77
- fields: ((_field$settings = field.settings) === null || _field$settings === void 0 ? void 0 : _field$settings.fields) || [],
106
+ fields: ((_field$settings2 = field.settings) === null || _field$settings2 === void 0 ? void 0 : _field$settings2.fields) || [],
78
107
  input: objFieldInputValue[key],
79
108
  parentPaths: parentPaths.concat([field.fieldId, key])
80
109
  });
@@ -87,7 +116,7 @@ const buildReferenceFieldPaths = params => {
87
116
  * Single value reference field.
88
117
  */
89
118
  const results = buildReferenceFieldPaths({
90
- fields: ((_field$settings2 = field.settings) === null || _field$settings2 === void 0 ? void 0 : _field$settings2.fields) || [],
119
+ fields: ((_field$settings3 = field.settings) === null || _field$settings3 === void 0 ? void 0 : _field$settings3.fields) || [],
91
120
  input: objFieldInputValue,
92
121
  parentPaths: parentPaths.concat([field.fieldId])
93
122
  });
@@ -1 +1 @@
1
- {"version":3,"names":["buildReferenceFieldPaths","params","fields","parentPaths","initialParentPaths","input","isMultipleValues","Array","isArray","filter","field","includes","getBaseFieldType","reduce","collection","baseType","parentPathsValue","length","join","multipleValues","inputValue","dotProp","get","fieldId","key","path","push","objFieldPath","objFieldInputValue","result","settings","concat","results","getReferenceFieldValue","ref","id","modelId","entryId","trim","referenceFieldsMapping","context","model","validateEntries","output","referenceFieldPaths","referencesByModel","pathsByReferenceId","Object","keys","models","cms","listModels","entries","promises","map","getEntriesByIds","Promise","all","records","entry","WebinyError","parseIdentifier","paths","set"],"sources":["referenceFieldsMapping.ts"],"sourcesContent":["import { CmsContext, CmsModel, CmsModelField } from \"~/types\";\nimport WebinyError from \"@webiny/error\";\nimport dotProp from \"dot-prop\";\nimport { parseIdentifier } from \"@webiny/utils\";\nimport { getBaseFieldType } from \"~/utils/getBaseFieldType\";\n\ninterface CmsRefEntry {\n id: string;\n entryId: string;\n modelId: string;\n}\n\ninterface ReferenceObject {\n id: string;\n modelId: string;\n}\n\ninterface Params {\n context: CmsContext;\n model: CmsModel;\n input: Record<string, ReferenceObject | ReferenceObject[]>;\n validateEntries?: boolean;\n}\n\ninterface BuildReferenceFieldPaths {\n fields: CmsModelField[];\n parentPaths: string[];\n input: Record<string, any>;\n}\n\nconst buildReferenceFieldPaths = (params: BuildReferenceFieldPaths): string[] => {\n const { fields, parentPaths: initialParentPaths, input } = params;\n\n const parentPaths = [...initialParentPaths];\n\n const isMultipleValues = Array.isArray(input);\n\n return fields\n .filter(field => [\"object\", \"ref\"].includes(getBaseFieldType(field)))\n .reduce((collection, field) => {\n /**\n * First we check the ref field\n */\n const baseType = getBaseFieldType(field);\n if (baseType === \"ref\") {\n const parentPathsValue = parentPaths.length > 0 ? `${parentPaths.join(\".\")}.` : \"\";\n if (field.multipleValues) {\n const inputValue = dotProp.get(input, `${field.fieldId}`, []);\n if (Array.isArray(inputValue) === false) {\n return collection;\n }\n for (const key in inputValue) {\n const path = `${parentPathsValue}${field.fieldId}.${key}`;\n collection.push(path);\n }\n return collection;\n }\n\n if (isMultipleValues) {\n for (const key in input) {\n const path = `${parentPathsValue}${key}.${field.fieldId}`;\n collection.push(path);\n }\n return collection;\n }\n\n collection.push(`${parentPathsValue}${field.fieldId}`);\n\n return collection;\n }\n /**\n * Then we move onto the object field\n */\n const parentPathsValue = parentPaths.length > 0 ? `${parentPaths.join(\".\")}.` : \"\";\n /**\n * This is if received input is array. We need to map key with fieldId at this point.\n */\n if (isMultipleValues) {\n for (const key in input) {\n const path = `${parentPathsValue}${key}.${field.fieldId}`;\n collection.push(path);\n }\n return collection;\n }\n\n const objFieldPath = `${field.fieldId}`;\n const objFieldInputValue = dotProp.get(input, objFieldPath, []);\n\n /**\n * If field is multiple values one, we need to go through the input and use the existing keys.\n */\n if (field.multipleValues) {\n if (Array.isArray(objFieldInputValue) === false) {\n return collection;\n }\n for (const key in objFieldInputValue) {\n const result = buildReferenceFieldPaths({\n fields: field.settings?.fields || [],\n input: objFieldInputValue[key],\n parentPaths: parentPaths.concat([field.fieldId, key])\n });\n collection.push(...result);\n }\n\n return collection;\n }\n\n /**\n * Single value reference field.\n */\n const results = buildReferenceFieldPaths({\n fields: field.settings?.fields || [],\n input: objFieldInputValue,\n parentPaths: parentPaths.concat([field.fieldId])\n });\n\n return collection.concat(results);\n }, [] as string[]);\n};\n\nconst getReferenceFieldValue = (ref: any): { id: string | null; modelId: string | null } => {\n if (!ref) {\n return {\n id: null,\n modelId: null\n };\n }\n return {\n id: (ref.id || ref.entryId || \"\").trim() || null,\n modelId: (ref.modelId || \"\").trim() || null\n };\n};\n\nexport const referenceFieldsMapping = async (params: Params): Promise<Record<string, any>> => {\n const { context, model, input, validateEntries = false } = params;\n\n let output: Record<string, any> = {\n ...input\n };\n\n const referenceFieldPaths = buildReferenceFieldPaths({\n fields: model.fields,\n input,\n parentPaths: []\n });\n if (referenceFieldPaths.length === 0) {\n return output;\n }\n\n const referencesByModel: Record<string, string[]> = {};\n const pathsByReferenceId: Record<string, string[]> = {};\n\n for (const path of referenceFieldPaths) {\n const ref = dotProp.get(output, path) as ReferenceObject | any;\n\n const { id, modelId } = getReferenceFieldValue(ref);\n\n if (!id || !modelId) {\n continue;\n }\n if (!referencesByModel[modelId]) {\n referencesByModel[modelId] = [];\n }\n referencesByModel[modelId].push(id);\n if (!pathsByReferenceId[id]) {\n pathsByReferenceId[id] = [];\n }\n pathsByReferenceId[id].push(path);\n }\n\n /**\n * Again, no point in going further.\n */\n if (Object.keys(referencesByModel).length === 0) {\n return output;\n }\n /**\n * Load all models and use only those that are used in reference.\n */\n const models = (await context.cms.listModels()).filter(model => {\n const entries = referencesByModel[model.modelId];\n if (!Array.isArray(entries) || entries.length === 0) {\n return false;\n }\n return true;\n });\n /**\n * Check for any model existence, just in case.\n */\n if (models.length === 0) {\n return output;\n }\n\n /**\n * Load all the entries by their ID\n */\n const promises = models.map(model => {\n return context.cms.getEntriesByIds(model, referencesByModel[model.modelId]);\n });\n\n const results = await Promise.all(promises);\n\n const records: Record<string, CmsRefEntry> = results.reduce((collection, entries) => {\n for (const entry of entries) {\n collection[entry.id] = {\n id: entry.id,\n entryId: entry.entryId,\n modelId: entry.modelId\n };\n }\n return collection;\n }, {} as Record<string, CmsRefEntry>);\n /**\n * Verify that all referenced entries actually exist.\n */\n for (const modelId in referencesByModel) {\n const entries = referencesByModel[modelId];\n for (const id of entries) {\n if (records[id]) {\n continue;\n } else if (validateEntries) {\n throw new WebinyError(\n `Missing referenced entry with id \"${id}\" in model \"${modelId}\".`,\n \"ENTRY_NOT_FOUND\",\n {\n id,\n model: modelId\n }\n );\n }\n const { id: entryId } = parseIdentifier(id);\n records[id] = {\n id,\n entryId,\n modelId\n };\n }\n }\n\n /**\n * In the end, assign the entryId, id and model values to the output.\n */\n for (const id in pathsByReferenceId) {\n const entry = records[id];\n const paths = pathsByReferenceId[id];\n if (!entry) {\n if (validateEntries) {\n throw new WebinyError(\"Missing entry in records.\", \"ENTRY_ERROR\", {\n id,\n paths\n });\n }\n continue;\n }\n for (const path of paths) {\n output = dotProp.set(output, path, {\n id: entry.id,\n entryId: entry.entryId,\n modelId: entry.modelId\n });\n }\n }\n\n return output;\n};\n"],"mappings":"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"}
1
+ {"version":3,"names":["buildReferenceFieldPaths","params","fields","parentPaths","initialParentPaths","input","isMultipleValues","Array","isArray","filter","field","includes","getBaseFieldType","reduce","collection","baseType","parentPathsValue","length","join","multipleValues","inputValue","dotProp","get","fieldId","key","path","push","templates","settings","template","result","concat","gqlTypeName","objFieldPath","objFieldInputValue","results","getReferenceFieldValue","ref","id","modelId","entryId","trim","referenceFieldsMapping","context","model","validateEntries","output","referenceFieldPaths","referencesByModel","pathsByReferenceId","Object","keys","models","cms","listModels","entries","promises","map","getEntriesByIds","Promise","all","records","entry","WebinyError","parseIdentifier","paths","set"],"sources":["referenceFieldsMapping.ts"],"sourcesContent":["import { CmsContext, CmsDynamicZoneTemplate, CmsModel, CmsModelField } from \"~/types\";\nimport WebinyError from \"@webiny/error\";\nimport dotProp from \"dot-prop\";\nimport { parseIdentifier } from \"@webiny/utils\";\nimport { getBaseFieldType } from \"~/utils/getBaseFieldType\";\n\ninterface CmsRefEntry {\n id: string;\n entryId: string;\n modelId: string;\n}\n\ninterface ReferenceObject {\n id: string;\n modelId: string;\n}\n\ninterface Params {\n context: CmsContext;\n model: CmsModel;\n input: Record<string, ReferenceObject | ReferenceObject[]>;\n validateEntries?: boolean;\n}\n\ninterface BuildReferenceFieldPaths {\n fields: CmsModelField[];\n parentPaths: string[];\n input: Record<string, any>;\n}\n\nconst buildReferenceFieldPaths = (params: BuildReferenceFieldPaths): string[] => {\n const { fields, parentPaths: initialParentPaths, input } = params;\n\n const parentPaths = [...initialParentPaths];\n\n const isMultipleValues = Array.isArray(input);\n\n return fields\n .filter(field => [\"object\", \"ref\", \"dynamicZone\"].includes(getBaseFieldType(field)))\n .reduce((collection, field) => {\n /**\n * First we check the ref field\n */\n const baseType = getBaseFieldType(field);\n if (baseType === \"ref\") {\n const parentPathsValue = parentPaths.length > 0 ? `${parentPaths.join(\".\")}.` : \"\";\n if (field.multipleValues) {\n const inputValue = dotProp.get(input, `${field.fieldId}`, []);\n if (Array.isArray(inputValue) === false) {\n return collection;\n }\n for (const key in inputValue) {\n const path = `${parentPathsValue}${field.fieldId}.${key}`;\n collection.push(path);\n }\n return collection;\n }\n\n if (isMultipleValues) {\n for (const key in input) {\n const path = `${parentPathsValue}${key}.${field.fieldId}`;\n collection.push(path);\n }\n return collection;\n }\n\n collection.push(`${parentPathsValue}${field.fieldId}`);\n\n return collection;\n }\n\n if (baseType === \"dynamicZone\") {\n const templates: CmsDynamicZoneTemplate[] = field.settings?.templates || [];\n for (const template of templates) {\n if (field.multipleValues) {\n const inputValue = dotProp.get(input, `${field.fieldId}`, []);\n if (Array.isArray(inputValue) === false) {\n return collection;\n }\n\n for (const key in inputValue) {\n const result = buildReferenceFieldPaths({\n fields: template.fields,\n input: inputValue[key],\n parentPaths: parentPaths.concat([\n field.fieldId,\n key,\n template.gqlTypeName\n ])\n });\n collection.push(...result);\n }\n continue;\n }\n\n const result = buildReferenceFieldPaths({\n fields: template.fields,\n input,\n parentPaths: parentPaths.concat([field.fieldId, template.gqlTypeName])\n });\n collection.push(...result);\n }\n\n return collection;\n }\n\n /**\n * Then we move onto the object field\n */\n const parentPathsValue = parentPaths.length > 0 ? `${parentPaths.join(\".\")}.` : \"\";\n /**\n * This is if received input is array. We need to map key with fieldId at this point.\n */\n if (isMultipleValues) {\n for (const key in input) {\n const path = `${parentPathsValue}${key}.${field.fieldId}`;\n collection.push(path);\n }\n return collection;\n }\n\n const objFieldPath = `${field.fieldId}`;\n const objFieldInputValue = dotProp.get(input, objFieldPath, []);\n\n /**\n * If field is multiple values one, we need to go through the input and use the existing keys.\n */\n if (field.multipleValues) {\n if (Array.isArray(objFieldInputValue) === false) {\n return collection;\n }\n for (const key in objFieldInputValue) {\n const result = buildReferenceFieldPaths({\n fields: field.settings?.fields || [],\n input: objFieldInputValue[key],\n parentPaths: parentPaths.concat([field.fieldId, key])\n });\n collection.push(...result);\n }\n\n return collection;\n }\n\n /**\n * Single value reference field.\n */\n const results = buildReferenceFieldPaths({\n fields: field.settings?.fields || [],\n input: objFieldInputValue,\n parentPaths: parentPaths.concat([field.fieldId])\n });\n\n return collection.concat(results);\n }, [] as string[]);\n};\n\nconst getReferenceFieldValue = (ref: any): { id: string | null; modelId: string | null } => {\n if (!ref) {\n return {\n id: null,\n modelId: null\n };\n }\n return {\n id: (ref.id || ref.entryId || \"\").trim() || null,\n modelId: (ref.modelId || \"\").trim() || null\n };\n};\n\nexport const referenceFieldsMapping = async (params: Params): Promise<Record<string, any>> => {\n const { context, model, input, validateEntries = false } = params;\n\n let output: Record<string, any> = {\n ...input\n };\n\n const referenceFieldPaths = buildReferenceFieldPaths({\n fields: model.fields,\n input,\n parentPaths: []\n });\n if (referenceFieldPaths.length === 0) {\n return output;\n }\n\n const referencesByModel: Record<string, string[]> = {};\n const pathsByReferenceId: Record<string, string[]> = {};\n\n for (const path of referenceFieldPaths) {\n const ref = dotProp.get(output, path) as ReferenceObject | any;\n\n const { id, modelId } = getReferenceFieldValue(ref);\n\n if (!id || !modelId) {\n continue;\n }\n if (!referencesByModel[modelId]) {\n referencesByModel[modelId] = [];\n }\n referencesByModel[modelId].push(id);\n if (!pathsByReferenceId[id]) {\n pathsByReferenceId[id] = [];\n }\n pathsByReferenceId[id].push(path);\n }\n\n /**\n * Again, no point in going further.\n */\n if (Object.keys(referencesByModel).length === 0) {\n return output;\n }\n /**\n * Load all models and use only those that are used in reference.\n */\n const models = (await context.cms.listModels()).filter(model => {\n const entries = referencesByModel[model.modelId];\n if (!Array.isArray(entries) || entries.length === 0) {\n return false;\n }\n return true;\n });\n /**\n * Check for any model existence, just in case.\n */\n if (models.length === 0) {\n return output;\n }\n\n /**\n * Load all the entries by their ID\n */\n const promises = models.map(model => {\n return context.cms.getEntriesByIds(model, referencesByModel[model.modelId]);\n });\n\n const results = await Promise.all(promises);\n\n const records: Record<string, CmsRefEntry> = results.reduce((collection, entries) => {\n for (const entry of entries) {\n collection[entry.id] = {\n id: entry.id,\n entryId: entry.entryId,\n modelId: entry.modelId\n };\n }\n return collection;\n }, {} as Record<string, CmsRefEntry>);\n /**\n * Verify that all referenced entries actually exist.\n */\n for (const modelId in referencesByModel) {\n const entries = referencesByModel[modelId];\n for (const id of entries) {\n if (records[id]) {\n continue;\n } else if (validateEntries) {\n throw new WebinyError(\n `Missing referenced entry with id \"${id}\" in model \"${modelId}\".`,\n \"ENTRY_NOT_FOUND\",\n {\n id,\n model: modelId\n }\n );\n }\n const { id: entryId } = parseIdentifier(id);\n records[id] = {\n id,\n entryId,\n modelId\n };\n }\n }\n\n /**\n * In the end, assign the entryId, id and model values to the output.\n */\n for (const id in pathsByReferenceId) {\n const entry = records[id];\n const paths = pathsByReferenceId[id];\n if (!entry) {\n if (validateEntries) {\n throw new WebinyError(\"Missing entry in records.\", \"ENTRY_ERROR\", {\n id,\n paths\n });\n }\n continue;\n }\n for (const path of paths) {\n output = dotProp.set(output, path, {\n id: entry.id,\n entryId: entry.entryId,\n modelId: entry.modelId\n });\n }\n }\n\n return output;\n};\n"],"mappings":"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"}
@@ -1,10 +1,10 @@
1
- import { CmsContext, CmsEntryContext, HeadlessCmsStorageOperations } from "../types";
1
+ import { CmsContext, CmsEntryContext, CONTENT_ENTRY_STATUS, HeadlessCmsStorageOperations } from "../types";
2
2
  import { SecurityIdentity } from "@webiny/api-security/types";
3
3
  import { Tenant } from "@webiny/api-tenancy/types";
4
4
  import { I18NLocale } from "@webiny/api-i18n/types";
5
- export declare const STATUS_DRAFT = "draft";
6
- export declare const STATUS_PUBLISHED = "published";
7
- export declare const STATUS_UNPUBLISHED = "unpublished";
5
+ export declare const STATUS_DRAFT = CONTENT_ENTRY_STATUS.DRAFT;
6
+ export declare const STATUS_PUBLISHED = CONTENT_ENTRY_STATUS.PUBLISHED;
7
+ export declare const STATUS_UNPUBLISHED = CONTENT_ENTRY_STATUS.UNPUBLISHED;
8
8
  interface CreateContentEntryCrudParams {
9
9
  storageOperations: HeadlessCmsStorageOperations;
10
10
  context: CmsContext;
@@ -7,14 +7,14 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.createContentEntryCrud = exports.STATUS_UNPUBLISHED = exports.STATUS_PUBLISHED = exports.STATUS_DRAFT = void 0;
8
8
  var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
9
9
  var _merge = _interopRequireDefault(require("lodash/merge"));
10
- var _mdbid = _interopRequireDefault(require("mdbid"));
10
+ var _utils = require("@webiny/utils");
11
11
  var _error = _interopRequireDefault(require("@webiny/error"));
12
12
  var _handlerGraphql = require("@webiny/handler-graphql");
13
+ var _types = require("../types");
13
14
  var _entryDataValidation = require("./contentEntry/entryDataValidation");
14
15
  var _pubsub = require("@webiny/pubsub");
15
16
  var _beforeCreate = require("./contentEntry/beforeCreate");
16
17
  var _beforeUpdate = require("./contentEntry/beforeUpdate");
17
- var _utils = require("@webiny/utils");
18
18
  var _afterDelete = require("./contentEntry/afterDelete");
19
19
  var _referenceFieldsMapping = require("./contentEntry/referenceFieldsMapping");
20
20
  var _permissions = require("../utils/permissions");
@@ -22,16 +22,12 @@ var _access = require("../utils/access");
22
22
  var _ownership = require("../utils/ownership");
23
23
  var _entryStorage = require("../utils/entryStorage");
24
24
  var _searchableFields = require("./contentEntry/searchableFields");
25
- /**
26
- * Package mdbid does not have types.
27
- */
28
- // @ts-ignore
29
-
30
- const STATUS_DRAFT = "draft";
25
+ var _filterAsync = require("../utils/filterAsync");
26
+ const STATUS_DRAFT = _types.CONTENT_ENTRY_STATUS.DRAFT;
31
27
  exports.STATUS_DRAFT = STATUS_DRAFT;
32
- const STATUS_PUBLISHED = "published";
28
+ const STATUS_PUBLISHED = _types.CONTENT_ENTRY_STATUS.PUBLISHED;
33
29
  exports.STATUS_PUBLISHED = STATUS_PUBLISHED;
34
- const STATUS_UNPUBLISHED = "unpublished";
30
+ const STATUS_UNPUBLISHED = _types.CONTENT_ENTRY_STATUS.UNPUBLISHED;
35
31
  exports.STATUS_UNPUBLISHED = STATUS_UNPUBLISHED;
36
32
  /**
37
33
  * Used for some fields to convert their values.
@@ -133,7 +129,7 @@ const createEntryMeta = (input, original) => {
133
129
  return (0, _utils.removeUndefinedValues)((0, _utils.removeNullValues)(meta));
134
130
  };
135
131
  const createEntryId = input => {
136
- let entryId = (0, _mdbid.default)();
132
+ let entryId = (0, _utils.mdbid)();
137
133
  if (input.id) {
138
134
  if (input.id.match(/^([a-zA-Z0-9])([a-zA-Z0-9\-]+)([a-zA-Z0-9])$/) === null) {
139
135
  throw new _error.default("The provided ID is not valid. It must be a string which can be A-Z, a-z, 0-9, - and it cannot start or end with a -.", "INVALID_ID", {
@@ -247,6 +243,12 @@ const createContentEntryCrud = params => {
247
243
  const onEntryRevisionBeforeDelete = (0, _pubsub.createTopic)("cms.onEntryRevisionBeforeDelete");
248
244
  const onEntryRevisionAfterDelete = (0, _pubsub.createTopic)("cms.onEntryRevisionAfterDelete");
249
245
  const onEntryRevisionDeleteError = (0, _pubsub.createTopic)("cms.onEntryRevisionDeleteError");
246
+ /**
247
+ * Delete multiple entries
248
+ */
249
+ const onEntryBeforeDeleteMultiple = (0, _pubsub.createTopic)("cms.onEntryBeforeDeleteMultiple");
250
+ const onEntryAfterDeleteMultiple = (0, _pubsub.createTopic)("cms.onEntryAfterDeleteMultiple");
251
+ const onEntryDeleteMultipleError = (0, _pubsub.createTopic)("cms.onEntryDeleteMultipleError");
250
252
 
251
253
  /**
252
254
  * Get entry
@@ -397,9 +399,6 @@ const createContentEntryCrud = params => {
397
399
  limit: initialLimit
398
400
  } = params;
399
401
  const limit = initialLimit && initialLimit > 0 ? initialLimit : 50;
400
- /**
401
- * We always assign tenant and locale because we do not allow one model to have content through multiple tenants.
402
- */
403
402
  const where = (0, _objectSpread2.default)({}, initialWhere);
404
403
  /**
405
404
  * Possibly only get records which are owned by current user.
@@ -894,16 +893,110 @@ const createContentEntryCrud = params => {
894
893
  });
895
894
  }
896
895
  };
897
- const deleteEntry = async (model, entryId) => {
896
+ const deleteMultipleEntries = async (model, params) => {
897
+ const {
898
+ entries: input
899
+ } = params;
900
+ const maxDeletableEntries = 50;
901
+ const entryIdList = new Set();
902
+ for (const id of input) {
903
+ const {
904
+ id: entryId
905
+ } = (0, _utils.parseIdentifier)(id);
906
+ entryIdList.add(entryId);
907
+ }
908
+ const ids = Array.from(entryIdList);
909
+ if (ids.length > maxDeletableEntries) {
910
+ throw new _error.default("Cannot delete more than 50 entries at once.", "DELETE_ENTRIES_MAX", {
911
+ entries: ids
912
+ });
913
+ }
914
+ const permission = await checkEntryPermissions({
915
+ rwd: "d"
916
+ });
917
+ await (0, _access.checkModelAccess)(context, model);
918
+ const {
919
+ items: entries
920
+ } = await storageOperations.entries.list(model, {
921
+ where: {
922
+ latest: true,
923
+ entryId_in: ids
924
+ },
925
+ limit: maxDeletableEntries + 1
926
+ });
927
+ /**
928
+ * We do not want to allow deleting entries that user does not own or cannot access.
929
+ */
930
+ const items = (await (0, _filterAsync.filterAsync)(entries, async entry => {
931
+ return (0, _ownership.validateOwnership)(context, permission, entry);
932
+ })).map(entry => entry.id);
933
+ try {
934
+ await onEntryBeforeDeleteMultiple.publish({
935
+ entries,
936
+ ids,
937
+ model
938
+ });
939
+ await storageOperations.entries.deleteMultipleEntries(model, {
940
+ entries: items
941
+ });
942
+ await onEntryAfterDeleteMultiple.publish({
943
+ entries,
944
+ ids,
945
+ model
946
+ });
947
+ return items.map(id => {
948
+ return {
949
+ id
950
+ };
951
+ });
952
+ } catch (ex) {
953
+ await onEntryDeleteMultipleError.publish({
954
+ entries,
955
+ ids,
956
+ model,
957
+ error: ex
958
+ });
959
+ throw new _error.default(ex.message, ex.code || "DELETE_ENTRIES_MULTIPLE_ERROR", {
960
+ error: ex,
961
+ entries
962
+ });
963
+ }
964
+ };
965
+ const deleteEntry = async (model, id, options) => {
898
966
  const permission = await checkEntryPermissions({
899
967
  rwd: "d"
900
968
  });
901
969
  await (0, _access.checkModelAccess)(context, model);
970
+ const {
971
+ force
972
+ } = options || {};
902
973
  const storageEntry = await storageOperations.entries.getLatestRevisionByEntryId(model, {
903
- id: entryId
974
+ id
904
975
  });
905
- if (!storageEntry) {
906
- throw new _handlerGraphql.NotFoundError(`Entry "${entryId}" was not found!`);
976
+ /**
977
+ * If there is no entry, and we do not force the deletion, just throw an error.
978
+ */
979
+ if (!storageEntry && !force) {
980
+ throw new _handlerGraphql.NotFoundError(`Entry "${id}" was not found!`);
981
+ }
982
+ /**
983
+ * In the case we are forcing the deletion, we do not need the storageEntry to exist as it might be an error when loading single database record.
984
+ *
985
+ * This happens, sometimes, in the Elasticsearch system as the entry might get deleted from the DynamoDB but not from the Elasticsearch.
986
+ * This is due to high load on the Elasticsearch at the time of the deletion.
987
+ */
988
+ //
989
+ else if (!storageEntry && force) {
990
+ const {
991
+ id: entryId
992
+ } = (0, _utils.parseIdentifier)(id);
993
+ return await deleteEntryHelper({
994
+ model,
995
+ entry: {
996
+ id,
997
+ entryId
998
+ }
999
+ });
907
1000
  }
908
1001
  (0, _ownership.checkOwnership)(context, permission, storageEntry);
909
1002
  const entry = await (0, _entryStorage.entryFromStorageTransform)(context, model, storageEntry);
@@ -1018,6 +1111,68 @@ const createContentEntryCrud = params => {
1018
1111
  });
1019
1112
  }
1020
1113
  };
1114
+ const getUniqueFieldValues = async (model, params) => {
1115
+ const permission = await checkEntryPermissions({
1116
+ rwd: "r"
1117
+ });
1118
+ await (0, _access.checkModelAccess)(context, model);
1119
+ const {
1120
+ where: initialWhere,
1121
+ fieldId
1122
+ } = params;
1123
+ const where = (0, _objectSpread2.default)({}, initialWhere);
1124
+ /**
1125
+ * Possibly only get records which are owned by current user.
1126
+ * Or if searching for the owner set that value - in the case that user can see other entries than their own.
1127
+ */
1128
+ const ownedBy = permission.own ? getIdentity().id : where.ownedBy;
1129
+ if (ownedBy !== undefined) {
1130
+ where.ownedBy = ownedBy;
1131
+ }
1132
+ /**
1133
+ * Where must contain either latest or published keys.
1134
+ * We cannot list entries without one of those
1135
+ */
1136
+ if (where.latest && where.published) {
1137
+ throw new _error.default("Cannot list entries that are both published and latest.", "LIST_ENTRIES_ERROR", {
1138
+ where
1139
+ });
1140
+ } else if (!where.latest && !where.published) {
1141
+ throw new _error.default("Cannot list entries if we do not have latest or published defined.", "LIST_ENTRIES_ERROR", {
1142
+ where
1143
+ });
1144
+ }
1145
+ /**
1146
+ * We need to verify that the field in question is searchable.
1147
+ */
1148
+ const fields = (0, _searchableFields.getSearchableFields)({
1149
+ fields: model.fields,
1150
+ plugins: context.plugins,
1151
+ input: []
1152
+ });
1153
+ if (fields.includes(fieldId) === false) {
1154
+ throw new _error.default("Cannot list unique entry field values if the field is not searchable.", "LIST_UNIQUE_ENTRY_VALUES_ERROR", {
1155
+ fieldId
1156
+ });
1157
+ }
1158
+ try {
1159
+ return await storageOperations.entries.getUniqueFieldValues(model, {
1160
+ where,
1161
+ fieldId
1162
+ });
1163
+ } catch (ex) {
1164
+ throw new _error.default("Error while fetching unique entry values from storage.", "LIST_UNIQUE_ENTRY_VALUES_ERROR", {
1165
+ error: {
1166
+ message: ex.message,
1167
+ code: ex.code,
1168
+ data: ex.data
1169
+ },
1170
+ model,
1171
+ where,
1172
+ fieldId
1173
+ });
1174
+ }
1175
+ };
1021
1176
  return {
1022
1177
  /**
1023
1178
  * Deprecated - will be removed in 5.35.0
@@ -1197,6 +1352,11 @@ const createContentEntryCrud = params => {
1197
1352
  return deleteEntry(model, entryId);
1198
1353
  });
1199
1354
  },
1355
+ async deleteMultipleEntries(model, ids) {
1356
+ return context.benchmark.measure("headlessCms.crud.entries.deleteMultipleEntries", async () => {
1357
+ return deleteMultipleEntries(model, ids);
1358
+ });
1359
+ },
1200
1360
  async publishEntry(model, id) {
1201
1361
  return context.benchmark.measure("headlessCms.crud.entries.publishEntry", async () => {
1202
1362
  return publishEntry(model, id);
@@ -1206,6 +1366,11 @@ const createContentEntryCrud = params => {
1206
1366
  return context.benchmark.measure("headlessCms.crud.entries.unpublishEntry", async () => {
1207
1367
  return unpublishEntry(model, id);
1208
1368
  });
1369
+ },
1370
+ async getUniqueFieldValues(model, params) {
1371
+ return context.benchmark.measure("headlessCms.crud.entries.getUniqueFieldValues", async () => {
1372
+ return getUniqueFieldValues(model, params);
1373
+ });
1209
1374
  }
1210
1375
  };
1211
1376
  };