@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.
- package/dist/Strapi.d.ts.map +1 -1
- package/dist/Strapi.js +12 -6
- package/dist/Strapi.js.map +1 -1
- package/dist/Strapi.mjs +12 -6
- package/dist/Strapi.mjs.map +1 -1
- package/dist/compile.js +1 -1
- package/dist/compile.js.map +1 -1
- package/dist/compile.mjs +1 -1
- package/dist/compile.mjs.map +1 -1
- package/dist/configuration/urls.js +2 -2
- package/dist/configuration/urls.js.map +1 -1
- package/dist/configuration/urls.mjs +2 -2
- package/dist/configuration/urls.mjs.map +1 -1
- package/dist/ee/index.js +2 -2
- package/dist/ee/index.js.map +1 -1
- package/dist/ee/index.mjs +2 -2
- package/dist/ee/index.mjs.map +1 -1
- package/dist/index.d.ts +0 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/loaders/apis.d.ts.map +1 -1
- package/dist/loaders/apis.js +3 -1
- package/dist/loaders/apis.js.map +1 -1
- package/dist/loaders/apis.mjs +3 -1
- package/dist/loaders/apis.mjs.map +1 -1
- package/dist/loaders/plugins/get-enabled-plugins.js +1 -1
- package/dist/loaders/plugins/get-enabled-plugins.js.map +1 -1
- package/dist/loaders/plugins/get-enabled-plugins.mjs +1 -1
- package/dist/loaders/plugins/get-enabled-plugins.mjs.map +1 -1
- package/dist/loaders/plugins/index.js +2 -2
- package/dist/loaders/plugins/index.js.map +1 -1
- package/dist/loaders/plugins/index.mjs +2 -2
- package/dist/loaders/plugins/index.mjs.map +1 -1
- package/dist/migrations/database/5.0.0-discard-drafts.js +9 -9
- package/dist/migrations/database/5.0.0-discard-drafts.js.map +1 -1
- package/dist/migrations/database/5.0.0-discard-drafts.mjs +9 -9
- package/dist/migrations/database/5.0.0-discard-drafts.mjs.map +1 -1
- package/dist/package.json.js +14 -14
- package/dist/package.json.mjs +14 -14
- package/dist/services/content-api/index.js +1 -1
- package/dist/services/content-api/index.js.map +1 -1
- package/dist/services/content-api/index.mjs +1 -1
- package/dist/services/content-api/index.mjs.map +1 -1
- package/dist/services/content-api/permissions/engine.d.ts +3 -3
- package/dist/services/content-api/permissions/engine.d.ts.map +1 -1
- package/dist/services/content-api/permissions/engine.js +1 -5
- package/dist/services/content-api/permissions/engine.js.map +1 -1
- package/dist/services/content-api/permissions/engine.mjs +2 -2
- package/dist/services/content-api/permissions/engine.mjs.map +1 -1
- package/dist/services/core-store.js +1 -1
- package/dist/services/core-store.js.map +1 -1
- package/dist/services/core-store.mjs +1 -1
- package/dist/services/core-store.mjs.map +1 -1
- package/dist/services/document-service/repository.js +2 -2
- package/dist/services/document-service/repository.js.map +1 -1
- package/dist/services/document-service/repository.mjs +2 -2
- package/dist/services/document-service/repository.mjs.map +1 -1
- package/dist/services/document-service/utils/clean-component-join-table.js +2 -2
- package/dist/services/document-service/utils/clean-component-join-table.js.map +1 -1
- package/dist/services/document-service/utils/clean-component-join-table.mjs +2 -2
- package/dist/services/document-service/utils/clean-component-join-table.mjs.map +1 -1
- package/dist/services/document-service/utils/clone-relations.js +1 -1
- package/dist/services/document-service/utils/clone-relations.js.map +1 -1
- package/dist/services/document-service/utils/clone-relations.mjs +1 -1
- package/dist/services/document-service/utils/clone-relations.mjs.map +1 -1
- package/dist/services/entity-validator/blocks-validator.js +1 -1
- package/dist/services/entity-validator/blocks-validator.js.map +1 -1
- package/dist/services/entity-validator/blocks-validator.mjs +1 -1
- package/dist/services/entity-validator/blocks-validator.mjs.map +1 -1
- package/dist/services/entity-validator/index.js +23 -5
- package/dist/services/entity-validator/index.js.map +1 -1
- package/dist/services/entity-validator/index.mjs +1 -1
- package/dist/services/entity-validator/index.mjs.map +1 -1
- package/dist/services/metrics/sender.js +1 -1
- package/dist/services/metrics/sender.js.map +1 -1
- package/dist/services/metrics/sender.mjs +1 -1
- package/dist/services/metrics/sender.mjs.map +1 -1
- package/dist/services/server/koa-methods.d.ts +6 -0
- package/dist/services/server/koa-methods.d.ts.map +1 -1
- package/dist/services/server/koa-methods.js.map +1 -1
- package/dist/services/server/koa-methods.mjs.map +1 -1
- package/dist/services/server/middleware.js +1 -1
- package/dist/services/server/middleware.js.map +1 -1
- package/dist/services/server/middleware.mjs +1 -1
- package/dist/services/server/middleware.mjs.map +1 -1
- package/dist/services/server/register-middlewares.js +1 -1
- package/dist/services/server/register-middlewares.js.map +1 -1
- package/dist/services/server/register-middlewares.mjs +1 -1
- package/dist/services/server/register-middlewares.mjs.map +1 -1
- package/dist/services/server/routing.js +1 -1
- package/dist/services/server/routing.js.map +1 -1
- package/dist/services/server/routing.mjs +1 -1
- package/dist/services/server/routing.mjs.map +1 -1
- package/dist/services/session-manager.d.ts.map +1 -1
- package/dist/services/session-manager.js +5 -5
- package/dist/services/session-manager.js.map +1 -1
- package/dist/services/session-manager.mjs +5 -5
- package/dist/services/session-manager.mjs.map +1 -1
- 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
|
|
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
|
|
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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"}
|
|
@@ -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":"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"}
|
|
@@ -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
|
|
30
|
+
var strapiUtils__namespace = /*#__PURE__*/_interopNamespace(strapiUtils);
|
|
13
31
|
|
|
14
|
-
const { yup, validateYupSchema } =
|
|
15
|
-
const { isMediaAttribute, isScalarAttribute, getWritableAttributes } =
|
|
16
|
-
const { isAnyToOne } =
|
|
17
|
-
const { ValidationError } =
|
|
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;
|