@strapi/core 5.51.1 → 5.51.2

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 (100) hide show
  1. package/dist/Strapi.d.ts.map +1 -1
  2. package/dist/Strapi.js +12 -6
  3. package/dist/Strapi.js.map +1 -1
  4. package/dist/Strapi.mjs +12 -6
  5. package/dist/Strapi.mjs.map +1 -1
  6. package/dist/compile.js +1 -1
  7. package/dist/compile.js.map +1 -1
  8. package/dist/compile.mjs +1 -1
  9. package/dist/compile.mjs.map +1 -1
  10. package/dist/configuration/urls.js +2 -2
  11. package/dist/configuration/urls.js.map +1 -1
  12. package/dist/configuration/urls.mjs +2 -2
  13. package/dist/configuration/urls.mjs.map +1 -1
  14. package/dist/ee/index.js +2 -2
  15. package/dist/ee/index.js.map +1 -1
  16. package/dist/ee/index.mjs +2 -2
  17. package/dist/ee/index.mjs.map +1 -1
  18. package/dist/index.d.ts +0 -3
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js.map +1 -1
  21. package/dist/index.mjs.map +1 -1
  22. package/dist/loaders/apis.d.ts.map +1 -1
  23. package/dist/loaders/apis.js +3 -1
  24. package/dist/loaders/apis.js.map +1 -1
  25. package/dist/loaders/apis.mjs +3 -1
  26. package/dist/loaders/apis.mjs.map +1 -1
  27. package/dist/loaders/plugins/get-enabled-plugins.js +1 -1
  28. package/dist/loaders/plugins/get-enabled-plugins.js.map +1 -1
  29. package/dist/loaders/plugins/get-enabled-plugins.mjs +1 -1
  30. package/dist/loaders/plugins/get-enabled-plugins.mjs.map +1 -1
  31. package/dist/loaders/plugins/index.js +2 -2
  32. package/dist/loaders/plugins/index.js.map +1 -1
  33. package/dist/loaders/plugins/index.mjs +2 -2
  34. package/dist/loaders/plugins/index.mjs.map +1 -1
  35. package/dist/migrations/database/5.0.0-discard-drafts.js +9 -9
  36. package/dist/migrations/database/5.0.0-discard-drafts.js.map +1 -1
  37. package/dist/migrations/database/5.0.0-discard-drafts.mjs +9 -9
  38. package/dist/migrations/database/5.0.0-discard-drafts.mjs.map +1 -1
  39. package/dist/package.json.js +14 -14
  40. package/dist/package.json.mjs +14 -14
  41. package/dist/services/content-api/index.js +1 -1
  42. package/dist/services/content-api/index.js.map +1 -1
  43. package/dist/services/content-api/index.mjs +1 -1
  44. package/dist/services/content-api/index.mjs.map +1 -1
  45. package/dist/services/content-api/permissions/engine.d.ts +3 -3
  46. package/dist/services/content-api/permissions/engine.d.ts.map +1 -1
  47. package/dist/services/content-api/permissions/engine.js +1 -5
  48. package/dist/services/content-api/permissions/engine.js.map +1 -1
  49. package/dist/services/content-api/permissions/engine.mjs +2 -2
  50. package/dist/services/content-api/permissions/engine.mjs.map +1 -1
  51. package/dist/services/core-store.js +1 -1
  52. package/dist/services/core-store.js.map +1 -1
  53. package/dist/services/core-store.mjs +1 -1
  54. package/dist/services/core-store.mjs.map +1 -1
  55. package/dist/services/document-service/repository.js +2 -2
  56. package/dist/services/document-service/repository.js.map +1 -1
  57. package/dist/services/document-service/repository.mjs +2 -2
  58. package/dist/services/document-service/repository.mjs.map +1 -1
  59. package/dist/services/document-service/utils/clean-component-join-table.js +2 -2
  60. package/dist/services/document-service/utils/clean-component-join-table.js.map +1 -1
  61. package/dist/services/document-service/utils/clean-component-join-table.mjs +2 -2
  62. package/dist/services/document-service/utils/clean-component-join-table.mjs.map +1 -1
  63. package/dist/services/document-service/utils/clone-relations.js +1 -1
  64. package/dist/services/document-service/utils/clone-relations.js.map +1 -1
  65. package/dist/services/document-service/utils/clone-relations.mjs +1 -1
  66. package/dist/services/document-service/utils/clone-relations.mjs.map +1 -1
  67. package/dist/services/entity-validator/blocks-validator.js +1 -1
  68. package/dist/services/entity-validator/blocks-validator.js.map +1 -1
  69. package/dist/services/entity-validator/blocks-validator.mjs +1 -1
  70. package/dist/services/entity-validator/blocks-validator.mjs.map +1 -1
  71. package/dist/services/entity-validator/index.js +23 -5
  72. package/dist/services/entity-validator/index.js.map +1 -1
  73. package/dist/services/entity-validator/index.mjs +1 -1
  74. package/dist/services/entity-validator/index.mjs.map +1 -1
  75. package/dist/services/metrics/sender.js +1 -1
  76. package/dist/services/metrics/sender.js.map +1 -1
  77. package/dist/services/metrics/sender.mjs +1 -1
  78. package/dist/services/metrics/sender.mjs.map +1 -1
  79. package/dist/services/server/koa-methods.d.ts +6 -0
  80. package/dist/services/server/koa-methods.d.ts.map +1 -1
  81. package/dist/services/server/koa-methods.js.map +1 -1
  82. package/dist/services/server/koa-methods.mjs.map +1 -1
  83. package/dist/services/server/middleware.js +1 -1
  84. package/dist/services/server/middleware.js.map +1 -1
  85. package/dist/services/server/middleware.mjs +1 -1
  86. package/dist/services/server/middleware.mjs.map +1 -1
  87. package/dist/services/server/register-middlewares.js +1 -1
  88. package/dist/services/server/register-middlewares.js.map +1 -1
  89. package/dist/services/server/register-middlewares.mjs +1 -1
  90. package/dist/services/server/register-middlewares.mjs.map +1 -1
  91. package/dist/services/server/routing.js +1 -1
  92. package/dist/services/server/routing.js.map +1 -1
  93. package/dist/services/server/routing.mjs +1 -1
  94. package/dist/services/server/routing.mjs.map +1 -1
  95. package/dist/services/session-manager.d.ts.map +1 -1
  96. package/dist/services/session-manager.js +5 -5
  97. package/dist/services/session-manager.js.map +1 -1
  98. package/dist/services/session-manager.mjs +5 -5
  99. package/dist/services/session-manager.mjs.map +1 -1
  100. package/package.json +14 -14
@@ -1 +1 @@
1
- {"version":3,"file":"clean-component-join-table.js","sources":["../../../../src/services/document-service/utils/clean-component-join-table.ts"],"sourcesContent":["import type { Database } from '@strapi/database';\nimport type { Schema } from '@strapi/types';\nimport { findComponentParent, getParentSchemasForComponent } from '../components';\n\n/**\n * Cleans ghost relations with publication state mismatches from a join table\n * Uses schema-based draft/publish checking like prevention fix\n */\nexport const cleanComponentJoinTable = async (\n db: Database,\n joinTableName: string,\n relation: any,\n sourceModel: any\n): Promise<number> => {\n try {\n // Get the target model metadata\n const targetModel = db.metadata.get(relation.target);\n if (!targetModel) {\n db.logger.debug(`Target model ${relation.target} not found, skipping ${joinTableName}`);\n return 0;\n }\n\n // Check if source supports draft/publish, if it doesnt it should contain duplicate states\n const sourceContentType = strapi.contentTypes[sourceModel.uid];\n // It could be a model, which does not have the draftAndPublish option\n const sourceSupportsDraftPublish = sourceContentType?.options?.draftAndPublish;\n\n if (sourceContentType && !sourceSupportsDraftPublish) {\n return 0;\n }\n\n // Check if target supports draft/publish using schema-based approach (like prevention fix)\n const targetContentType =\n strapi.contentTypes[relation.target as keyof typeof strapi.contentTypes];\n const targetSupportsDraftPublish = targetContentType?.options?.draftAndPublish || false;\n\n if (!targetSupportsDraftPublish) {\n return 0;\n }\n\n // Find entries with publication state mismatches\n const ghostEntries = await findPublicationStateMismatches(\n db,\n joinTableName,\n relation,\n targetModel,\n sourceModel\n );\n\n if (ghostEntries.length === 0) {\n return 0;\n }\n\n // Remove ghost entries\n await db.connection(joinTableName).whereIn('id', ghostEntries).del();\n db.logger.debug(\n `Removed ${ghostEntries.length} ghost relations with publication state mismatches from ${joinTableName}`\n );\n\n return ghostEntries.length;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n db.logger.error(`Failed to clean join table \"${joinTableName}\": ${errorMessage}`);\n return 0;\n }\n};\n\nconst findContentTypeParentForComponentInstance = async (\n componentSchema: Schema.Component,\n componentId: number | string\n): Promise<{ uid: string; table: string; parentId: number | string } | null> => {\n // Get the parent schemas that could contain this component\n const parentSchemas = getParentSchemasForComponent(componentSchema);\n if (parentSchemas.length === 0) {\n // No potential parents\n return null;\n }\n\n // Find the actual parent for THIS specific component instance\n const parent = await findComponentParent(componentSchema, componentId, parentSchemas);\n if (!parent) {\n // No parent found for this component instance\n return null;\n }\n\n if (strapi.components[parent.uid as keyof typeof strapi.components]) {\n // If the parent is a component, we need to check its parents recursively\n const parentComponentSchema = strapi.components[parent.uid as keyof typeof strapi.components];\n return findContentTypeParentForComponentInstance(parentComponentSchema, parent.parentId);\n }\n\n if (strapi.contentTypes[parent.uid as keyof typeof strapi.contentTypes]) {\n // Found a content type parent\n return parent;\n }\n\n return null;\n};\n\n/**\n * Finds join table entries with publication state mismatches\n * Uses existing component parent detection from document service\n */\nconst findPublicationStateMismatches = async (\n db: Database,\n joinTableName: string,\n relation: any,\n targetModel: any,\n sourceModel: any\n): Promise<number[]> => {\n try {\n // Get join column names using proper functions (addressing PR feedback)\n const sourceColumn = relation.joinTable.joinColumn.name;\n const targetColumn = relation.joinTable.inverseJoinColumn.name;\n\n // Get all join entries with their target entities\n const query = db\n .connection(joinTableName)\n .select(\n `${joinTableName}.id as join_id`,\n `${joinTableName}.${sourceColumn} as source_id`,\n `${joinTableName}.${targetColumn} as target_id`,\n `${targetModel.tableName}.published_at as target_published_at`\n )\n .leftJoin(\n targetModel.tableName,\n `${joinTableName}.${targetColumn}`,\n `${targetModel.tableName}.id`\n );\n\n const joinEntries = await query;\n\n // Group by source_id to find duplicates pointing to draft/published versions of same entity\n const entriesBySource: { [key: string]: any[] } = {};\n for (const entry of joinEntries) {\n const sourceId = entry.source_id;\n if (!entriesBySource[sourceId]) {\n entriesBySource[sourceId] = [];\n }\n entriesBySource[sourceId].push(entry);\n }\n\n const ghostEntries: number[] = [];\n\n // Check if this is a join table (ends with _lnk)\n const isRelationJoinTable = joinTableName.endsWith('_lnk');\n const isComponentModel =\n !sourceModel.uid?.startsWith('api::') &&\n !sourceModel.uid?.startsWith('plugin::') &&\n sourceModel.uid?.includes('.');\n\n // Check for draft/publish inconsistencies\n for (const [sourceId, entries] of Object.entries(entriesBySource)) {\n // Skip entries with single relations\n if (entries.length <= 1) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n // For component join tables, check if THIS specific component instance's parent supports D&P\n if (isRelationJoinTable && isComponentModel) {\n try {\n const componentSchema = strapi.components[sourceModel.uid] as Schema.Component;\n if (!componentSchema) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n const parent = await findContentTypeParentForComponentInstance(componentSchema, sourceId);\n if (!parent) {\n continue;\n }\n\n // Check if THIS component instance's parent supports draft/publish\n const parentContentType =\n strapi.contentTypes[parent.uid as keyof typeof strapi.contentTypes];\n if (!parentContentType?.options?.draftAndPublish) {\n // This component instance's parent does NOT support D&P - skip cleanup\n // eslint-disable-next-line no-continue\n continue;\n }\n\n // If we reach here, this component instance's parent DOES support D&P\n // Continue to process this component instance for ghost relations\n } catch (error) {\n // Skip this component instance on error\n // eslint-disable-next-line no-continue\n continue;\n }\n }\n\n // Find ghost relations (same logic as original but with improved parent checking)\n for (const entry of entries) {\n if (entry.target_published_at === null) {\n // This is a draft target - find its published version\n const draftTarget = await db\n .connection(targetModel.tableName)\n .select('document_id')\n .where('id', entry.target_id)\n .first();\n\n if (draftTarget) {\n const publishedVersion = await db\n .connection(targetModel.tableName)\n .select('id', 'document_id')\n .where('document_id', draftTarget.document_id)\n .whereNotNull('published_at')\n .first();\n\n if (publishedVersion) {\n // Check if we also have a relation to the published version\n const publishedRelation = entries.find((e) => e.target_id === publishedVersion.id);\n if (publishedRelation) {\n ghostEntries.push(publishedRelation.join_id);\n }\n }\n }\n }\n }\n }\n\n return ghostEntries;\n } catch (error) {\n return [];\n }\n};\n"],"names":["cleanComponentJoinTable","db","joinTableName","relation","sourceModel","targetModel","metadata","get","target","logger","debug","sourceContentType","strapi","contentTypes","uid","sourceSupportsDraftPublish","options","draftAndPublish","targetContentType","targetSupportsDraftPublish","ghostEntries","findPublicationStateMismatches","length","connection","whereIn","del","error","errorMessage","Error","message","String","findContentTypeParentForComponentInstance","componentSchema","componentId","parentSchemas","getParentSchemasForComponent","parent","findComponentParent","components","parentComponentSchema","parentId","sourceColumn","joinTable","joinColumn","name","targetColumn","inverseJoinColumn","query","select","tableName","leftJoin","joinEntries","entriesBySource","entry","sourceId","source_id","push","isRelationJoinTable","endsWith","isComponentModel","startsWith","includes","entries","Object","parentContentType","target_published_at","draftTarget","where","target_id","first","publishedVersion","document_id","whereNotNull","publishedRelation","find","e","id","join_id"],"mappings":"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"}
1
+ {"version":3,"file":"clean-component-join-table.js","sources":["../../../../src/services/document-service/utils/clean-component-join-table.ts"],"sourcesContent":["import type { Database } from '@strapi/database';\nimport type { Schema } from '@strapi/types';\nimport { findComponentParent, getParentSchemasForComponent } from '../components';\n\n/**\n * Cleans ghost relations with publication state mismatches from a join table\n * Uses schema-based draft/publish checking like prevention fix\n */\nexport const cleanComponentJoinTable = async (\n db: Database,\n joinTableName: string,\n relation: any,\n sourceModel: any\n): Promise<number> => {\n try {\n // Get the target model metadata\n const targetModel = db.metadata.get(relation.target);\n if (!targetModel) {\n db.logger.debug(`Target model ${relation.target} not found, skipping ${joinTableName}`);\n return 0;\n }\n\n // Check if source supports draft/publish, if it doesnt it should contain duplicate states\n const sourceContentType = strapi.contentTypes[sourceModel.uid];\n // It could be a model, which does not have the draftAndPublish option\n const sourceSupportsDraftPublish = sourceContentType?.options?.draftAndPublish;\n\n if (sourceContentType && !sourceSupportsDraftPublish) {\n return 0;\n }\n\n // Check if target supports draft/publish using schema-based approach (like prevention fix)\n const targetContentType =\n strapi.contentTypes[relation.target as keyof typeof strapi.contentTypes];\n const targetSupportsDraftPublish = targetContentType?.options?.draftAndPublish || false;\n\n if (!targetSupportsDraftPublish) {\n return 0;\n }\n\n // Find entries with publication state mismatches\n const ghostEntries = await findPublicationStateMismatches(\n db,\n joinTableName,\n relation,\n targetModel,\n sourceModel\n );\n\n if (ghostEntries.length === 0) {\n return 0;\n }\n\n // Remove ghost entries\n await db.connection(joinTableName).whereIn('id', ghostEntries).del();\n db.logger.debug(\n `Removed ${ghostEntries.length} ghost relations with publication state mismatches from ${joinTableName}`\n );\n\n return ghostEntries.length;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n db.logger.error(`Failed to clean join table \"${joinTableName}\": ${errorMessage}`);\n return 0;\n }\n};\n\nconst findContentTypeParentForComponentInstance = async (\n componentSchema: Schema.Component,\n componentId: number | string\n): Promise<{ uid: string; table: string; parentId: number | string } | null> => {\n // Get the parent schemas that could contain this component\n const parentSchemas = getParentSchemasForComponent(componentSchema);\n if (parentSchemas.length === 0) {\n // No potential parents\n return null;\n }\n\n // Find the actual parent for THIS specific component instance\n const parent = await findComponentParent(componentSchema, componentId, parentSchemas);\n if (!parent) {\n // No parent found for this component instance\n return null;\n }\n\n if (strapi.components[parent.uid as keyof typeof strapi.components]) {\n // If the parent is a component, we need to check its parents recursively\n const parentComponentSchema = strapi.components[parent.uid as keyof typeof strapi.components];\n return findContentTypeParentForComponentInstance(parentComponentSchema, parent.parentId);\n }\n\n if (strapi.contentTypes[parent.uid as keyof typeof strapi.contentTypes]) {\n // Found a content type parent\n return parent;\n }\n\n return null;\n};\n\n/**\n * Finds join table entries with publication state mismatches\n * Uses existing component parent detection from document service\n */\nconst findPublicationStateMismatches = async (\n db: Database,\n joinTableName: string,\n relation: any,\n targetModel: any,\n sourceModel: any\n): Promise<number[]> => {\n try {\n // Get join column names using proper functions (addressing PR feedback)\n const sourceColumn = relation.joinTable.joinColumn.name;\n const targetColumn = relation.joinTable.inverseJoinColumn.name;\n\n // Get all join entries with their target entities\n const query = db\n .connection(joinTableName)\n .select(\n `${joinTableName}.id as join_id`,\n `${joinTableName}.${sourceColumn} as source_id`,\n `${joinTableName}.${targetColumn} as target_id`,\n `${targetModel.tableName}.published_at as target_published_at`\n )\n .leftJoin(\n targetModel.tableName,\n `${joinTableName}.${targetColumn}`,\n `${targetModel.tableName}.id`\n );\n\n const joinEntries = await query;\n\n // Group by source_id to find duplicates pointing to draft/published versions of same entity\n const entriesBySource: { [key: string]: any[] } = {};\n for (const entry of joinEntries) {\n const sourceId = entry.source_id;\n if (!entriesBySource[sourceId]) {\n entriesBySource[sourceId] = [];\n }\n entriesBySource[sourceId].push(entry);\n }\n\n const ghostEntries: number[] = [];\n\n // Check if this is a join table (ends with _lnk)\n const isRelationJoinTable = joinTableName.endsWith('_lnk');\n const isComponentModel =\n !sourceModel.uid?.startsWith('api::') &&\n !sourceModel.uid?.startsWith('plugin::') &&\n sourceModel.uid?.includes('.');\n\n // Check for draft/publish inconsistencies\n for (const [sourceId, entries] of Object.entries(entriesBySource)) {\n // Skip entries with single relations\n if (entries.length <= 1) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n // For component join tables, check if THIS specific component instance's parent supports D&P\n if (isRelationJoinTable && isComponentModel) {\n try {\n const componentSchema = strapi.components[sourceModel.uid] as Schema.Component;\n if (!componentSchema) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n const parent = await findContentTypeParentForComponentInstance(componentSchema, sourceId);\n if (!parent) {\n continue;\n }\n\n // Check if THIS component instance's parent supports draft/publish\n const parentContentType =\n strapi.contentTypes[parent.uid as keyof typeof strapi.contentTypes];\n if (!parentContentType?.options?.draftAndPublish) {\n // This component instance's parent does NOT support D&P - skip cleanup\n // eslint-disable-next-line no-continue\n continue;\n }\n\n // If we reach here, this component instance's parent DOES support D&P\n // Continue to process this component instance for ghost relations\n } catch {\n // Skip this component instance on error\n // eslint-disable-next-line no-continue\n continue;\n }\n }\n\n // Find ghost relations (same logic as original but with improved parent checking)\n for (const entry of entries) {\n if (entry.target_published_at === null) {\n // This is a draft target - find its published version\n const draftTarget = await db\n .connection(targetModel.tableName)\n .select('document_id')\n .where('id', entry.target_id)\n .first();\n\n if (draftTarget) {\n const publishedVersion = await db\n .connection(targetModel.tableName)\n .select('id', 'document_id')\n .where('document_id', draftTarget.document_id)\n .whereNotNull('published_at')\n .first();\n\n if (publishedVersion) {\n // Check if we also have a relation to the published version\n const publishedRelation = entries.find((e) => e.target_id === publishedVersion.id);\n if (publishedRelation) {\n ghostEntries.push(publishedRelation.join_id);\n }\n }\n }\n }\n }\n }\n\n return ghostEntries;\n } catch {\n return [];\n }\n};\n"],"names":["cleanComponentJoinTable","db","joinTableName","relation","sourceModel","targetModel","metadata","get","target","logger","debug","sourceContentType","strapi","contentTypes","uid","sourceSupportsDraftPublish","options","draftAndPublish","targetContentType","targetSupportsDraftPublish","ghostEntries","findPublicationStateMismatches","length","connection","whereIn","del","error","errorMessage","Error","message","String","findContentTypeParentForComponentInstance","componentSchema","componentId","parentSchemas","getParentSchemasForComponent","parent","findComponentParent","components","parentComponentSchema","parentId","sourceColumn","joinTable","joinColumn","name","targetColumn","inverseJoinColumn","query","select","tableName","leftJoin","joinEntries","entriesBySource","entry","sourceId","source_id","push","isRelationJoinTable","endsWith","isComponentModel","startsWith","includes","entries","Object","parentContentType","target_published_at","draftTarget","where","target_id","first","publishedVersion","document_id","whereNotNull","publishedRelation","find","e","id","join_id"],"mappings":"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"}
@@ -111,7 +111,7 @@ const findContentTypeParentForComponentInstance = async (componentSchema, compon
111
111
  }
112
112
  // If we reach here, this component instance's parent DOES support D&P
113
113
  // Continue to process this component instance for ghost relations
114
- } catch (error) {
114
+ } catch {
115
115
  continue;
116
116
  }
117
117
  }
@@ -134,7 +134,7 @@ const findContentTypeParentForComponentInstance = async (componentSchema, compon
134
134
  }
135
135
  }
136
136
  return ghostEntries;
137
- } catch (error) {
137
+ } catch {
138
138
  return [];
139
139
  }
140
140
  };
@@ -1 +1 @@
1
- {"version":3,"file":"clean-component-join-table.mjs","sources":["../../../../src/services/document-service/utils/clean-component-join-table.ts"],"sourcesContent":["import type { Database } from '@strapi/database';\nimport type { Schema } from '@strapi/types';\nimport { findComponentParent, getParentSchemasForComponent } from '../components';\n\n/**\n * Cleans ghost relations with publication state mismatches from a join table\n * Uses schema-based draft/publish checking like prevention fix\n */\nexport const cleanComponentJoinTable = async (\n db: Database,\n joinTableName: string,\n relation: any,\n sourceModel: any\n): Promise<number> => {\n try {\n // Get the target model metadata\n const targetModel = db.metadata.get(relation.target);\n if (!targetModel) {\n db.logger.debug(`Target model ${relation.target} not found, skipping ${joinTableName}`);\n return 0;\n }\n\n // Check if source supports draft/publish, if it doesnt it should contain duplicate states\n const sourceContentType = strapi.contentTypes[sourceModel.uid];\n // It could be a model, which does not have the draftAndPublish option\n const sourceSupportsDraftPublish = sourceContentType?.options?.draftAndPublish;\n\n if (sourceContentType && !sourceSupportsDraftPublish) {\n return 0;\n }\n\n // Check if target supports draft/publish using schema-based approach (like prevention fix)\n const targetContentType =\n strapi.contentTypes[relation.target as keyof typeof strapi.contentTypes];\n const targetSupportsDraftPublish = targetContentType?.options?.draftAndPublish || false;\n\n if (!targetSupportsDraftPublish) {\n return 0;\n }\n\n // Find entries with publication state mismatches\n const ghostEntries = await findPublicationStateMismatches(\n db,\n joinTableName,\n relation,\n targetModel,\n sourceModel\n );\n\n if (ghostEntries.length === 0) {\n return 0;\n }\n\n // Remove ghost entries\n await db.connection(joinTableName).whereIn('id', ghostEntries).del();\n db.logger.debug(\n `Removed ${ghostEntries.length} ghost relations with publication state mismatches from ${joinTableName}`\n );\n\n return ghostEntries.length;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n db.logger.error(`Failed to clean join table \"${joinTableName}\": ${errorMessage}`);\n return 0;\n }\n};\n\nconst findContentTypeParentForComponentInstance = async (\n componentSchema: Schema.Component,\n componentId: number | string\n): Promise<{ uid: string; table: string; parentId: number | string } | null> => {\n // Get the parent schemas that could contain this component\n const parentSchemas = getParentSchemasForComponent(componentSchema);\n if (parentSchemas.length === 0) {\n // No potential parents\n return null;\n }\n\n // Find the actual parent for THIS specific component instance\n const parent = await findComponentParent(componentSchema, componentId, parentSchemas);\n if (!parent) {\n // No parent found for this component instance\n return null;\n }\n\n if (strapi.components[parent.uid as keyof typeof strapi.components]) {\n // If the parent is a component, we need to check its parents recursively\n const parentComponentSchema = strapi.components[parent.uid as keyof typeof strapi.components];\n return findContentTypeParentForComponentInstance(parentComponentSchema, parent.parentId);\n }\n\n if (strapi.contentTypes[parent.uid as keyof typeof strapi.contentTypes]) {\n // Found a content type parent\n return parent;\n }\n\n return null;\n};\n\n/**\n * Finds join table entries with publication state mismatches\n * Uses existing component parent detection from document service\n */\nconst findPublicationStateMismatches = async (\n db: Database,\n joinTableName: string,\n relation: any,\n targetModel: any,\n sourceModel: any\n): Promise<number[]> => {\n try {\n // Get join column names using proper functions (addressing PR feedback)\n const sourceColumn = relation.joinTable.joinColumn.name;\n const targetColumn = relation.joinTable.inverseJoinColumn.name;\n\n // Get all join entries with their target entities\n const query = db\n .connection(joinTableName)\n .select(\n `${joinTableName}.id as join_id`,\n `${joinTableName}.${sourceColumn} as source_id`,\n `${joinTableName}.${targetColumn} as target_id`,\n `${targetModel.tableName}.published_at as target_published_at`\n )\n .leftJoin(\n targetModel.tableName,\n `${joinTableName}.${targetColumn}`,\n `${targetModel.tableName}.id`\n );\n\n const joinEntries = await query;\n\n // Group by source_id to find duplicates pointing to draft/published versions of same entity\n const entriesBySource: { [key: string]: any[] } = {};\n for (const entry of joinEntries) {\n const sourceId = entry.source_id;\n if (!entriesBySource[sourceId]) {\n entriesBySource[sourceId] = [];\n }\n entriesBySource[sourceId].push(entry);\n }\n\n const ghostEntries: number[] = [];\n\n // Check if this is a join table (ends with _lnk)\n const isRelationJoinTable = joinTableName.endsWith('_lnk');\n const isComponentModel =\n !sourceModel.uid?.startsWith('api::') &&\n !sourceModel.uid?.startsWith('plugin::') &&\n sourceModel.uid?.includes('.');\n\n // Check for draft/publish inconsistencies\n for (const [sourceId, entries] of Object.entries(entriesBySource)) {\n // Skip entries with single relations\n if (entries.length <= 1) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n // For component join tables, check if THIS specific component instance's parent supports D&P\n if (isRelationJoinTable && isComponentModel) {\n try {\n const componentSchema = strapi.components[sourceModel.uid] as Schema.Component;\n if (!componentSchema) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n const parent = await findContentTypeParentForComponentInstance(componentSchema, sourceId);\n if (!parent) {\n continue;\n }\n\n // Check if THIS component instance's parent supports draft/publish\n const parentContentType =\n strapi.contentTypes[parent.uid as keyof typeof strapi.contentTypes];\n if (!parentContentType?.options?.draftAndPublish) {\n // This component instance's parent does NOT support D&P - skip cleanup\n // eslint-disable-next-line no-continue\n continue;\n }\n\n // If we reach here, this component instance's parent DOES support D&P\n // Continue to process this component instance for ghost relations\n } catch (error) {\n // Skip this component instance on error\n // eslint-disable-next-line no-continue\n continue;\n }\n }\n\n // Find ghost relations (same logic as original but with improved parent checking)\n for (const entry of entries) {\n if (entry.target_published_at === null) {\n // This is a draft target - find its published version\n const draftTarget = await db\n .connection(targetModel.tableName)\n .select('document_id')\n .where('id', entry.target_id)\n .first();\n\n if (draftTarget) {\n const publishedVersion = await db\n .connection(targetModel.tableName)\n .select('id', 'document_id')\n .where('document_id', draftTarget.document_id)\n .whereNotNull('published_at')\n .first();\n\n if (publishedVersion) {\n // Check if we also have a relation to the published version\n const publishedRelation = entries.find((e) => e.target_id === publishedVersion.id);\n if (publishedRelation) {\n ghostEntries.push(publishedRelation.join_id);\n }\n }\n }\n }\n }\n }\n\n return ghostEntries;\n } catch (error) {\n return [];\n }\n};\n"],"names":["cleanComponentJoinTable","db","joinTableName","relation","sourceModel","targetModel","metadata","get","target","logger","debug","sourceContentType","strapi","contentTypes","uid","sourceSupportsDraftPublish","options","draftAndPublish","targetContentType","targetSupportsDraftPublish","ghostEntries","findPublicationStateMismatches","length","connection","whereIn","del","error","errorMessage","Error","message","String","findContentTypeParentForComponentInstance","componentSchema","componentId","parentSchemas","getParentSchemasForComponent","parent","findComponentParent","components","parentComponentSchema","parentId","sourceColumn","joinTable","joinColumn","name","targetColumn","inverseJoinColumn","query","select","tableName","leftJoin","joinEntries","entriesBySource","entry","sourceId","source_id","push","isRelationJoinTable","endsWith","isComponentModel","startsWith","includes","entries","Object","parentContentType","target_published_at","draftTarget","where","target_id","first","publishedVersion","document_id","whereNotNull","publishedRelation","find","e","id","join_id"],"mappings":"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"}
1
+ {"version":3,"file":"clean-component-join-table.mjs","sources":["../../../../src/services/document-service/utils/clean-component-join-table.ts"],"sourcesContent":["import type { Database } from '@strapi/database';\nimport type { Schema } from '@strapi/types';\nimport { findComponentParent, getParentSchemasForComponent } from '../components';\n\n/**\n * Cleans ghost relations with publication state mismatches from a join table\n * Uses schema-based draft/publish checking like prevention fix\n */\nexport const cleanComponentJoinTable = async (\n db: Database,\n joinTableName: string,\n relation: any,\n sourceModel: any\n): Promise<number> => {\n try {\n // Get the target model metadata\n const targetModel = db.metadata.get(relation.target);\n if (!targetModel) {\n db.logger.debug(`Target model ${relation.target} not found, skipping ${joinTableName}`);\n return 0;\n }\n\n // Check if source supports draft/publish, if it doesnt it should contain duplicate states\n const sourceContentType = strapi.contentTypes[sourceModel.uid];\n // It could be a model, which does not have the draftAndPublish option\n const sourceSupportsDraftPublish = sourceContentType?.options?.draftAndPublish;\n\n if (sourceContentType && !sourceSupportsDraftPublish) {\n return 0;\n }\n\n // Check if target supports draft/publish using schema-based approach (like prevention fix)\n const targetContentType =\n strapi.contentTypes[relation.target as keyof typeof strapi.contentTypes];\n const targetSupportsDraftPublish = targetContentType?.options?.draftAndPublish || false;\n\n if (!targetSupportsDraftPublish) {\n return 0;\n }\n\n // Find entries with publication state mismatches\n const ghostEntries = await findPublicationStateMismatches(\n db,\n joinTableName,\n relation,\n targetModel,\n sourceModel\n );\n\n if (ghostEntries.length === 0) {\n return 0;\n }\n\n // Remove ghost entries\n await db.connection(joinTableName).whereIn('id', ghostEntries).del();\n db.logger.debug(\n `Removed ${ghostEntries.length} ghost relations with publication state mismatches from ${joinTableName}`\n );\n\n return ghostEntries.length;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n db.logger.error(`Failed to clean join table \"${joinTableName}\": ${errorMessage}`);\n return 0;\n }\n};\n\nconst findContentTypeParentForComponentInstance = async (\n componentSchema: Schema.Component,\n componentId: number | string\n): Promise<{ uid: string; table: string; parentId: number | string } | null> => {\n // Get the parent schemas that could contain this component\n const parentSchemas = getParentSchemasForComponent(componentSchema);\n if (parentSchemas.length === 0) {\n // No potential parents\n return null;\n }\n\n // Find the actual parent for THIS specific component instance\n const parent = await findComponentParent(componentSchema, componentId, parentSchemas);\n if (!parent) {\n // No parent found for this component instance\n return null;\n }\n\n if (strapi.components[parent.uid as keyof typeof strapi.components]) {\n // If the parent is a component, we need to check its parents recursively\n const parentComponentSchema = strapi.components[parent.uid as keyof typeof strapi.components];\n return findContentTypeParentForComponentInstance(parentComponentSchema, parent.parentId);\n }\n\n if (strapi.contentTypes[parent.uid as keyof typeof strapi.contentTypes]) {\n // Found a content type parent\n return parent;\n }\n\n return null;\n};\n\n/**\n * Finds join table entries with publication state mismatches\n * Uses existing component parent detection from document service\n */\nconst findPublicationStateMismatches = async (\n db: Database,\n joinTableName: string,\n relation: any,\n targetModel: any,\n sourceModel: any\n): Promise<number[]> => {\n try {\n // Get join column names using proper functions (addressing PR feedback)\n const sourceColumn = relation.joinTable.joinColumn.name;\n const targetColumn = relation.joinTable.inverseJoinColumn.name;\n\n // Get all join entries with their target entities\n const query = db\n .connection(joinTableName)\n .select(\n `${joinTableName}.id as join_id`,\n `${joinTableName}.${sourceColumn} as source_id`,\n `${joinTableName}.${targetColumn} as target_id`,\n `${targetModel.tableName}.published_at as target_published_at`\n )\n .leftJoin(\n targetModel.tableName,\n `${joinTableName}.${targetColumn}`,\n `${targetModel.tableName}.id`\n );\n\n const joinEntries = await query;\n\n // Group by source_id to find duplicates pointing to draft/published versions of same entity\n const entriesBySource: { [key: string]: any[] } = {};\n for (const entry of joinEntries) {\n const sourceId = entry.source_id;\n if (!entriesBySource[sourceId]) {\n entriesBySource[sourceId] = [];\n }\n entriesBySource[sourceId].push(entry);\n }\n\n const ghostEntries: number[] = [];\n\n // Check if this is a join table (ends with _lnk)\n const isRelationJoinTable = joinTableName.endsWith('_lnk');\n const isComponentModel =\n !sourceModel.uid?.startsWith('api::') &&\n !sourceModel.uid?.startsWith('plugin::') &&\n sourceModel.uid?.includes('.');\n\n // Check for draft/publish inconsistencies\n for (const [sourceId, entries] of Object.entries(entriesBySource)) {\n // Skip entries with single relations\n if (entries.length <= 1) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n // For component join tables, check if THIS specific component instance's parent supports D&P\n if (isRelationJoinTable && isComponentModel) {\n try {\n const componentSchema = strapi.components[sourceModel.uid] as Schema.Component;\n if (!componentSchema) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n const parent = await findContentTypeParentForComponentInstance(componentSchema, sourceId);\n if (!parent) {\n continue;\n }\n\n // Check if THIS component instance's parent supports draft/publish\n const parentContentType =\n strapi.contentTypes[parent.uid as keyof typeof strapi.contentTypes];\n if (!parentContentType?.options?.draftAndPublish) {\n // This component instance's parent does NOT support D&P - skip cleanup\n // eslint-disable-next-line no-continue\n continue;\n }\n\n // If we reach here, this component instance's parent DOES support D&P\n // Continue to process this component instance for ghost relations\n } catch {\n // Skip this component instance on error\n // eslint-disable-next-line no-continue\n continue;\n }\n }\n\n // Find ghost relations (same logic as original but with improved parent checking)\n for (const entry of entries) {\n if (entry.target_published_at === null) {\n // This is a draft target - find its published version\n const draftTarget = await db\n .connection(targetModel.tableName)\n .select('document_id')\n .where('id', entry.target_id)\n .first();\n\n if (draftTarget) {\n const publishedVersion = await db\n .connection(targetModel.tableName)\n .select('id', 'document_id')\n .where('document_id', draftTarget.document_id)\n .whereNotNull('published_at')\n .first();\n\n if (publishedVersion) {\n // Check if we also have a relation to the published version\n const publishedRelation = entries.find((e) => e.target_id === publishedVersion.id);\n if (publishedRelation) {\n ghostEntries.push(publishedRelation.join_id);\n }\n }\n }\n }\n }\n }\n\n return ghostEntries;\n } catch {\n return [];\n }\n};\n"],"names":["cleanComponentJoinTable","db","joinTableName","relation","sourceModel","targetModel","metadata","get","target","logger","debug","sourceContentType","strapi","contentTypes","uid","sourceSupportsDraftPublish","options","draftAndPublish","targetContentType","targetSupportsDraftPublish","ghostEntries","findPublicationStateMismatches","length","connection","whereIn","del","error","errorMessage","Error","message","String","findContentTypeParentForComponentInstance","componentSchema","componentId","parentSchemas","getParentSchemasForComponent","parent","findComponentParent","components","parentComponentSchema","parentId","sourceColumn","joinTable","joinColumn","name","targetColumn","inverseJoinColumn","query","select","tableName","leftJoin","joinEntries","entriesBySource","entry","sourceId","source_id","push","isRelationJoinTable","endsWith","isComponentModel","startsWith","includes","entries","Object","parentContentType","target_published_at","draftTarget","where","target_id","first","publishedVersion","document_id","whereNotNull","publishedRelation","find","e","id","join_id"],"mappings":"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"}
@@ -102,7 +102,7 @@ const copyCloneRelationRows = async (strapi, uid, sourceEntryId, targetEntryId,
102
102
  const { joinColumn } = joinTable;
103
103
  const rows = await strapi.db.connection(joinTable.name).where({
104
104
  [joinColumn.name]: sourceEntryId,
105
- ...'on' in joinTable && joinTable.on || {}
105
+ ...'on' in joinTable && joinTable.on || undefined
106
106
  }).select('*').transacting(trx);
107
107
  const rowsToCopy = rows.map((row)=>{
108
108
  const copiedRow = {
@@ -1 +1 @@
1
- {"version":3,"file":"clone-relations.js","sources":["../../../../src/services/document-service/utils/clone-relations.ts"],"sourcesContent":["import { merge, set } from 'lodash/fp';\n\nimport type { Core, Schema, UID } from '@strapi/types';\nimport type { traverseEntity } from '@strapi/utils';\nimport { traverseEntityRelations } from '../transform/relations/utils/map-relation';\n\nconst RELATION_OPERATIONS = ['connect', 'disconnect', 'set'] as const;\ntype TraversableData = Parameters<typeof traverseEntity>[2];\n\ntype CloneRelationAttribute = Schema.Attribute.Relation & {\n targetAttribute?: string;\n};\n\nconst isRecord = (value: unknown): value is Record<string, unknown> => {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n};\n\nconst isRelationAttribute = (attribute: unknown): attribute is CloneRelationAttribute => {\n return (\n isRecord(attribute) && attribute.type === 'relation' && typeof attribute.relation === 'string'\n );\n};\n\nconst isRelationOperationPayload = (value: unknown): value is Record<string, unknown> => {\n return (\n isRecord(value) &&\n RELATION_OPERATIONS.some((operation) => Object.prototype.hasOwnProperty.call(value, operation))\n );\n};\n\nconst hasMeaningfulRelationOperations = (value: Record<string, unknown>) => {\n if (Object.prototype.hasOwnProperty.call(value, 'set')) {\n return true;\n }\n\n return ['connect', 'disconnect'].some((operation) => {\n const operationValue = value[operation];\n return Array.isArray(operationValue) ? operationValue.length > 0 : operationValue != null;\n });\n};\n\nconst canTransformRelationOperationPayload = (attribute: Schema.Attribute.Relation) => {\n return attribute.useJoinTable !== false && attribute.relation !== 'morphToOne';\n};\n\nconst isBidirectionalOneToOne = (attribute: CloneRelationAttribute) => {\n return (\n attribute.relation === 'oneToOne' &&\n [attribute.inversedBy, attribute.mappedBy, attribute.targetAttribute].some(\n (inverseAttribute) => inverseAttribute != null\n )\n );\n};\n\nconst hasPopulatedRelation = (value: unknown) => {\n return isRecord(value) && ('id' in value || 'documentId' in value);\n};\n\nconst collectRelationOperationOverrides = async (\n submittedData: Record<string, unknown>,\n contentType: Schema.ContentType,\n getModel: (uid: string) => Schema.Schema\n) => {\n const overrides = new Map<string, Record<string, unknown>>();\n\n await traverseEntityRelations(\n ({ path, value }) => {\n if (isRelationOperationPayload(value) && hasMeaningfulRelationOperations(value)) {\n overrides.set(path.rawWithIndices!, value);\n }\n },\n { schema: contentType, getModel },\n submittedData as TraversableData\n );\n\n return [...overrides.entries()].sort(([leftPath], [rightPath]) =>\n leftPath.localeCompare(rightPath)\n );\n};\n\nexport const prepareCloneData = async (\n originalData: Record<string, unknown>,\n submittedData: Record<string, unknown> | undefined,\n contentType: Schema.ContentType,\n getModel: (uid: string) => Schema.Schema\n) => {\n const submitted = submittedData ?? {};\n const relationOperationOverrides = await collectRelationOperationOverrides(\n submitted,\n contentType,\n getModel\n );\n let data = merge(originalData, submitted) as Record<string, unknown>;\n const relationsToCopy: string[] = [];\n\n for (const [attributeName, attribute] of Object.entries(contentType.attributes)) {\n if (!isRelationAttribute(attribute) || !canTransformRelationOperationPayload(attribute)) {\n continue;\n }\n\n const relationWasSubmitted = Object.prototype.hasOwnProperty.call(submitted, attributeName);\n const submittedValue = submitted[attributeName];\n const isOperationPayload = isRelationOperationPayload(submittedValue);\n const hasMeaningfulOperations =\n isOperationPayload && hasMeaningfulRelationOperations(submittedValue);\n\n const relationIsUnchanged =\n !relationWasSubmitted || (isOperationPayload && !hasMeaningfulOperations);\n\n if (\n relationIsUnchanged &&\n isBidirectionalOneToOne(attribute) &&\n hasPopulatedRelation(originalData[attributeName])\n ) {\n // Normal relation attachment enforces oneToOne ownership by removing the source link.\n // Leave unchanged relations out of create and copy their join row after the clone exists.\n delete data[attributeName];\n relationsToCopy.push(attributeName);\n }\n }\n\n for (const [path, value] of relationOperationOverrides) {\n data = set(path, value, data) as Record<string, unknown>;\n }\n\n return { data, relationsToCopy };\n};\n\nexport const copyCloneRelationRows = async (\n strapi: Core.Strapi,\n uid: UID.ContentType,\n sourceEntryId: number,\n targetEntryId: number,\n attributeNames: string[]\n) => {\n if (attributeNames.length === 0) {\n return;\n }\n\n const { attributes } = strapi.db.metadata.get(uid);\n const idColumn = strapi.db.metadata.identifiers.ID_COLUMN;\n const batchSize = strapi.db.dialect.getBatchInsertSize();\n\n await strapi.db.transaction(async ({ trx }) => {\n for (const attributeName of attributeNames) {\n const attribute = attributes[attributeName];\n\n if (attribute?.type !== 'relation' || !('joinTable' in attribute) || !attribute.joinTable) {\n continue;\n }\n\n const { joinTable } = attribute;\n const { joinColumn } = joinTable;\n const rows = (await strapi.db\n .connection(joinTable.name)\n .where({\n [joinColumn.name]: sourceEntryId,\n ...(('on' in joinTable && joinTable.on) || {}),\n })\n .select('*')\n .transacting(trx)) as Record<string, unknown>[];\n\n const rowsToCopy = rows.map((row) => {\n const copiedRow = { ...row, [joinColumn.name]: targetEntryId };\n delete copiedRow[idColumn];\n return copiedRow;\n });\n\n for (let index = 0; index < rowsToCopy.length; index += batchSize) {\n await strapi.db\n .connection(joinTable.name)\n .insert(rowsToCopy.slice(index, index + batchSize))\n .transacting(trx);\n }\n }\n });\n};\n"],"names":["RELATION_OPERATIONS","isRecord","value","Array","isArray","isRelationAttribute","attribute","type","relation","isRelationOperationPayload","some","operation","Object","prototype","hasOwnProperty","call","hasMeaningfulRelationOperations","operationValue","length","canTransformRelationOperationPayload","useJoinTable","isBidirectionalOneToOne","inversedBy","mappedBy","targetAttribute","inverseAttribute","hasPopulatedRelation","collectRelationOperationOverrides","submittedData","contentType","getModel","overrides","Map","traverseEntityRelations","path","set","rawWithIndices","schema","entries","sort","leftPath","rightPath","localeCompare","prepareCloneData","originalData","submitted","relationOperationOverrides","data","merge","relationsToCopy","attributeName","attributes","relationWasSubmitted","submittedValue","isOperationPayload","hasMeaningfulOperations","relationIsUnchanged","push","copyCloneRelationRows","strapi","uid","sourceEntryId","targetEntryId","attributeNames","db","metadata","get","idColumn","identifiers","ID_COLUMN","batchSize","dialect","getBatchInsertSize","transaction","trx","joinTable","joinColumn","rows","connection","name","where","on","select","transacting","rowsToCopy","map","row","copiedRow","index","insert","slice"],"mappings":"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"}
1
+ {"version":3,"file":"clone-relations.js","sources":["../../../../src/services/document-service/utils/clone-relations.ts"],"sourcesContent":["import { merge, set } from 'lodash/fp';\n\nimport type { Core, Schema, UID } from '@strapi/types';\nimport type { traverseEntity } from '@strapi/utils';\nimport { traverseEntityRelations } from '../transform/relations/utils/map-relation';\n\nconst RELATION_OPERATIONS = ['connect', 'disconnect', 'set'] as const;\ntype TraversableData = Parameters<typeof traverseEntity>[2];\n\ntype CloneRelationAttribute = Schema.Attribute.Relation & {\n targetAttribute?: string;\n};\n\nconst isRecord = (value: unknown): value is Record<string, unknown> => {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n};\n\nconst isRelationAttribute = (attribute: unknown): attribute is CloneRelationAttribute => {\n return (\n isRecord(attribute) && attribute.type === 'relation' && typeof attribute.relation === 'string'\n );\n};\n\nconst isRelationOperationPayload = (value: unknown): value is Record<string, unknown> => {\n return (\n isRecord(value) &&\n RELATION_OPERATIONS.some((operation) => Object.prototype.hasOwnProperty.call(value, operation))\n );\n};\n\nconst hasMeaningfulRelationOperations = (value: Record<string, unknown>) => {\n if (Object.prototype.hasOwnProperty.call(value, 'set')) {\n return true;\n }\n\n return ['connect', 'disconnect'].some((operation) => {\n const operationValue = value[operation];\n return Array.isArray(operationValue) ? operationValue.length > 0 : operationValue != null;\n });\n};\n\nconst canTransformRelationOperationPayload = (attribute: Schema.Attribute.Relation) => {\n return attribute.useJoinTable !== false && attribute.relation !== 'morphToOne';\n};\n\nconst isBidirectionalOneToOne = (attribute: CloneRelationAttribute) => {\n return (\n attribute.relation === 'oneToOne' &&\n [attribute.inversedBy, attribute.mappedBy, attribute.targetAttribute].some(\n (inverseAttribute) => inverseAttribute != null\n )\n );\n};\n\nconst hasPopulatedRelation = (value: unknown) => {\n return isRecord(value) && ('id' in value || 'documentId' in value);\n};\n\nconst collectRelationOperationOverrides = async (\n submittedData: Record<string, unknown>,\n contentType: Schema.ContentType,\n getModel: (uid: string) => Schema.Schema\n) => {\n const overrides = new Map<string, Record<string, unknown>>();\n\n await traverseEntityRelations(\n ({ path, value }) => {\n if (isRelationOperationPayload(value) && hasMeaningfulRelationOperations(value)) {\n overrides.set(path.rawWithIndices!, value);\n }\n },\n { schema: contentType, getModel },\n submittedData as TraversableData\n );\n\n return [...overrides.entries()].sort(([leftPath], [rightPath]) =>\n leftPath.localeCompare(rightPath)\n );\n};\n\nexport const prepareCloneData = async (\n originalData: Record<string, unknown>,\n submittedData: Record<string, unknown> | undefined,\n contentType: Schema.ContentType,\n getModel: (uid: string) => Schema.Schema\n) => {\n const submitted = submittedData ?? {};\n const relationOperationOverrides = await collectRelationOperationOverrides(\n submitted,\n contentType,\n getModel\n );\n let data = merge(originalData, submitted) as Record<string, unknown>;\n const relationsToCopy: string[] = [];\n\n for (const [attributeName, attribute] of Object.entries(contentType.attributes)) {\n if (!isRelationAttribute(attribute) || !canTransformRelationOperationPayload(attribute)) {\n continue;\n }\n\n const relationWasSubmitted = Object.prototype.hasOwnProperty.call(submitted, attributeName);\n const submittedValue = submitted[attributeName];\n const isOperationPayload = isRelationOperationPayload(submittedValue);\n const hasMeaningfulOperations =\n isOperationPayload && hasMeaningfulRelationOperations(submittedValue);\n\n const relationIsUnchanged =\n !relationWasSubmitted || (isOperationPayload && !hasMeaningfulOperations);\n\n if (\n relationIsUnchanged &&\n isBidirectionalOneToOne(attribute) &&\n hasPopulatedRelation(originalData[attributeName])\n ) {\n // Normal relation attachment enforces oneToOne ownership by removing the source link.\n // Leave unchanged relations out of create and copy their join row after the clone exists.\n delete data[attributeName];\n relationsToCopy.push(attributeName);\n }\n }\n\n for (const [path, value] of relationOperationOverrides) {\n data = set(path, value, data) as Record<string, unknown>;\n }\n\n return { data, relationsToCopy };\n};\n\nexport const copyCloneRelationRows = async (\n strapi: Core.Strapi,\n uid: UID.ContentType,\n sourceEntryId: number,\n targetEntryId: number,\n attributeNames: string[]\n) => {\n if (attributeNames.length === 0) {\n return;\n }\n\n const { attributes } = strapi.db.metadata.get(uid);\n const idColumn = strapi.db.metadata.identifiers.ID_COLUMN;\n const batchSize = strapi.db.dialect.getBatchInsertSize();\n\n await strapi.db.transaction(async ({ trx }) => {\n for (const attributeName of attributeNames) {\n const attribute = attributes[attributeName];\n\n if (attribute?.type !== 'relation' || !('joinTable' in attribute) || !attribute.joinTable) {\n continue;\n }\n\n const { joinTable } = attribute;\n const { joinColumn } = joinTable;\n const rows = (await strapi.db\n .connection(joinTable.name)\n .where({\n [joinColumn.name]: sourceEntryId,\n ...(('on' in joinTable && joinTable.on) || undefined),\n })\n .select('*')\n .transacting(trx)) as Record<string, unknown>[];\n\n const rowsToCopy = rows.map((row) => {\n const copiedRow = { ...row, [joinColumn.name]: targetEntryId };\n delete copiedRow[idColumn];\n return copiedRow;\n });\n\n for (let index = 0; index < rowsToCopy.length; index += batchSize) {\n await strapi.db\n .connection(joinTable.name)\n .insert(rowsToCopy.slice(index, index + batchSize))\n .transacting(trx);\n }\n }\n });\n};\n"],"names":["RELATION_OPERATIONS","isRecord","value","Array","isArray","isRelationAttribute","attribute","type","relation","isRelationOperationPayload","some","operation","Object","prototype","hasOwnProperty","call","hasMeaningfulRelationOperations","operationValue","length","canTransformRelationOperationPayload","useJoinTable","isBidirectionalOneToOne","inversedBy","mappedBy","targetAttribute","inverseAttribute","hasPopulatedRelation","collectRelationOperationOverrides","submittedData","contentType","getModel","overrides","Map","traverseEntityRelations","path","set","rawWithIndices","schema","entries","sort","leftPath","rightPath","localeCompare","prepareCloneData","originalData","submitted","relationOperationOverrides","data","merge","relationsToCopy","attributeName","attributes","relationWasSubmitted","submittedValue","isOperationPayload","hasMeaningfulOperations","relationIsUnchanged","push","copyCloneRelationRows","strapi","uid","sourceEntryId","targetEntryId","attributeNames","db","metadata","get","idColumn","identifiers","ID_COLUMN","batchSize","dialect","getBatchInsertSize","transaction","trx","joinTable","joinColumn","rows","connection","name","where","on","undefined","select","transacting","rowsToCopy","map","row","copiedRow","index","insert","slice"],"mappings":"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"}
@@ -100,7 +100,7 @@ const copyCloneRelationRows = async (strapi, uid, sourceEntryId, targetEntryId,
100
100
  const { joinColumn } = joinTable;
101
101
  const rows = await strapi.db.connection(joinTable.name).where({
102
102
  [joinColumn.name]: sourceEntryId,
103
- ...'on' in joinTable && joinTable.on || {}
103
+ ...'on' in joinTable && joinTable.on || undefined
104
104
  }).select('*').transacting(trx);
105
105
  const rowsToCopy = rows.map((row)=>{
106
106
  const copiedRow = {
@@ -1 +1 @@
1
- {"version":3,"file":"clone-relations.mjs","sources":["../../../../src/services/document-service/utils/clone-relations.ts"],"sourcesContent":["import { merge, set } from 'lodash/fp';\n\nimport type { Core, Schema, UID } from '@strapi/types';\nimport type { traverseEntity } from '@strapi/utils';\nimport { traverseEntityRelations } from '../transform/relations/utils/map-relation';\n\nconst RELATION_OPERATIONS = ['connect', 'disconnect', 'set'] as const;\ntype TraversableData = Parameters<typeof traverseEntity>[2];\n\ntype CloneRelationAttribute = Schema.Attribute.Relation & {\n targetAttribute?: string;\n};\n\nconst isRecord = (value: unknown): value is Record<string, unknown> => {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n};\n\nconst isRelationAttribute = (attribute: unknown): attribute is CloneRelationAttribute => {\n return (\n isRecord(attribute) && attribute.type === 'relation' && typeof attribute.relation === 'string'\n );\n};\n\nconst isRelationOperationPayload = (value: unknown): value is Record<string, unknown> => {\n return (\n isRecord(value) &&\n RELATION_OPERATIONS.some((operation) => Object.prototype.hasOwnProperty.call(value, operation))\n );\n};\n\nconst hasMeaningfulRelationOperations = (value: Record<string, unknown>) => {\n if (Object.prototype.hasOwnProperty.call(value, 'set')) {\n return true;\n }\n\n return ['connect', 'disconnect'].some((operation) => {\n const operationValue = value[operation];\n return Array.isArray(operationValue) ? operationValue.length > 0 : operationValue != null;\n });\n};\n\nconst canTransformRelationOperationPayload = (attribute: Schema.Attribute.Relation) => {\n return attribute.useJoinTable !== false && attribute.relation !== 'morphToOne';\n};\n\nconst isBidirectionalOneToOne = (attribute: CloneRelationAttribute) => {\n return (\n attribute.relation === 'oneToOne' &&\n [attribute.inversedBy, attribute.mappedBy, attribute.targetAttribute].some(\n (inverseAttribute) => inverseAttribute != null\n )\n );\n};\n\nconst hasPopulatedRelation = (value: unknown) => {\n return isRecord(value) && ('id' in value || 'documentId' in value);\n};\n\nconst collectRelationOperationOverrides = async (\n submittedData: Record<string, unknown>,\n contentType: Schema.ContentType,\n getModel: (uid: string) => Schema.Schema\n) => {\n const overrides = new Map<string, Record<string, unknown>>();\n\n await traverseEntityRelations(\n ({ path, value }) => {\n if (isRelationOperationPayload(value) && hasMeaningfulRelationOperations(value)) {\n overrides.set(path.rawWithIndices!, value);\n }\n },\n { schema: contentType, getModel },\n submittedData as TraversableData\n );\n\n return [...overrides.entries()].sort(([leftPath], [rightPath]) =>\n leftPath.localeCompare(rightPath)\n );\n};\n\nexport const prepareCloneData = async (\n originalData: Record<string, unknown>,\n submittedData: Record<string, unknown> | undefined,\n contentType: Schema.ContentType,\n getModel: (uid: string) => Schema.Schema\n) => {\n const submitted = submittedData ?? {};\n const relationOperationOverrides = await collectRelationOperationOverrides(\n submitted,\n contentType,\n getModel\n );\n let data = merge(originalData, submitted) as Record<string, unknown>;\n const relationsToCopy: string[] = [];\n\n for (const [attributeName, attribute] of Object.entries(contentType.attributes)) {\n if (!isRelationAttribute(attribute) || !canTransformRelationOperationPayload(attribute)) {\n continue;\n }\n\n const relationWasSubmitted = Object.prototype.hasOwnProperty.call(submitted, attributeName);\n const submittedValue = submitted[attributeName];\n const isOperationPayload = isRelationOperationPayload(submittedValue);\n const hasMeaningfulOperations =\n isOperationPayload && hasMeaningfulRelationOperations(submittedValue);\n\n const relationIsUnchanged =\n !relationWasSubmitted || (isOperationPayload && !hasMeaningfulOperations);\n\n if (\n relationIsUnchanged &&\n isBidirectionalOneToOne(attribute) &&\n hasPopulatedRelation(originalData[attributeName])\n ) {\n // Normal relation attachment enforces oneToOne ownership by removing the source link.\n // Leave unchanged relations out of create and copy their join row after the clone exists.\n delete data[attributeName];\n relationsToCopy.push(attributeName);\n }\n }\n\n for (const [path, value] of relationOperationOverrides) {\n data = set(path, value, data) as Record<string, unknown>;\n }\n\n return { data, relationsToCopy };\n};\n\nexport const copyCloneRelationRows = async (\n strapi: Core.Strapi,\n uid: UID.ContentType,\n sourceEntryId: number,\n targetEntryId: number,\n attributeNames: string[]\n) => {\n if (attributeNames.length === 0) {\n return;\n }\n\n const { attributes } = strapi.db.metadata.get(uid);\n const idColumn = strapi.db.metadata.identifiers.ID_COLUMN;\n const batchSize = strapi.db.dialect.getBatchInsertSize();\n\n await strapi.db.transaction(async ({ trx }) => {\n for (const attributeName of attributeNames) {\n const attribute = attributes[attributeName];\n\n if (attribute?.type !== 'relation' || !('joinTable' in attribute) || !attribute.joinTable) {\n continue;\n }\n\n const { joinTable } = attribute;\n const { joinColumn } = joinTable;\n const rows = (await strapi.db\n .connection(joinTable.name)\n .where({\n [joinColumn.name]: sourceEntryId,\n ...(('on' in joinTable && joinTable.on) || {}),\n })\n .select('*')\n .transacting(trx)) as Record<string, unknown>[];\n\n const rowsToCopy = rows.map((row) => {\n const copiedRow = { ...row, [joinColumn.name]: targetEntryId };\n delete copiedRow[idColumn];\n return copiedRow;\n });\n\n for (let index = 0; index < rowsToCopy.length; index += batchSize) {\n await strapi.db\n .connection(joinTable.name)\n .insert(rowsToCopy.slice(index, index + batchSize))\n .transacting(trx);\n }\n }\n });\n};\n"],"names":["RELATION_OPERATIONS","isRecord","value","Array","isArray","isRelationAttribute","attribute","type","relation","isRelationOperationPayload","some","operation","Object","prototype","hasOwnProperty","call","hasMeaningfulRelationOperations","operationValue","length","canTransformRelationOperationPayload","useJoinTable","isBidirectionalOneToOne","inversedBy","mappedBy","targetAttribute","inverseAttribute","hasPopulatedRelation","collectRelationOperationOverrides","submittedData","contentType","getModel","overrides","Map","traverseEntityRelations","path","set","rawWithIndices","schema","entries","sort","leftPath","rightPath","localeCompare","prepareCloneData","originalData","submitted","relationOperationOverrides","data","merge","relationsToCopy","attributeName","attributes","relationWasSubmitted","submittedValue","isOperationPayload","hasMeaningfulOperations","relationIsUnchanged","push","copyCloneRelationRows","strapi","uid","sourceEntryId","targetEntryId","attributeNames","db","metadata","get","idColumn","identifiers","ID_COLUMN","batchSize","dialect","getBatchInsertSize","transaction","trx","joinTable","joinColumn","rows","connection","name","where","on","select","transacting","rowsToCopy","map","row","copiedRow","index","insert","slice"],"mappings":"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"}
1
+ {"version":3,"file":"clone-relations.mjs","sources":["../../../../src/services/document-service/utils/clone-relations.ts"],"sourcesContent":["import { merge, set } from 'lodash/fp';\n\nimport type { Core, Schema, UID } from '@strapi/types';\nimport type { traverseEntity } from '@strapi/utils';\nimport { traverseEntityRelations } from '../transform/relations/utils/map-relation';\n\nconst RELATION_OPERATIONS = ['connect', 'disconnect', 'set'] as const;\ntype TraversableData = Parameters<typeof traverseEntity>[2];\n\ntype CloneRelationAttribute = Schema.Attribute.Relation & {\n targetAttribute?: string;\n};\n\nconst isRecord = (value: unknown): value is Record<string, unknown> => {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n};\n\nconst isRelationAttribute = (attribute: unknown): attribute is CloneRelationAttribute => {\n return (\n isRecord(attribute) && attribute.type === 'relation' && typeof attribute.relation === 'string'\n );\n};\n\nconst isRelationOperationPayload = (value: unknown): value is Record<string, unknown> => {\n return (\n isRecord(value) &&\n RELATION_OPERATIONS.some((operation) => Object.prototype.hasOwnProperty.call(value, operation))\n );\n};\n\nconst hasMeaningfulRelationOperations = (value: Record<string, unknown>) => {\n if (Object.prototype.hasOwnProperty.call(value, 'set')) {\n return true;\n }\n\n return ['connect', 'disconnect'].some((operation) => {\n const operationValue = value[operation];\n return Array.isArray(operationValue) ? operationValue.length > 0 : operationValue != null;\n });\n};\n\nconst canTransformRelationOperationPayload = (attribute: Schema.Attribute.Relation) => {\n return attribute.useJoinTable !== false && attribute.relation !== 'morphToOne';\n};\n\nconst isBidirectionalOneToOne = (attribute: CloneRelationAttribute) => {\n return (\n attribute.relation === 'oneToOne' &&\n [attribute.inversedBy, attribute.mappedBy, attribute.targetAttribute].some(\n (inverseAttribute) => inverseAttribute != null\n )\n );\n};\n\nconst hasPopulatedRelation = (value: unknown) => {\n return isRecord(value) && ('id' in value || 'documentId' in value);\n};\n\nconst collectRelationOperationOverrides = async (\n submittedData: Record<string, unknown>,\n contentType: Schema.ContentType,\n getModel: (uid: string) => Schema.Schema\n) => {\n const overrides = new Map<string, Record<string, unknown>>();\n\n await traverseEntityRelations(\n ({ path, value }) => {\n if (isRelationOperationPayload(value) && hasMeaningfulRelationOperations(value)) {\n overrides.set(path.rawWithIndices!, value);\n }\n },\n { schema: contentType, getModel },\n submittedData as TraversableData\n );\n\n return [...overrides.entries()].sort(([leftPath], [rightPath]) =>\n leftPath.localeCompare(rightPath)\n );\n};\n\nexport const prepareCloneData = async (\n originalData: Record<string, unknown>,\n submittedData: Record<string, unknown> | undefined,\n contentType: Schema.ContentType,\n getModel: (uid: string) => Schema.Schema\n) => {\n const submitted = submittedData ?? {};\n const relationOperationOverrides = await collectRelationOperationOverrides(\n submitted,\n contentType,\n getModel\n );\n let data = merge(originalData, submitted) as Record<string, unknown>;\n const relationsToCopy: string[] = [];\n\n for (const [attributeName, attribute] of Object.entries(contentType.attributes)) {\n if (!isRelationAttribute(attribute) || !canTransformRelationOperationPayload(attribute)) {\n continue;\n }\n\n const relationWasSubmitted = Object.prototype.hasOwnProperty.call(submitted, attributeName);\n const submittedValue = submitted[attributeName];\n const isOperationPayload = isRelationOperationPayload(submittedValue);\n const hasMeaningfulOperations =\n isOperationPayload && hasMeaningfulRelationOperations(submittedValue);\n\n const relationIsUnchanged =\n !relationWasSubmitted || (isOperationPayload && !hasMeaningfulOperations);\n\n if (\n relationIsUnchanged &&\n isBidirectionalOneToOne(attribute) &&\n hasPopulatedRelation(originalData[attributeName])\n ) {\n // Normal relation attachment enforces oneToOne ownership by removing the source link.\n // Leave unchanged relations out of create and copy their join row after the clone exists.\n delete data[attributeName];\n relationsToCopy.push(attributeName);\n }\n }\n\n for (const [path, value] of relationOperationOverrides) {\n data = set(path, value, data) as Record<string, unknown>;\n }\n\n return { data, relationsToCopy };\n};\n\nexport const copyCloneRelationRows = async (\n strapi: Core.Strapi,\n uid: UID.ContentType,\n sourceEntryId: number,\n targetEntryId: number,\n attributeNames: string[]\n) => {\n if (attributeNames.length === 0) {\n return;\n }\n\n const { attributes } = strapi.db.metadata.get(uid);\n const idColumn = strapi.db.metadata.identifiers.ID_COLUMN;\n const batchSize = strapi.db.dialect.getBatchInsertSize();\n\n await strapi.db.transaction(async ({ trx }) => {\n for (const attributeName of attributeNames) {\n const attribute = attributes[attributeName];\n\n if (attribute?.type !== 'relation' || !('joinTable' in attribute) || !attribute.joinTable) {\n continue;\n }\n\n const { joinTable } = attribute;\n const { joinColumn } = joinTable;\n const rows = (await strapi.db\n .connection(joinTable.name)\n .where({\n [joinColumn.name]: sourceEntryId,\n ...(('on' in joinTable && joinTable.on) || undefined),\n })\n .select('*')\n .transacting(trx)) as Record<string, unknown>[];\n\n const rowsToCopy = rows.map((row) => {\n const copiedRow = { ...row, [joinColumn.name]: targetEntryId };\n delete copiedRow[idColumn];\n return copiedRow;\n });\n\n for (let index = 0; index < rowsToCopy.length; index += batchSize) {\n await strapi.db\n .connection(joinTable.name)\n .insert(rowsToCopy.slice(index, index + batchSize))\n .transacting(trx);\n }\n }\n });\n};\n"],"names":["RELATION_OPERATIONS","isRecord","value","Array","isArray","isRelationAttribute","attribute","type","relation","isRelationOperationPayload","some","operation","Object","prototype","hasOwnProperty","call","hasMeaningfulRelationOperations","operationValue","length","canTransformRelationOperationPayload","useJoinTable","isBidirectionalOneToOne","inversedBy","mappedBy","targetAttribute","inverseAttribute","hasPopulatedRelation","collectRelationOperationOverrides","submittedData","contentType","getModel","overrides","Map","traverseEntityRelations","path","set","rawWithIndices","schema","entries","sort","leftPath","rightPath","localeCompare","prepareCloneData","originalData","submitted","relationOperationOverrides","data","merge","relationsToCopy","attributeName","attributes","relationWasSubmitted","submittedValue","isOperationPayload","hasMeaningfulOperations","relationIsUnchanged","push","copyCloneRelationRows","strapi","uid","sourceEntryId","targetEntryId","attributeNames","db","metadata","get","idColumn","identifiers","ID_COLUMN","batchSize","dialect","getBatchInsertSize","transaction","trx","joinTable","joinColumn","rows","connection","name","where","on","undefined","select","transacting","rowsToCopy","map","row","copiedRow","index","insert","slice"],"mappings":"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"}
@@ -19,7 +19,7 @@ const checkValidLink = (link)=>{
19
19
  try {
20
20
  // eslint-disable-next-line no-new
21
21
  new URL(link.startsWith('/') ? `https://strapi.io${link}` : link);
22
- } catch (error) {
22
+ } catch {
23
23
  return false;
24
24
  }
25
25
  return true;
@@ -1 +1 @@
1
- {"version":3,"file":"blocks-validator.js","sources":["../../../src/services/entity-validator/blocks-validator.ts"],"sourcesContent":["import { yup } from '@strapi/utils';\n\nconst textNodeValidator = yup.object().shape({\n type: yup.string().equals(['text']).required(),\n text: yup\n .string()\n .test(\n 'is-valid-text',\n 'Text must be defined with at least an empty string',\n (text: unknown) => {\n return typeof text === 'string' || text === '';\n }\n ),\n bold: yup.boolean(),\n italic: yup.boolean(),\n underline: yup.boolean(),\n strikethrough: yup.boolean(),\n code: yup.boolean(),\n});\n\nconst checkValidLink = (link: string) => {\n try {\n // eslint-disable-next-line no-new\n new URL(link.startsWith('/') ? `https://strapi.io${link}` : link);\n } catch (error) {\n return false;\n }\n return true;\n};\n\nconst linkNodeValidator = yup.object().shape({\n type: yup.string().equals(['link']).required(),\n url: yup\n .string()\n .test('invalid-url', 'Please specify a valid link.', (value) => checkValidLink(value ?? '')),\n children: yup.array().of(textNodeValidator).required(),\n});\n\n// TODO: remove any with a correct Type\nconst inlineNodeValidator: any = yup.lazy((value: { type: string }) => {\n switch (value.type) {\n case 'text':\n return textNodeValidator;\n case 'link':\n return linkNodeValidator;\n default:\n return yup.mixed().test('invalid-type', 'Inline node must be Text or Link', () => {\n return false;\n });\n }\n});\n\nconst paragraphNodeValidator = yup.object().shape({\n type: yup.string().equals(['paragraph']).required(),\n children: yup\n .array()\n .of(inlineNodeValidator)\n .min(1, 'Paragraph node children must have at least one Text or Link node')\n .required(),\n});\n\nconst headingNodeValidator = yup.object().shape({\n type: yup.string().equals(['heading']).required(),\n level: yup.number().oneOf([1, 2, 3, 4, 5, 6]).required(),\n children: yup\n .array()\n .of(inlineNodeValidator)\n .min(1, 'Heading node children must have at least one Text or Link node')\n .required(),\n});\n\nconst quoteNodeValidator = yup.object().shape({\n type: yup.string().equals(['quote']).required(),\n children: yup\n .array()\n .of(inlineNodeValidator)\n .min(1, 'Quote node children must have at least one Text or Link node')\n .required(),\n});\n\nconst codeBlockValidator = yup.object().shape({\n type: yup.string().equals(['code']).required(),\n language: yup.string().nullable(),\n children: yup\n .array()\n .of(textNodeValidator)\n .min(1, 'Quote node children must have at least one Text or Link node')\n .required(),\n});\n\nconst listItemNode = yup.object().shape({\n type: yup.string().equals(['list-item']).required(),\n children: yup.array().of(inlineNodeValidator).required(),\n});\n\n// Allow children to be either a listItemNode or a listNode itself\n// @ts-expect-error - listChildrenValidator needs a type\nconst listChildrenValidator = yup.lazy((value: { type: string }) => {\n switch (value.type) {\n case 'list':\n return listNodeValidator;\n case 'list-item':\n return listItemNode;\n default:\n return yup.mixed().test('invalid-type', 'Inline node must be list-item or list', () => {\n return false;\n });\n }\n});\n\n// @ts-expect-error - listNodeValidator needs a type\nconst listNodeValidator = yup.object().shape({\n type: yup.string().equals(['list']).required(),\n format: yup.string().equals(['ordered', 'unordered']).required(),\n children: yup\n .array()\n .of(listChildrenValidator)\n .min(1, 'List node children must have at least one ListItem or ListNode')\n .required(),\n});\n\nconst imageNodeValidator = yup.object().shape({\n type: yup.string().equals(['image']).required(),\n image: yup.object().shape({\n name: yup.string().required(),\n alternativeText: yup.string().nullable(),\n url: yup.string().required(),\n caption: yup.string().nullable(),\n width: yup.number().required(),\n height: yup.number().required(),\n formats: yup.object().nullable(),\n hash: yup.string().required(),\n ext: yup.string().required(),\n mime: yup.string().required(),\n size: yup.number().required(),\n previewUrl: yup.string().nullable(),\n provider: yup.string().required(),\n provider_metadata: yup.mixed().nullable(),\n createdAt: yup.string().required(),\n updatedAt: yup.string().required(),\n }),\n children: yup.array().of(inlineNodeValidator).required(),\n});\n\n// TODO: remove the any and replace with a correct Type\nconst blockNodeValidator: any = yup.lazy((value: { type: string }) => {\n switch (value.type) {\n case 'paragraph':\n return paragraphNodeValidator;\n case 'heading':\n return headingNodeValidator;\n case 'quote':\n return quoteNodeValidator;\n case 'list':\n return listNodeValidator;\n case 'image':\n return imageNodeValidator;\n case 'code':\n return codeBlockValidator;\n default:\n return yup.mixed().test('invalid-type', 'Block node is of invalid type', () => {\n return false;\n });\n }\n});\n\nconst blocksValidatorSchema = yup.array().of(blockNodeValidator);\n\nexport const blocksValidator = () => blocksValidatorSchema;\n"],"names":["textNodeValidator","yup","object","shape","type","string","equals","required","text","test","bold","boolean","italic","underline","strikethrough","code","checkValidLink","link","URL","startsWith","error","linkNodeValidator","url","value","children","array","of","inlineNodeValidator","lazy","mixed","paragraphNodeValidator","min","headingNodeValidator","level","number","oneOf","quoteNodeValidator","codeBlockValidator","language","nullable","listItemNode","listChildrenValidator","listNodeValidator","format","imageNodeValidator","image","name","alternativeText","caption","width","height","formats","hash","ext","mime","size","previewUrl","provider","provider_metadata","createdAt","updatedAt","blockNodeValidator","blocksValidatorSchema","blocksValidator"],"mappings":"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"}
1
+ {"version":3,"file":"blocks-validator.js","sources":["../../../src/services/entity-validator/blocks-validator.ts"],"sourcesContent":["import { yup } from '@strapi/utils';\n\nconst textNodeValidator = yup.object().shape({\n type: yup.string().equals(['text']).required(),\n text: yup\n .string()\n .test(\n 'is-valid-text',\n 'Text must be defined with at least an empty string',\n (text: unknown) => {\n return typeof text === 'string' || text === '';\n }\n ),\n bold: yup.boolean(),\n italic: yup.boolean(),\n underline: yup.boolean(),\n strikethrough: yup.boolean(),\n code: yup.boolean(),\n});\n\nconst checkValidLink = (link: string) => {\n try {\n // eslint-disable-next-line no-new\n new URL(link.startsWith('/') ? `https://strapi.io${link}` : link);\n } catch {\n return false;\n }\n return true;\n};\n\nconst linkNodeValidator = yup.object().shape({\n type: yup.string().equals(['link']).required(),\n url: yup\n .string()\n .test('invalid-url', 'Please specify a valid link.', (value) => checkValidLink(value ?? '')),\n children: yup.array().of(textNodeValidator).required(),\n});\n\n// TODO: remove any with a correct Type\nconst inlineNodeValidator: any = yup.lazy((value: { type: string }) => {\n switch (value.type) {\n case 'text':\n return textNodeValidator;\n case 'link':\n return linkNodeValidator;\n default:\n return yup.mixed().test('invalid-type', 'Inline node must be Text or Link', () => {\n return false;\n });\n }\n});\n\nconst paragraphNodeValidator = yup.object().shape({\n type: yup.string().equals(['paragraph']).required(),\n children: yup\n .array()\n .of(inlineNodeValidator)\n .min(1, 'Paragraph node children must have at least one Text or Link node')\n .required(),\n});\n\nconst headingNodeValidator = yup.object().shape({\n type: yup.string().equals(['heading']).required(),\n level: yup.number().oneOf([1, 2, 3, 4, 5, 6]).required(),\n children: yup\n .array()\n .of(inlineNodeValidator)\n .min(1, 'Heading node children must have at least one Text or Link node')\n .required(),\n});\n\nconst quoteNodeValidator = yup.object().shape({\n type: yup.string().equals(['quote']).required(),\n children: yup\n .array()\n .of(inlineNodeValidator)\n .min(1, 'Quote node children must have at least one Text or Link node')\n .required(),\n});\n\nconst codeBlockValidator = yup.object().shape({\n type: yup.string().equals(['code']).required(),\n language: yup.string().nullable(),\n children: yup\n .array()\n .of(textNodeValidator)\n .min(1, 'Quote node children must have at least one Text or Link node')\n .required(),\n});\n\nconst listItemNode = yup.object().shape({\n type: yup.string().equals(['list-item']).required(),\n children: yup.array().of(inlineNodeValidator).required(),\n});\n\n// Allow children to be either a listItemNode or a listNode itself\n// @ts-expect-error - listChildrenValidator needs a type\nconst listChildrenValidator = yup.lazy((value: { type: string }) => {\n switch (value.type) {\n case 'list':\n return listNodeValidator;\n case 'list-item':\n return listItemNode;\n default:\n return yup.mixed().test('invalid-type', 'Inline node must be list-item or list', () => {\n return false;\n });\n }\n});\n\n// @ts-expect-error - listNodeValidator needs a type\nconst listNodeValidator = yup.object().shape({\n type: yup.string().equals(['list']).required(),\n format: yup.string().equals(['ordered', 'unordered']).required(),\n children: yup\n .array()\n .of(listChildrenValidator)\n .min(1, 'List node children must have at least one ListItem or ListNode')\n .required(),\n});\n\nconst imageNodeValidator = yup.object().shape({\n type: yup.string().equals(['image']).required(),\n image: yup.object().shape({\n name: yup.string().required(),\n alternativeText: yup.string().nullable(),\n url: yup.string().required(),\n caption: yup.string().nullable(),\n width: yup.number().required(),\n height: yup.number().required(),\n formats: yup.object().nullable(),\n hash: yup.string().required(),\n ext: yup.string().required(),\n mime: yup.string().required(),\n size: yup.number().required(),\n previewUrl: yup.string().nullable(),\n provider: yup.string().required(),\n provider_metadata: yup.mixed().nullable(),\n createdAt: yup.string().required(),\n updatedAt: yup.string().required(),\n }),\n children: yup.array().of(inlineNodeValidator).required(),\n});\n\n// TODO: remove the any and replace with a correct Type\nconst blockNodeValidator: any = yup.lazy((value: { type: string }) => {\n switch (value.type) {\n case 'paragraph':\n return paragraphNodeValidator;\n case 'heading':\n return headingNodeValidator;\n case 'quote':\n return quoteNodeValidator;\n case 'list':\n return listNodeValidator;\n case 'image':\n return imageNodeValidator;\n case 'code':\n return codeBlockValidator;\n default:\n return yup.mixed().test('invalid-type', 'Block node is of invalid type', () => {\n return false;\n });\n }\n});\n\nconst blocksValidatorSchema = yup.array().of(blockNodeValidator);\n\nexport const blocksValidator = () => blocksValidatorSchema;\n"],"names":["textNodeValidator","yup","object","shape","type","string","equals","required","text","test","bold","boolean","italic","underline","strikethrough","code","checkValidLink","link","URL","startsWith","linkNodeValidator","url","value","children","array","of","inlineNodeValidator","lazy","mixed","paragraphNodeValidator","min","headingNodeValidator","level","number","oneOf","quoteNodeValidator","codeBlockValidator","language","nullable","listItemNode","listChildrenValidator","listNodeValidator","format","imageNodeValidator","image","name","alternativeText","caption","width","height","formats","hash","ext","mime","size","previewUrl","provider","provider_metadata","createdAt","updatedAt","blockNodeValidator","blocksValidatorSchema","blocksValidator"],"mappings":";;;;AAEA,MAAMA,iBAAAA,GAAoBC,eAAAA,CAAIC,MAAM,EAAA,CAAGC,KAAK,CAAC;AAC3CC,IAAAA,IAAAA,EAAMH,eAAAA,CAAII,MAAM,EAAA,CAAGC,MAAM,CAAC;AAAC,QAAA;AAAO,KAAA,CAAA,CAAEC,QAAQ,EAAA;AAC5CC,IAAAA,IAAAA,EAAMP,gBACHI,MAAM,EAAA,CACNI,IAAI,CACH,eAAA,EACA,sDACA,CAACD,IAAAA,GAAAA;QACC,OAAO,OAAOA,IAAAA,KAAS,QAAA,IAAYA,IAAAA,KAAS,EAAA;AAC9C,IAAA,CAAA,CAAA;AAEJE,IAAAA,IAAAA,EAAMT,gBAAIU,OAAO,EAAA;AACjBC,IAAAA,MAAAA,EAAQX,gBAAIU,OAAO,EAAA;AACnBE,IAAAA,SAAAA,EAAWZ,gBAAIU,OAAO,EAAA;AACtBG,IAAAA,aAAAA,EAAeb,gBAAIU,OAAO,EAAA;AAC1BI,IAAAA,IAAAA,EAAMd,gBAAIU,OAAO;AACnB,CAAA,CAAA;AAEA,MAAMK,iBAAiB,CAACC,IAAAA,GAAAA;IACtB,IAAI;;QAEF,IAAIC,GAAAA,CAAID,KAAKE,UAAU,CAAC,OAAO,CAAC,iBAAiB,EAAEF,IAAAA,CAAAA,CAAM,GAAGA,IAAAA,CAAAA;AAC9D,IAAA,CAAA,CAAE,OAAM;QACN,OAAO,KAAA;AACT,IAAA;IACA,OAAO,IAAA;AACT,CAAA;AAEA,MAAMG,iBAAAA,GAAoBnB,eAAAA,CAAIC,MAAM,EAAA,CAAGC,KAAK,CAAC;AAC3CC,IAAAA,IAAAA,EAAMH,eAAAA,CAAII,MAAM,EAAA,CAAGC,MAAM,CAAC;AAAC,QAAA;AAAO,KAAA,CAAA,CAAEC,QAAQ,EAAA;IAC5Cc,GAAAA,EAAKpB,eAAAA,CACFI,MAAM,EAAA,CACNI,IAAI,CAAC,eAAe,8BAAA,EAAgC,CAACa,KAAAA,GAAUN,cAAAA,CAAeM,KAAAA,IAAS,EAAA,CAAA,CAAA;AAC1FC,IAAAA,QAAAA,EAAUtB,gBAAIuB,KAAK,EAAA,CAAGC,EAAE,CAACzB,mBAAmBO,QAAQ;AACtD,CAAA,CAAA;AAEA;AACA,MAAMmB,mBAAAA,GAA2BzB,eAAAA,CAAI0B,IAAI,CAAC,CAACL,KAAAA,GAAAA;AACzC,IAAA,OAAQA,MAAMlB,IAAI;QAChB,KAAK,MAAA;YACH,OAAOJ,iBAAAA;QACT,KAAK,MAAA;YACH,OAAOoB,iBAAAA;AACT,QAAA;AACE,YAAA,OAAOnB,gBAAI2B,KAAK,EAAA,CAAGnB,IAAI,CAAC,gBAAgB,kCAAA,EAAoC,IAAA;gBAC1E,OAAO,KAAA;AACT,YAAA,CAAA,CAAA;AACJ;AACF,CAAA,CAAA;AAEA,MAAMoB,sBAAAA,GAAyB5B,eAAAA,CAAIC,MAAM,EAAA,CAAGC,KAAK,CAAC;AAChDC,IAAAA,IAAAA,EAAMH,eAAAA,CAAII,MAAM,EAAA,CAAGC,MAAM,CAAC;AAAC,QAAA;AAAY,KAAA,CAAA,CAAEC,QAAQ,EAAA;IACjDgB,QAAAA,EAAUtB,eAAAA,CACPuB,KAAK,EAAA,CACLC,EAAE,CAACC,qBACHI,GAAG,CAAC,CAAA,EAAG,kEAAA,CAAA,CACPvB,QAAQ;AACb,CAAA,CAAA;AAEA,MAAMwB,oBAAAA,GAAuB9B,eAAAA,CAAIC,MAAM,EAAA,CAAGC,KAAK,CAAC;AAC9CC,IAAAA,IAAAA,EAAMH,eAAAA,CAAII,MAAM,EAAA,CAAGC,MAAM,CAAC;AAAC,QAAA;AAAU,KAAA,CAAA,CAAEC,QAAQ,EAAA;AAC/CyB,IAAAA,KAAAA,EAAO/B,eAAAA,CAAIgC,MAAM,EAAA,CAAGC,KAAK,CAAC;AAAC,QAAA,CAAA;AAAG,QAAA,CAAA;AAAG,QAAA,CAAA;AAAG,QAAA,CAAA;AAAG,QAAA,CAAA;AAAG,QAAA;AAAE,KAAA,CAAA,CAAE3B,QAAQ,EAAA;IACtDgB,QAAAA,EAAUtB,eAAAA,CACPuB,KAAK,EAAA,CACLC,EAAE,CAACC,qBACHI,GAAG,CAAC,CAAA,EAAG,gEAAA,CAAA,CACPvB,QAAQ;AACb,CAAA,CAAA;AAEA,MAAM4B,kBAAAA,GAAqBlC,eAAAA,CAAIC,MAAM,EAAA,CAAGC,KAAK,CAAC;AAC5CC,IAAAA,IAAAA,EAAMH,eAAAA,CAAII,MAAM,EAAA,CAAGC,MAAM,CAAC;AAAC,QAAA;AAAQ,KAAA,CAAA,CAAEC,QAAQ,EAAA;IAC7CgB,QAAAA,EAAUtB,eAAAA,CACPuB,KAAK,EAAA,CACLC,EAAE,CAACC,qBACHI,GAAG,CAAC,CAAA,EAAG,8DAAA,CAAA,CACPvB,QAAQ;AACb,CAAA,CAAA;AAEA,MAAM6B,kBAAAA,GAAqBnC,eAAAA,CAAIC,MAAM,EAAA,CAAGC,KAAK,CAAC;AAC5CC,IAAAA,IAAAA,EAAMH,eAAAA,CAAII,MAAM,EAAA,CAAGC,MAAM,CAAC;AAAC,QAAA;AAAO,KAAA,CAAA,CAAEC,QAAQ,EAAA;IAC5C8B,QAAAA,EAAUpC,eAAAA,CAAII,MAAM,EAAA,CAAGiC,QAAQ,EAAA;IAC/Bf,QAAAA,EAAUtB,eAAAA,CACPuB,KAAK,EAAA,CACLC,EAAE,CAACzB,mBACH8B,GAAG,CAAC,CAAA,EAAG,8DAAA,CAAA,CACPvB,QAAQ;AACb,CAAA,CAAA;AAEA,MAAMgC,YAAAA,GAAetC,eAAAA,CAAIC,MAAM,EAAA,CAAGC,KAAK,CAAC;AACtCC,IAAAA,IAAAA,EAAMH,eAAAA,CAAII,MAAM,EAAA,CAAGC,MAAM,CAAC;AAAC,QAAA;AAAY,KAAA,CAAA,CAAEC,QAAQ,EAAA;AACjDgB,IAAAA,QAAAA,EAAUtB,gBAAIuB,KAAK,EAAA,CAAGC,EAAE,CAACC,qBAAqBnB,QAAQ;AACxD,CAAA,CAAA;AAEA;AACA;AACA,MAAMiC,qBAAAA,GAAwBvC,eAAAA,CAAI0B,IAAI,CAAC,CAACL,KAAAA,GAAAA;AACtC,IAAA,OAAQA,MAAMlB,IAAI;QAChB,KAAK,MAAA;YACH,OAAOqC,iBAAAA;QACT,KAAK,WAAA;YACH,OAAOF,YAAAA;AACT,QAAA;AACE,YAAA,OAAOtC,gBAAI2B,KAAK,EAAA,CAAGnB,IAAI,CAAC,gBAAgB,uCAAA,EAAyC,IAAA;gBAC/E,OAAO,KAAA;AACT,YAAA,CAAA,CAAA;AACJ;AACF,CAAA,CAAA;AAEA;AACA,MAAMgC,iBAAAA,GAAoBxC,eAAAA,CAAIC,MAAM,EAAA,CAAGC,KAAK,CAAC;AAC3CC,IAAAA,IAAAA,EAAMH,eAAAA,CAAII,MAAM,EAAA,CAAGC,MAAM,CAAC;AAAC,QAAA;AAAO,KAAA,CAAA,CAAEC,QAAQ,EAAA;AAC5CmC,IAAAA,MAAAA,EAAQzC,eAAAA,CAAII,MAAM,EAAA,CAAGC,MAAM,CAAC;AAAC,QAAA,SAAA;AAAW,QAAA;AAAY,KAAA,CAAA,CAAEC,QAAQ,EAAA;IAC9DgB,QAAAA,EAAUtB,eAAAA,CACPuB,KAAK,EAAA,CACLC,EAAE,CAACe,uBACHV,GAAG,CAAC,CAAA,EAAG,gEAAA,CAAA,CACPvB,QAAQ;AACb,CAAA,CAAA;AAEA,MAAMoC,kBAAAA,GAAqB1C,eAAAA,CAAIC,MAAM,EAAA,CAAGC,KAAK,CAAC;AAC5CC,IAAAA,IAAAA,EAAMH,eAAAA,CAAII,MAAM,EAAA,CAAGC,MAAM,CAAC;AAAC,QAAA;AAAQ,KAAA,CAAA,CAAEC,QAAQ,EAAA;AAC7CqC,IAAAA,KAAAA,EAAO3C,eAAAA,CAAIC,MAAM,EAAA,CAAGC,KAAK,CAAC;QACxB0C,IAAAA,EAAM5C,eAAAA,CAAII,MAAM,EAAA,CAAGE,QAAQ,EAAA;QAC3BuC,eAAAA,EAAiB7C,eAAAA,CAAII,MAAM,EAAA,CAAGiC,QAAQ,EAAA;QACtCjB,GAAAA,EAAKpB,eAAAA,CAAII,MAAM,EAAA,CAAGE,QAAQ,EAAA;QAC1BwC,OAAAA,EAAS9C,eAAAA,CAAII,MAAM,EAAA,CAAGiC,QAAQ,EAAA;QAC9BU,KAAAA,EAAO/C,eAAAA,CAAIgC,MAAM,EAAA,CAAG1B,QAAQ,EAAA;QAC5B0C,MAAAA,EAAQhD,eAAAA,CAAIgC,MAAM,EAAA,CAAG1B,QAAQ,EAAA;QAC7B2C,OAAAA,EAASjD,eAAAA,CAAIC,MAAM,EAAA,CAAGoC,QAAQ,EAAA;QAC9Ba,IAAAA,EAAMlD,eAAAA,CAAII,MAAM,EAAA,CAAGE,QAAQ,EAAA;QAC3B6C,GAAAA,EAAKnD,eAAAA,CAAII,MAAM,EAAA,CAAGE,QAAQ,EAAA;QAC1B8C,IAAAA,EAAMpD,eAAAA,CAAII,MAAM,EAAA,CAAGE,QAAQ,EAAA;QAC3B+C,IAAAA,EAAMrD,eAAAA,CAAIgC,MAAM,EAAA,CAAG1B,QAAQ,EAAA;QAC3BgD,UAAAA,EAAYtD,eAAAA,CAAII,MAAM,EAAA,CAAGiC,QAAQ,EAAA;QACjCkB,QAAAA,EAAUvD,eAAAA,CAAII,MAAM,EAAA,CAAGE,QAAQ,EAAA;QAC/BkD,iBAAAA,EAAmBxD,eAAAA,CAAI2B,KAAK,EAAA,CAAGU,QAAQ,EAAA;QACvCoB,SAAAA,EAAWzD,eAAAA,CAAII,MAAM,EAAA,CAAGE,QAAQ,EAAA;QAChCoD,SAAAA,EAAW1D,eAAAA,CAAII,MAAM,EAAA,CAAGE,QAAQ;AAClC,KAAA,CAAA;AACAgB,IAAAA,QAAAA,EAAUtB,gBAAIuB,KAAK,EAAA,CAAGC,EAAE,CAACC,qBAAqBnB,QAAQ;AACxD,CAAA,CAAA;AAEA;AACA,MAAMqD,kBAAAA,GAA0B3D,eAAAA,CAAI0B,IAAI,CAAC,CAACL,KAAAA,GAAAA;AACxC,IAAA,OAAQA,MAAMlB,IAAI;QAChB,KAAK,WAAA;YACH,OAAOyB,sBAAAA;QACT,KAAK,SAAA;YACH,OAAOE,oBAAAA;QACT,KAAK,OAAA;YACH,OAAOI,kBAAAA;QACT,KAAK,MAAA;YACH,OAAOM,iBAAAA;QACT,KAAK,OAAA;YACH,OAAOE,kBAAAA;QACT,KAAK,MAAA;YACH,OAAOP,kBAAAA;AACT,QAAA;AACE,YAAA,OAAOnC,gBAAI2B,KAAK,EAAA,CAAGnB,IAAI,CAAC,gBAAgB,+BAAA,EAAiC,IAAA;gBACvE,OAAO,KAAA;AACT,YAAA,CAAA,CAAA;AACJ;AACF,CAAA,CAAA;AAEA,MAAMoD,qBAAAA,GAAwB5D,eAAAA,CAAIuB,KAAK,EAAA,CAAGC,EAAE,CAACmC,kBAAAA,CAAAA;AAEtC,MAAME,eAAAA,GAAkB,IAAMD;;;;"}
@@ -17,7 +17,7 @@ const checkValidLink = (link)=>{
17
17
  try {
18
18
  // eslint-disable-next-line no-new
19
19
  new URL(link.startsWith('/') ? `https://strapi.io${link}` : link);
20
- } catch (error) {
20
+ } catch {
21
21
  return false;
22
22
  }
23
23
  return true;
@@ -1 +1 @@
1
- {"version":3,"file":"blocks-validator.mjs","sources":["../../../src/services/entity-validator/blocks-validator.ts"],"sourcesContent":["import { yup } from '@strapi/utils';\n\nconst textNodeValidator = yup.object().shape({\n type: yup.string().equals(['text']).required(),\n text: yup\n .string()\n .test(\n 'is-valid-text',\n 'Text must be defined with at least an empty string',\n (text: unknown) => {\n return typeof text === 'string' || text === '';\n }\n ),\n bold: yup.boolean(),\n italic: yup.boolean(),\n underline: yup.boolean(),\n strikethrough: yup.boolean(),\n code: yup.boolean(),\n});\n\nconst checkValidLink = (link: string) => {\n try {\n // eslint-disable-next-line no-new\n new URL(link.startsWith('/') ? `https://strapi.io${link}` : link);\n } catch (error) {\n return false;\n }\n return true;\n};\n\nconst linkNodeValidator = yup.object().shape({\n type: yup.string().equals(['link']).required(),\n url: yup\n .string()\n .test('invalid-url', 'Please specify a valid link.', (value) => checkValidLink(value ?? '')),\n children: yup.array().of(textNodeValidator).required(),\n});\n\n// TODO: remove any with a correct Type\nconst inlineNodeValidator: any = yup.lazy((value: { type: string }) => {\n switch (value.type) {\n case 'text':\n return textNodeValidator;\n case 'link':\n return linkNodeValidator;\n default:\n return yup.mixed().test('invalid-type', 'Inline node must be Text or Link', () => {\n return false;\n });\n }\n});\n\nconst paragraphNodeValidator = yup.object().shape({\n type: yup.string().equals(['paragraph']).required(),\n children: yup\n .array()\n .of(inlineNodeValidator)\n .min(1, 'Paragraph node children must have at least one Text or Link node')\n .required(),\n});\n\nconst headingNodeValidator = yup.object().shape({\n type: yup.string().equals(['heading']).required(),\n level: yup.number().oneOf([1, 2, 3, 4, 5, 6]).required(),\n children: yup\n .array()\n .of(inlineNodeValidator)\n .min(1, 'Heading node children must have at least one Text or Link node')\n .required(),\n});\n\nconst quoteNodeValidator = yup.object().shape({\n type: yup.string().equals(['quote']).required(),\n children: yup\n .array()\n .of(inlineNodeValidator)\n .min(1, 'Quote node children must have at least one Text or Link node')\n .required(),\n});\n\nconst codeBlockValidator = yup.object().shape({\n type: yup.string().equals(['code']).required(),\n language: yup.string().nullable(),\n children: yup\n .array()\n .of(textNodeValidator)\n .min(1, 'Quote node children must have at least one Text or Link node')\n .required(),\n});\n\nconst listItemNode = yup.object().shape({\n type: yup.string().equals(['list-item']).required(),\n children: yup.array().of(inlineNodeValidator).required(),\n});\n\n// Allow children to be either a listItemNode or a listNode itself\n// @ts-expect-error - listChildrenValidator needs a type\nconst listChildrenValidator = yup.lazy((value: { type: string }) => {\n switch (value.type) {\n case 'list':\n return listNodeValidator;\n case 'list-item':\n return listItemNode;\n default:\n return yup.mixed().test('invalid-type', 'Inline node must be list-item or list', () => {\n return false;\n });\n }\n});\n\n// @ts-expect-error - listNodeValidator needs a type\nconst listNodeValidator = yup.object().shape({\n type: yup.string().equals(['list']).required(),\n format: yup.string().equals(['ordered', 'unordered']).required(),\n children: yup\n .array()\n .of(listChildrenValidator)\n .min(1, 'List node children must have at least one ListItem or ListNode')\n .required(),\n});\n\nconst imageNodeValidator = yup.object().shape({\n type: yup.string().equals(['image']).required(),\n image: yup.object().shape({\n name: yup.string().required(),\n alternativeText: yup.string().nullable(),\n url: yup.string().required(),\n caption: yup.string().nullable(),\n width: yup.number().required(),\n height: yup.number().required(),\n formats: yup.object().nullable(),\n hash: yup.string().required(),\n ext: yup.string().required(),\n mime: yup.string().required(),\n size: yup.number().required(),\n previewUrl: yup.string().nullable(),\n provider: yup.string().required(),\n provider_metadata: yup.mixed().nullable(),\n createdAt: yup.string().required(),\n updatedAt: yup.string().required(),\n }),\n children: yup.array().of(inlineNodeValidator).required(),\n});\n\n// TODO: remove the any and replace with a correct Type\nconst blockNodeValidator: any = yup.lazy((value: { type: string }) => {\n switch (value.type) {\n case 'paragraph':\n return paragraphNodeValidator;\n case 'heading':\n return headingNodeValidator;\n case 'quote':\n return quoteNodeValidator;\n case 'list':\n return listNodeValidator;\n case 'image':\n return imageNodeValidator;\n case 'code':\n return codeBlockValidator;\n default:\n return yup.mixed().test('invalid-type', 'Block node is of invalid type', () => {\n return false;\n });\n }\n});\n\nconst blocksValidatorSchema = yup.array().of(blockNodeValidator);\n\nexport const blocksValidator = () => blocksValidatorSchema;\n"],"names":["textNodeValidator","yup","object","shape","type","string","equals","required","text","test","bold","boolean","italic","underline","strikethrough","code","checkValidLink","link","URL","startsWith","error","linkNodeValidator","url","value","children","array","of","inlineNodeValidator","lazy","mixed","paragraphNodeValidator","min","headingNodeValidator","level","number","oneOf","quoteNodeValidator","codeBlockValidator","language","nullable","listItemNode","listChildrenValidator","listNodeValidator","format","imageNodeValidator","image","name","alternativeText","caption","width","height","formats","hash","ext","mime","size","previewUrl","provider","provider_metadata","createdAt","updatedAt","blockNodeValidator","blocksValidatorSchema","blocksValidator"],"mappings":"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"}
1
+ {"version":3,"file":"blocks-validator.mjs","sources":["../../../src/services/entity-validator/blocks-validator.ts"],"sourcesContent":["import { yup } from '@strapi/utils';\n\nconst textNodeValidator = yup.object().shape({\n type: yup.string().equals(['text']).required(),\n text: yup\n .string()\n .test(\n 'is-valid-text',\n 'Text must be defined with at least an empty string',\n (text: unknown) => {\n return typeof text === 'string' || text === '';\n }\n ),\n bold: yup.boolean(),\n italic: yup.boolean(),\n underline: yup.boolean(),\n strikethrough: yup.boolean(),\n code: yup.boolean(),\n});\n\nconst checkValidLink = (link: string) => {\n try {\n // eslint-disable-next-line no-new\n new URL(link.startsWith('/') ? `https://strapi.io${link}` : link);\n } catch {\n return false;\n }\n return true;\n};\n\nconst linkNodeValidator = yup.object().shape({\n type: yup.string().equals(['link']).required(),\n url: yup\n .string()\n .test('invalid-url', 'Please specify a valid link.', (value) => checkValidLink(value ?? '')),\n children: yup.array().of(textNodeValidator).required(),\n});\n\n// TODO: remove any with a correct Type\nconst inlineNodeValidator: any = yup.lazy((value: { type: string }) => {\n switch (value.type) {\n case 'text':\n return textNodeValidator;\n case 'link':\n return linkNodeValidator;\n default:\n return yup.mixed().test('invalid-type', 'Inline node must be Text or Link', () => {\n return false;\n });\n }\n});\n\nconst paragraphNodeValidator = yup.object().shape({\n type: yup.string().equals(['paragraph']).required(),\n children: yup\n .array()\n .of(inlineNodeValidator)\n .min(1, 'Paragraph node children must have at least one Text or Link node')\n .required(),\n});\n\nconst headingNodeValidator = yup.object().shape({\n type: yup.string().equals(['heading']).required(),\n level: yup.number().oneOf([1, 2, 3, 4, 5, 6]).required(),\n children: yup\n .array()\n .of(inlineNodeValidator)\n .min(1, 'Heading node children must have at least one Text or Link node')\n .required(),\n});\n\nconst quoteNodeValidator = yup.object().shape({\n type: yup.string().equals(['quote']).required(),\n children: yup\n .array()\n .of(inlineNodeValidator)\n .min(1, 'Quote node children must have at least one Text or Link node')\n .required(),\n});\n\nconst codeBlockValidator = yup.object().shape({\n type: yup.string().equals(['code']).required(),\n language: yup.string().nullable(),\n children: yup\n .array()\n .of(textNodeValidator)\n .min(1, 'Quote node children must have at least one Text or Link node')\n .required(),\n});\n\nconst listItemNode = yup.object().shape({\n type: yup.string().equals(['list-item']).required(),\n children: yup.array().of(inlineNodeValidator).required(),\n});\n\n// Allow children to be either a listItemNode or a listNode itself\n// @ts-expect-error - listChildrenValidator needs a type\nconst listChildrenValidator = yup.lazy((value: { type: string }) => {\n switch (value.type) {\n case 'list':\n return listNodeValidator;\n case 'list-item':\n return listItemNode;\n default:\n return yup.mixed().test('invalid-type', 'Inline node must be list-item or list', () => {\n return false;\n });\n }\n});\n\n// @ts-expect-error - listNodeValidator needs a type\nconst listNodeValidator = yup.object().shape({\n type: yup.string().equals(['list']).required(),\n format: yup.string().equals(['ordered', 'unordered']).required(),\n children: yup\n .array()\n .of(listChildrenValidator)\n .min(1, 'List node children must have at least one ListItem or ListNode')\n .required(),\n});\n\nconst imageNodeValidator = yup.object().shape({\n type: yup.string().equals(['image']).required(),\n image: yup.object().shape({\n name: yup.string().required(),\n alternativeText: yup.string().nullable(),\n url: yup.string().required(),\n caption: yup.string().nullable(),\n width: yup.number().required(),\n height: yup.number().required(),\n formats: yup.object().nullable(),\n hash: yup.string().required(),\n ext: yup.string().required(),\n mime: yup.string().required(),\n size: yup.number().required(),\n previewUrl: yup.string().nullable(),\n provider: yup.string().required(),\n provider_metadata: yup.mixed().nullable(),\n createdAt: yup.string().required(),\n updatedAt: yup.string().required(),\n }),\n children: yup.array().of(inlineNodeValidator).required(),\n});\n\n// TODO: remove the any and replace with a correct Type\nconst blockNodeValidator: any = yup.lazy((value: { type: string }) => {\n switch (value.type) {\n case 'paragraph':\n return paragraphNodeValidator;\n case 'heading':\n return headingNodeValidator;\n case 'quote':\n return quoteNodeValidator;\n case 'list':\n return listNodeValidator;\n case 'image':\n return imageNodeValidator;\n case 'code':\n return codeBlockValidator;\n default:\n return yup.mixed().test('invalid-type', 'Block node is of invalid type', () => {\n return false;\n });\n }\n});\n\nconst blocksValidatorSchema = yup.array().of(blockNodeValidator);\n\nexport const blocksValidator = () => blocksValidatorSchema;\n"],"names":["textNodeValidator","yup","object","shape","type","string","equals","required","text","test","bold","boolean","italic","underline","strikethrough","code","checkValidLink","link","URL","startsWith","linkNodeValidator","url","value","children","array","of","inlineNodeValidator","lazy","mixed","paragraphNodeValidator","min","headingNodeValidator","level","number","oneOf","quoteNodeValidator","codeBlockValidator","language","nullable","listItemNode","listChildrenValidator","listNodeValidator","format","imageNodeValidator","image","name","alternativeText","caption","width","height","formats","hash","ext","mime","size","previewUrl","provider","provider_metadata","createdAt","updatedAt","blockNodeValidator","blocksValidatorSchema","blocksValidator"],"mappings":"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"}
@@ -8,13 +8,31 @@ var validators = require('./validators.js');
8
8
 
9
9
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
10
10
 
11
+ function _interopNamespace(e) {
12
+ if (e && e.__esModule) return e;
13
+ var n = Object.create(null);
14
+ if (e) {
15
+ Object.keys(e).forEach(function (k) {
16
+ if (k !== 'default') {
17
+ var d = Object.getOwnPropertyDescriptor(e, k);
18
+ Object.defineProperty(n, k, d.get ? d : {
19
+ enumerable: true,
20
+ get: function () { return e[k]; }
21
+ });
22
+ }
23
+ });
24
+ }
25
+ n.default = e;
26
+ return Object.freeze(n);
27
+ }
28
+
11
29
  var jsonLogic__default = /*#__PURE__*/_interopDefault(jsonLogic);
12
- var strapiUtils__default = /*#__PURE__*/_interopDefault(strapiUtils);
30
+ var strapiUtils__namespace = /*#__PURE__*/_interopNamespace(strapiUtils);
13
31
 
14
- const { yup, validateYupSchema } = strapiUtils__default.default;
15
- const { isMediaAttribute, isScalarAttribute, getWritableAttributes } = strapiUtils__default.default.contentTypes;
16
- const { isAnyToOne } = strapiUtils__default.default.relations;
17
- const { ValidationError } = strapiUtils__default.default.errors;
32
+ const { yup, validateYupSchema } = strapiUtils__namespace;
33
+ const { isMediaAttribute, isScalarAttribute, getWritableAttributes } = strapiUtils__namespace.contentTypes;
34
+ const { isAnyToOne } = strapiUtils__namespace.relations;
35
+ const { ValidationError } = strapiUtils__namespace.errors;
18
36
  const isInteger = (value)=>Number.isInteger(value);
19
37
  const addMinMax = (validator, { attr, updatedAttribute })=>{
20
38
  let nextValidator = validator;