@strapi/core 5.45.0 → 5.46.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/dist/core-api/routes/validation/attributes.d.ts +4 -4
  2. package/dist/core-api/routes/validation/attributes.d.ts.map +1 -1
  3. package/dist/core-api/routes/validation/attributes.js +6 -6
  4. package/dist/core-api/routes/validation/attributes.js.map +1 -1
  5. package/dist/core-api/routes/validation/attributes.mjs +6 -6
  6. package/dist/core-api/routes/validation/attributes.mjs.map +1 -1
  7. package/dist/core-api/routes/validation/component.js +1 -1
  8. package/dist/core-api/routes/validation/component.js.map +1 -1
  9. package/dist/core-api/routes/validation/component.mjs +1 -1
  10. package/dist/core-api/routes/validation/component.mjs.map +1 -1
  11. package/dist/core-api/routes/validation/content-type.js +2 -2
  12. package/dist/core-api/routes/validation/content-type.js.map +1 -1
  13. package/dist/core-api/routes/validation/content-type.mjs +2 -2
  14. package/dist/core-api/routes/validation/content-type.mjs.map +1 -1
  15. package/dist/core-api/routes/validation/mappers.d.ts +5 -5
  16. package/dist/core-api/routes/validation/mappers.d.ts.map +1 -1
  17. package/dist/core-api/routes/validation/mappers.js +13 -21
  18. package/dist/core-api/routes/validation/mappers.js.map +1 -1
  19. package/dist/core-api/routes/validation/mappers.mjs +13 -21
  20. package/dist/core-api/routes/validation/mappers.mjs.map +1 -1
  21. package/dist/core-api/routes/validation/utils.d.ts +3 -3
  22. package/dist/core-api/routes/validation/utils.d.ts.map +1 -1
  23. package/dist/core-api/routes/validation/utils.js +4 -7
  24. package/dist/core-api/routes/validation/utils.js.map +1 -1
  25. package/dist/core-api/routes/validation/utils.mjs +4 -7
  26. package/dist/core-api/routes/validation/utils.mjs.map +1 -1
  27. package/dist/package.json.js +12 -12
  28. package/dist/package.json.mjs +12 -12
  29. package/dist/services/content-source-maps.d.ts.map +1 -1
  30. package/dist/services/content-source-maps.js +12 -4
  31. package/dist/services/content-source-maps.js.map +1 -1
  32. package/dist/services/content-source-maps.mjs +12 -4
  33. package/dist/services/content-source-maps.mjs.map +1 -1
  34. package/dist/services/document-service/transform/relations/extract/data-ids.d.ts.map +1 -1
  35. package/dist/services/document-service/transform/relations/extract/data-ids.js +4 -1
  36. package/dist/services/document-service/transform/relations/extract/data-ids.js.map +1 -1
  37. package/dist/services/document-service/transform/relations/extract/data-ids.mjs +4 -1
  38. package/dist/services/document-service/transform/relations/extract/data-ids.mjs.map +1 -1
  39. package/dist/services/document-service/transform/relations/transform/data-ids.d.ts.map +1 -1
  40. package/dist/services/document-service/transform/relations/transform/data-ids.js +4 -1
  41. package/dist/services/document-service/transform/relations/transform/data-ids.js.map +1 -1
  42. package/dist/services/document-service/transform/relations/transform/data-ids.mjs +4 -1
  43. package/dist/services/document-service/transform/relations/transform/data-ids.mjs.map +1 -1
  44. package/dist/services/document-service/transform/relations/utils/xto-one.d.ts +8 -0
  45. package/dist/services/document-service/transform/relations/utils/xto-one.d.ts.map +1 -0
  46. package/dist/services/document-service/transform/relations/utils/xto-one.js +41 -0
  47. package/dist/services/document-service/transform/relations/utils/xto-one.js.map +1 -0
  48. package/dist/services/document-service/transform/relations/utils/xto-one.mjs +39 -0
  49. package/dist/services/document-service/transform/relations/utils/xto-one.mjs.map +1 -0
  50. package/package.json +12 -12
@@ -36,7 +36,7 @@ var z__namespace = /*#__PURE__*/_interopNamespaceDefault(z);
36
36
  * ```typescript
37
37
  * safeGlobalRegistrySet("mySchema", z.object({ name: z.string() }));
38
38
  * ```
39
- */ const safeGlobalRegistrySet = (id, schema)=>{
39
+ */ const safeGlobalRegistrySet = (strapi, id, schema)=>{
40
40
  try {
41
41
  const { _idmap: idMap } = z__namespace.globalRegistry;
42
42
  const transformedId = strapiUtils.transformUidToValidOpenApiName(id);
@@ -45,7 +45,6 @@ var z__namespace = /*#__PURE__*/_interopNamespaceDefault(z);
45
45
  // Remove existing schema to prevent conflicts
46
46
  idMap.delete(transformedId);
47
47
  }
48
- // Register the new schema with the transformed ID
49
48
  strapi.log.debug(`${isReplacing ? 'Replacing' : 'Registering'} schema ${transformedId} in global registry`);
50
49
  z__namespace.globalRegistry.add(schema, {
51
50
  id: transformedId
@@ -82,7 +81,7 @@ var z__namespace = /*#__PURE__*/_interopNamespaceDefault(z);
82
81
  * })
83
82
  * );
84
83
  * ```
85
- */ const safeSchemaCreation = (id, callback)=>{
84
+ */ const safeSchemaCreation = (strapi, id, callback)=>{
86
85
  try {
87
86
  const { _idmap: idMap } = z__namespace.globalRegistry;
88
87
  const transformedId = strapiUtils.transformUidToValidOpenApiName(id);
@@ -96,20 +95,18 @@ var z__namespace = /*#__PURE__*/_interopNamespaceDefault(z);
96
95
  // Determine if this is a built-in schema or user content
97
96
  const isBuiltInSchema = id.startsWith('plugin::') || id.startsWith('admin');
98
97
  if (isBuiltInSchema) {
99
- // Built-in schemas keep at debug level to avoid clutter
100
98
  strapi.log.debug(`Initializing validation schema for ${transformedId}`);
101
99
  } else {
102
- // User content
103
100
  const schemaName = transformedId.replace('Document', '').replace('Entry', '').replace(/([A-Z])/g, ' $1').trim();
104
101
  strapi.log.debug(`📝 Generating validation schema for "${schemaName}"`);
105
102
  }
106
103
  // Temporary any placeholder before replacing with the actual schema type
107
104
  // Used to prevent infinite loops in cyclical data structures
108
- safeGlobalRegistrySet(id, z__namespace.any());
105
+ safeGlobalRegistrySet(strapi, id, z__namespace.any());
109
106
  // Generate the actual schema using the callback
110
107
  const schema = callback();
111
108
  // Replace the placeholder with the real schema
112
- safeGlobalRegistrySet(id, schema);
109
+ safeGlobalRegistrySet(strapi, id, schema);
113
110
  // Show completion for user content only
114
111
  if (!isBuiltInSchema) {
115
112
  const fieldCount = Object.keys(schema?._def?.shape || {}).length || 0;
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sources":["../../../../src/core-api/routes/validation/utils.ts"],"sourcesContent":["import { transformUidToValidOpenApiName } from '@strapi/utils';\nimport type { Internal } from '@strapi/types';\nimport * as z from 'zod/v4';\n\n// Schema generation happens on-demand when schemas don't exist in the registry\n\n/**\n * Safely adds or updates a schema in Zod's global registry.\n *\n * If a schema with the given `id` already exists, it will be removed before adding the new one.\n *\n * This is useful for hot-reloading or preventing issues with cyclical dependencies.\n *\n * @param id - The unique identifier for the schema in the global registry.\n * @param schema - The Zod schema to register.\n * @example\n * ```typescript\n * safeGlobalRegistrySet(\"mySchema\", z.object({ name: z.string() }));\n * ```\n */\nexport const safeGlobalRegistrySet = (id: Internal.UID.Schema, schema: z.ZodType) => {\n try {\n const { _idmap: idMap } = z.globalRegistry;\n\n const transformedId = transformUidToValidOpenApiName(id);\n\n const isReplacing = idMap.has(transformedId);\n\n if (isReplacing) {\n // Remove existing schema to prevent conflicts\n idMap.delete(transformedId);\n }\n\n // Register the new schema with the transformed ID\n strapi.log.debug(\n `${isReplacing ? 'Replacing' : 'Registering'} schema ${transformedId} in global registry`\n );\n z.globalRegistry.add(schema, { id: transformedId });\n } catch (error) {\n strapi.log.error(\n `Schema registration failed: Failed to register schema ${id} in global registry`\n );\n\n throw error;\n }\n};\n\n/**\n * Safely creates and registers a Zod schema in the global registry, particularly useful for handling cyclical data structures.\n *\n * If a schema with the given `id` already exists in the global registry, it returns the existing schema.\n *\n * Otherwise, it registers a temporary `z.any()` schema, calls the provided `callback` to create the actual schema,\n * and then replaces the temporary schema with the actual one in the registry.\n *\n * This prevents infinite loops in cases of cyclical dependencies.\n *\n * @param id - The unique identifier for the schema in the global registry.\n * @param callback - A function that returns the Zod schema to be created and registered.\n * @returns The created or retrieved Zod schema.\n * @example\n * ```typescript\n * const CategorySchema = safeSchemaCreation(\"Category\", () =>\n * z.object({\n * name: z.string(),\n * products: z.array(safeSchemaCreation(\"Product\", () =>\n * z.object({\n * name: z.string(),\n * category: z.lazy(() => CategorySchema) // Cyclical reference\n * })\n * ))\n * })\n * );\n * ```\n */\nexport const safeSchemaCreation = (id: Internal.UID.Schema, callback: () => z.ZodType) => {\n try {\n const { _idmap: idMap } = z.globalRegistry;\n\n const transformedId = transformUidToValidOpenApiName(id);\n\n // Return existing schema if already registered\n const mapItem = idMap.get(transformedId);\n if (mapItem) {\n // Schema already exists, return it silently\n return mapItem;\n }\n\n strapi.log.debug(`Schema ${transformedId} not found in registry, generating new schema`);\n\n // Determine if this is a built-in schema or user content\n const isBuiltInSchema = id.startsWith('plugin::') || id.startsWith('admin');\n\n if (isBuiltInSchema) {\n // Built-in schemas keep at debug level to avoid clutter\n strapi.log.debug(`Initializing validation schema for ${transformedId}`);\n } else {\n // User content\n const schemaName = transformedId\n .replace('Document', '')\n .replace('Entry', '')\n .replace(/([A-Z])/g, ' $1')\n .trim();\n strapi.log.debug(`📝 Generating validation schema for \"${schemaName}\"`);\n }\n\n // Temporary any placeholder before replacing with the actual schema type\n // Used to prevent infinite loops in cyclical data structures\n safeGlobalRegistrySet(id, z.any());\n\n // Generate the actual schema using the callback\n const schema = callback();\n\n // Replace the placeholder with the real schema\n safeGlobalRegistrySet(id, schema);\n\n // Show completion for user content only\n if (!isBuiltInSchema) {\n const fieldCount = Object.keys((schema as any)?._def?.shape || {}).length || 0;\n const schemaName = transformedId\n .replace('Document', '')\n .replace('Entry', '')\n .replace(/([A-Z])/g, ' $1')\n .trim();\n strapi.log.debug(` ✅ \"${schemaName}\" schema created with ${fieldCount} fields`);\n }\n\n return schema;\n } catch (error) {\n strapi.log.error(`Schema creation failed: Failed to create schema ${id}`);\n\n throw error;\n }\n};\n"],"names":["safeGlobalRegistrySet","id","schema","_idmap","idMap","z","globalRegistry","transformedId","transformUidToValidOpenApiName","isReplacing","has","delete","strapi","log","debug","add","error","safeSchemaCreation","callback","mapItem","get","isBuiltInSchema","startsWith","schemaName","replace","trim","any","fieldCount","Object","keys","_def","shape","length"],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","sources":["../../../../src/core-api/routes/validation/utils.ts"],"sourcesContent":["import { transformUidToValidOpenApiName } from '@strapi/utils';\nimport type { Core, Internal } from '@strapi/types';\nimport * as z from 'zod/v4';\n\n// Schema generation happens on-demand when schemas don't exist in the registry\n\n/**\n * Safely adds or updates a schema in Zod's global registry.\n *\n * If a schema with the given `id` already exists, it will be removed before adding the new one.\n *\n * This is useful for hot-reloading or preventing issues with cyclical dependencies.\n *\n * @param id - The unique identifier for the schema in the global registry.\n * @param schema - The Zod schema to register.\n * @example\n * ```typescript\n * safeGlobalRegistrySet(\"mySchema\", z.object({ name: z.string() }));\n * ```\n */\nexport const safeGlobalRegistrySet = (\n strapi: Core.Strapi,\n id: Internal.UID.Schema,\n schema: z.ZodType\n) => {\n try {\n const { _idmap: idMap } = z.globalRegistry;\n\n const transformedId = transformUidToValidOpenApiName(id);\n\n const isReplacing = idMap.has(transformedId);\n\n if (isReplacing) {\n // Remove existing schema to prevent conflicts\n idMap.delete(transformedId);\n }\n\n strapi.log.debug(\n `${isReplacing ? 'Replacing' : 'Registering'} schema ${transformedId} in global registry`\n );\n z.globalRegistry.add(schema, { id: transformedId });\n } catch (error) {\n strapi.log.error(\n `Schema registration failed: Failed to register schema ${id} in global registry`\n );\n\n throw error;\n }\n};\n\n/**\n * Safely creates and registers a Zod schema in the global registry, particularly useful for handling cyclical data structures.\n *\n * If a schema with the given `id` already exists in the global registry, it returns the existing schema.\n *\n * Otherwise, it registers a temporary `z.any()` schema, calls the provided `callback` to create the actual schema,\n * and then replaces the temporary schema with the actual one in the registry.\n *\n * This prevents infinite loops in cases of cyclical dependencies.\n *\n * @param id - The unique identifier for the schema in the global registry.\n * @param callback - A function that returns the Zod schema to be created and registered.\n * @returns The created or retrieved Zod schema.\n * @example\n * ```typescript\n * const CategorySchema = safeSchemaCreation(\"Category\", () =>\n * z.object({\n * name: z.string(),\n * products: z.array(safeSchemaCreation(\"Product\", () =>\n * z.object({\n * name: z.string(),\n * category: z.lazy(() => CategorySchema) // Cyclical reference\n * })\n * ))\n * })\n * );\n * ```\n */\nexport const safeSchemaCreation = (\n strapi: Core.Strapi,\n id: Internal.UID.Schema,\n callback: () => z.ZodType\n) => {\n try {\n const { _idmap: idMap } = z.globalRegistry;\n\n const transformedId = transformUidToValidOpenApiName(id);\n\n // Return existing schema if already registered\n const mapItem = idMap.get(transformedId);\n if (mapItem) {\n // Schema already exists, return it silently\n return mapItem;\n }\n\n strapi.log.debug(`Schema ${transformedId} not found in registry, generating new schema`);\n\n // Determine if this is a built-in schema or user content\n const isBuiltInSchema = id.startsWith('plugin::') || id.startsWith('admin');\n\n if (isBuiltInSchema) {\n strapi.log.debug(`Initializing validation schema for ${transformedId}`);\n } else {\n const schemaName = transformedId\n .replace('Document', '')\n .replace('Entry', '')\n .replace(/([A-Z])/g, ' $1')\n .trim();\n strapi.log.debug(`📝 Generating validation schema for \"${schemaName}\"`);\n }\n\n // Temporary any placeholder before replacing with the actual schema type\n // Used to prevent infinite loops in cyclical data structures\n safeGlobalRegistrySet(strapi, id, z.any());\n\n // Generate the actual schema using the callback\n const schema = callback();\n\n // Replace the placeholder with the real schema\n safeGlobalRegistrySet(strapi, id, schema);\n\n // Show completion for user content only\n if (!isBuiltInSchema) {\n const fieldCount = Object.keys((schema as any)?._def?.shape || {}).length || 0;\n const schemaName = transformedId\n .replace('Document', '')\n .replace('Entry', '')\n .replace(/([A-Z])/g, ' $1')\n .trim();\n strapi.log.debug(` ✅ \"${schemaName}\" schema created with ${fieldCount} fields`);\n }\n\n return schema;\n } catch (error) {\n strapi.log.error(`Schema creation failed: Failed to create schema ${id}`);\n\n throw error;\n }\n};\n"],"names":["safeGlobalRegistrySet","strapi","id","schema","_idmap","idMap","z","globalRegistry","transformedId","transformUidToValidOpenApiName","isReplacing","has","delete","log","debug","add","error","safeSchemaCreation","callback","mapItem","get","isBuiltInSchema","startsWith","schemaName","replace","trim","any","fieldCount","Object","keys","_def","shape","length"],"mappings":"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"}
@@ -15,7 +15,7 @@ import * as z from 'zod/v4';
15
15
  * ```typescript
16
16
  * safeGlobalRegistrySet("mySchema", z.object({ name: z.string() }));
17
17
  * ```
18
- */ const safeGlobalRegistrySet = (id, schema)=>{
18
+ */ const safeGlobalRegistrySet = (strapi, id, schema)=>{
19
19
  try {
20
20
  const { _idmap: idMap } = z.globalRegistry;
21
21
  const transformedId = transformUidToValidOpenApiName(id);
@@ -24,7 +24,6 @@ import * as z from 'zod/v4';
24
24
  // Remove existing schema to prevent conflicts
25
25
  idMap.delete(transformedId);
26
26
  }
27
- // Register the new schema with the transformed ID
28
27
  strapi.log.debug(`${isReplacing ? 'Replacing' : 'Registering'} schema ${transformedId} in global registry`);
29
28
  z.globalRegistry.add(schema, {
30
29
  id: transformedId
@@ -61,7 +60,7 @@ import * as z from 'zod/v4';
61
60
  * })
62
61
  * );
63
62
  * ```
64
- */ const safeSchemaCreation = (id, callback)=>{
63
+ */ const safeSchemaCreation = (strapi, id, callback)=>{
65
64
  try {
66
65
  const { _idmap: idMap } = z.globalRegistry;
67
66
  const transformedId = transformUidToValidOpenApiName(id);
@@ -75,20 +74,18 @@ import * as z from 'zod/v4';
75
74
  // Determine if this is a built-in schema or user content
76
75
  const isBuiltInSchema = id.startsWith('plugin::') || id.startsWith('admin');
77
76
  if (isBuiltInSchema) {
78
- // Built-in schemas keep at debug level to avoid clutter
79
77
  strapi.log.debug(`Initializing validation schema for ${transformedId}`);
80
78
  } else {
81
- // User content
82
79
  const schemaName = transformedId.replace('Document', '').replace('Entry', '').replace(/([A-Z])/g, ' $1').trim();
83
80
  strapi.log.debug(`📝 Generating validation schema for "${schemaName}"`);
84
81
  }
85
82
  // Temporary any placeholder before replacing with the actual schema type
86
83
  // Used to prevent infinite loops in cyclical data structures
87
- safeGlobalRegistrySet(id, z.any());
84
+ safeGlobalRegistrySet(strapi, id, z.any());
88
85
  // Generate the actual schema using the callback
89
86
  const schema = callback();
90
87
  // Replace the placeholder with the real schema
91
- safeGlobalRegistrySet(id, schema);
88
+ safeGlobalRegistrySet(strapi, id, schema);
92
89
  // Show completion for user content only
93
90
  if (!isBuiltInSchema) {
94
91
  const fieldCount = Object.keys(schema?._def?.shape || {}).length || 0;
@@ -1 +1 @@
1
- {"version":3,"file":"utils.mjs","sources":["../../../../src/core-api/routes/validation/utils.ts"],"sourcesContent":["import { transformUidToValidOpenApiName } from '@strapi/utils';\nimport type { Internal } from '@strapi/types';\nimport * as z from 'zod/v4';\n\n// Schema generation happens on-demand when schemas don't exist in the registry\n\n/**\n * Safely adds or updates a schema in Zod's global registry.\n *\n * If a schema with the given `id` already exists, it will be removed before adding the new one.\n *\n * This is useful for hot-reloading or preventing issues with cyclical dependencies.\n *\n * @param id - The unique identifier for the schema in the global registry.\n * @param schema - The Zod schema to register.\n * @example\n * ```typescript\n * safeGlobalRegistrySet(\"mySchema\", z.object({ name: z.string() }));\n * ```\n */\nexport const safeGlobalRegistrySet = (id: Internal.UID.Schema, schema: z.ZodType) => {\n try {\n const { _idmap: idMap } = z.globalRegistry;\n\n const transformedId = transformUidToValidOpenApiName(id);\n\n const isReplacing = idMap.has(transformedId);\n\n if (isReplacing) {\n // Remove existing schema to prevent conflicts\n idMap.delete(transformedId);\n }\n\n // Register the new schema with the transformed ID\n strapi.log.debug(\n `${isReplacing ? 'Replacing' : 'Registering'} schema ${transformedId} in global registry`\n );\n z.globalRegistry.add(schema, { id: transformedId });\n } catch (error) {\n strapi.log.error(\n `Schema registration failed: Failed to register schema ${id} in global registry`\n );\n\n throw error;\n }\n};\n\n/**\n * Safely creates and registers a Zod schema in the global registry, particularly useful for handling cyclical data structures.\n *\n * If a schema with the given `id` already exists in the global registry, it returns the existing schema.\n *\n * Otherwise, it registers a temporary `z.any()` schema, calls the provided `callback` to create the actual schema,\n * and then replaces the temporary schema with the actual one in the registry.\n *\n * This prevents infinite loops in cases of cyclical dependencies.\n *\n * @param id - The unique identifier for the schema in the global registry.\n * @param callback - A function that returns the Zod schema to be created and registered.\n * @returns The created or retrieved Zod schema.\n * @example\n * ```typescript\n * const CategorySchema = safeSchemaCreation(\"Category\", () =>\n * z.object({\n * name: z.string(),\n * products: z.array(safeSchemaCreation(\"Product\", () =>\n * z.object({\n * name: z.string(),\n * category: z.lazy(() => CategorySchema) // Cyclical reference\n * })\n * ))\n * })\n * );\n * ```\n */\nexport const safeSchemaCreation = (id: Internal.UID.Schema, callback: () => z.ZodType) => {\n try {\n const { _idmap: idMap } = z.globalRegistry;\n\n const transformedId = transformUidToValidOpenApiName(id);\n\n // Return existing schema if already registered\n const mapItem = idMap.get(transformedId);\n if (mapItem) {\n // Schema already exists, return it silently\n return mapItem;\n }\n\n strapi.log.debug(`Schema ${transformedId} not found in registry, generating new schema`);\n\n // Determine if this is a built-in schema or user content\n const isBuiltInSchema = id.startsWith('plugin::') || id.startsWith('admin');\n\n if (isBuiltInSchema) {\n // Built-in schemas keep at debug level to avoid clutter\n strapi.log.debug(`Initializing validation schema for ${transformedId}`);\n } else {\n // User content\n const schemaName = transformedId\n .replace('Document', '')\n .replace('Entry', '')\n .replace(/([A-Z])/g, ' $1')\n .trim();\n strapi.log.debug(`📝 Generating validation schema for \"${schemaName}\"`);\n }\n\n // Temporary any placeholder before replacing with the actual schema type\n // Used to prevent infinite loops in cyclical data structures\n safeGlobalRegistrySet(id, z.any());\n\n // Generate the actual schema using the callback\n const schema = callback();\n\n // Replace the placeholder with the real schema\n safeGlobalRegistrySet(id, schema);\n\n // Show completion for user content only\n if (!isBuiltInSchema) {\n const fieldCount = Object.keys((schema as any)?._def?.shape || {}).length || 0;\n const schemaName = transformedId\n .replace('Document', '')\n .replace('Entry', '')\n .replace(/([A-Z])/g, ' $1')\n .trim();\n strapi.log.debug(` ✅ \"${schemaName}\" schema created with ${fieldCount} fields`);\n }\n\n return schema;\n } catch (error) {\n strapi.log.error(`Schema creation failed: Failed to create schema ${id}`);\n\n throw error;\n }\n};\n"],"names":["safeGlobalRegistrySet","id","schema","_idmap","idMap","z","globalRegistry","transformedId","transformUidToValidOpenApiName","isReplacing","has","delete","strapi","log","debug","add","error","safeSchemaCreation","callback","mapItem","get","isBuiltInSchema","startsWith","schemaName","replace","trim","any","fieldCount","Object","keys","_def","shape","length"],"mappings":";;;AAIA;AAEA;;;;;;;;;;;;;AAaC,IACM,MAAMA,qBAAAA,GAAwB,CAACC,EAAAA,EAAyBC,MAAAA,GAAAA;IAC7D,IAAI;AACF,QAAA,MAAM,EAAEC,MAAAA,EAAQC,KAAK,EAAE,GAAGC,EAAEC,cAAc;AAE1C,QAAA,MAAMC,gBAAgBC,8BAAAA,CAA+BP,EAAAA,CAAAA;QAErD,MAAMQ,WAAAA,GAAcL,KAAAA,CAAMM,GAAG,CAACH,aAAAA,CAAAA;AAE9B,QAAA,IAAIE,WAAAA,EAAa;;AAEfL,YAAAA,KAAAA,CAAMO,MAAM,CAACJ,aAAAA,CAAAA;AACf,QAAA;;AAGAK,QAAAA,MAAAA,CAAOC,GAAG,CAACC,KAAK,CACd,CAAA,EAAGL,WAAAA,GAAc,WAAA,GAAc,aAAA,CAAc,QAAQ,EAAEF,aAAAA,CAAc,mBAAmB,CAAC,CAAA;AAE3FF,QAAAA,CAAAA,CAAEC,cAAc,CAACS,GAAG,CAACb,MAAAA,EAAQ;YAAED,EAAAA,EAAIM;AAAc,SAAA,CAAA;AACnD,IAAA,CAAA,CAAE,OAAOS,KAAAA,EAAO;QACdJ,MAAAA,CAAOC,GAAG,CAACG,KAAK,CACd,CAAC,sDAAsD,EAAEf,EAAAA,CAAG,mBAAmB,CAAC,CAAA;QAGlF,MAAMe,KAAAA;AACR,IAAA;AACF;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BC,IACM,MAAMC,kBAAAA,GAAqB,CAAChB,EAAAA,EAAyBiB,QAAAA,GAAAA;IAC1D,IAAI;AACF,QAAA,MAAM,EAAEf,MAAAA,EAAQC,KAAK,EAAE,GAAGC,EAAEC,cAAc;AAE1C,QAAA,MAAMC,gBAAgBC,8BAAAA,CAA+BP,EAAAA,CAAAA;;QAGrD,MAAMkB,OAAAA,GAAUf,KAAAA,CAAMgB,GAAG,CAACb,aAAAA,CAAAA;AAC1B,QAAA,IAAIY,OAAAA,EAAS;;YAEX,OAAOA,OAAAA;AACT,QAAA;QAEAP,MAAAA,CAAOC,GAAG,CAACC,KAAK,CAAC,CAAC,OAAO,EAAEP,aAAAA,CAAc,6CAA6C,CAAC,CAAA;;AAGvF,QAAA,MAAMc,kBAAkBpB,EAAAA,CAAGqB,UAAU,CAAC,UAAA,CAAA,IAAerB,EAAAA,CAAGqB,UAAU,CAAC,OAAA,CAAA;AAEnE,QAAA,IAAID,eAAAA,EAAiB;;AAEnBT,YAAAA,MAAAA,CAAOC,GAAG,CAACC,KAAK,CAAC,CAAC,mCAAmC,EAAEP,aAAAA,CAAAA,CAAe,CAAA;QACxE,CAAA,MAAO;;AAEL,YAAA,MAAMgB,UAAAA,GAAahB,aAAAA,CAChBiB,OAAO,CAAC,YAAY,EAAA,CAAA,CACpBA,OAAO,CAAC,OAAA,EAAS,EAAA,CAAA,CACjBA,OAAO,CAAC,UAAA,EAAY,OACpBC,IAAI,EAAA;YACPb,MAAAA,CAAOC,GAAG,CAACC,KAAK,CAAC,CAAC,qCAAqC,EAAES,UAAAA,CAAW,CAAC,CAAC,CAAA;AACxE,QAAA;;;QAIAvB,qBAAAA,CAAsBC,EAAAA,EAAII,EAAEqB,GAAG,EAAA,CAAA;;AAG/B,QAAA,MAAMxB,MAAAA,GAASgB,QAAAA,EAAAA;;AAGflB,QAAAA,qBAAAA,CAAsBC,EAAAA,EAAIC,MAAAA,CAAAA;;AAG1B,QAAA,IAAI,CAACmB,eAAAA,EAAiB;YACpB,MAAMM,UAAAA,GAAaC,MAAAA,CAAOC,IAAI,CAAE3B,MAAAA,EAAgB4B,IAAAA,EAAMC,KAAAA,IAAS,EAAC,CAAA,CAAGC,MAAM,IAAI,CAAA;AAC7E,YAAA,MAAMT,UAAAA,GAAahB,aAAAA,CAChBiB,OAAO,CAAC,YAAY,EAAA,CAAA,CACpBA,OAAO,CAAC,OAAA,EAAS,EAAA,CAAA,CACjBA,OAAO,CAAC,UAAA,EAAY,OACpBC,IAAI,EAAA;AACPb,YAAAA,MAAAA,CAAOC,GAAG,CAACC,KAAK,CAAC,CAAC,MAAM,EAAES,UAAAA,CAAW,sBAAsB,EAAEI,UAAAA,CAAW,OAAO,CAAC,CAAA;AAClF,QAAA;QAEA,OAAOzB,MAAAA;AACT,IAAA,CAAA,CAAE,OAAOc,KAAAA,EAAO;AACdJ,QAAAA,MAAAA,CAAOC,GAAG,CAACG,KAAK,CAAC,CAAC,gDAAgD,EAAEf,EAAAA,CAAAA,CAAI,CAAA;QAExE,MAAMe,KAAAA;AACR,IAAA;AACF;;;;"}
1
+ {"version":3,"file":"utils.mjs","sources":["../../../../src/core-api/routes/validation/utils.ts"],"sourcesContent":["import { transformUidToValidOpenApiName } from '@strapi/utils';\nimport type { Core, Internal } from '@strapi/types';\nimport * as z from 'zod/v4';\n\n// Schema generation happens on-demand when schemas don't exist in the registry\n\n/**\n * Safely adds or updates a schema in Zod's global registry.\n *\n * If a schema with the given `id` already exists, it will be removed before adding the new one.\n *\n * This is useful for hot-reloading or preventing issues with cyclical dependencies.\n *\n * @param id - The unique identifier for the schema in the global registry.\n * @param schema - The Zod schema to register.\n * @example\n * ```typescript\n * safeGlobalRegistrySet(\"mySchema\", z.object({ name: z.string() }));\n * ```\n */\nexport const safeGlobalRegistrySet = (\n strapi: Core.Strapi,\n id: Internal.UID.Schema,\n schema: z.ZodType\n) => {\n try {\n const { _idmap: idMap } = z.globalRegistry;\n\n const transformedId = transformUidToValidOpenApiName(id);\n\n const isReplacing = idMap.has(transformedId);\n\n if (isReplacing) {\n // Remove existing schema to prevent conflicts\n idMap.delete(transformedId);\n }\n\n strapi.log.debug(\n `${isReplacing ? 'Replacing' : 'Registering'} schema ${transformedId} in global registry`\n );\n z.globalRegistry.add(schema, { id: transformedId });\n } catch (error) {\n strapi.log.error(\n `Schema registration failed: Failed to register schema ${id} in global registry`\n );\n\n throw error;\n }\n};\n\n/**\n * Safely creates and registers a Zod schema in the global registry, particularly useful for handling cyclical data structures.\n *\n * If a schema with the given `id` already exists in the global registry, it returns the existing schema.\n *\n * Otherwise, it registers a temporary `z.any()` schema, calls the provided `callback` to create the actual schema,\n * and then replaces the temporary schema with the actual one in the registry.\n *\n * This prevents infinite loops in cases of cyclical dependencies.\n *\n * @param id - The unique identifier for the schema in the global registry.\n * @param callback - A function that returns the Zod schema to be created and registered.\n * @returns The created or retrieved Zod schema.\n * @example\n * ```typescript\n * const CategorySchema = safeSchemaCreation(\"Category\", () =>\n * z.object({\n * name: z.string(),\n * products: z.array(safeSchemaCreation(\"Product\", () =>\n * z.object({\n * name: z.string(),\n * category: z.lazy(() => CategorySchema) // Cyclical reference\n * })\n * ))\n * })\n * );\n * ```\n */\nexport const safeSchemaCreation = (\n strapi: Core.Strapi,\n id: Internal.UID.Schema,\n callback: () => z.ZodType\n) => {\n try {\n const { _idmap: idMap } = z.globalRegistry;\n\n const transformedId = transformUidToValidOpenApiName(id);\n\n // Return existing schema if already registered\n const mapItem = idMap.get(transformedId);\n if (mapItem) {\n // Schema already exists, return it silently\n return mapItem;\n }\n\n strapi.log.debug(`Schema ${transformedId} not found in registry, generating new schema`);\n\n // Determine if this is a built-in schema or user content\n const isBuiltInSchema = id.startsWith('plugin::') || id.startsWith('admin');\n\n if (isBuiltInSchema) {\n strapi.log.debug(`Initializing validation schema for ${transformedId}`);\n } else {\n const schemaName = transformedId\n .replace('Document', '')\n .replace('Entry', '')\n .replace(/([A-Z])/g, ' $1')\n .trim();\n strapi.log.debug(`📝 Generating validation schema for \"${schemaName}\"`);\n }\n\n // Temporary any placeholder before replacing with the actual schema type\n // Used to prevent infinite loops in cyclical data structures\n safeGlobalRegistrySet(strapi, id, z.any());\n\n // Generate the actual schema using the callback\n const schema = callback();\n\n // Replace the placeholder with the real schema\n safeGlobalRegistrySet(strapi, id, schema);\n\n // Show completion for user content only\n if (!isBuiltInSchema) {\n const fieldCount = Object.keys((schema as any)?._def?.shape || {}).length || 0;\n const schemaName = transformedId\n .replace('Document', '')\n .replace('Entry', '')\n .replace(/([A-Z])/g, ' $1')\n .trim();\n strapi.log.debug(` ✅ \"${schemaName}\" schema created with ${fieldCount} fields`);\n }\n\n return schema;\n } catch (error) {\n strapi.log.error(`Schema creation failed: Failed to create schema ${id}`);\n\n throw error;\n }\n};\n"],"names":["safeGlobalRegistrySet","strapi","id","schema","_idmap","idMap","z","globalRegistry","transformedId","transformUidToValidOpenApiName","isReplacing","has","delete","log","debug","add","error","safeSchemaCreation","callback","mapItem","get","isBuiltInSchema","startsWith","schemaName","replace","trim","any","fieldCount","Object","keys","_def","shape","length"],"mappings":"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"}
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var name = "@strapi/core";
6
- var version = "5.45.0";
6
+ var version = "5.46.0";
7
7
  var description = "Core of Strapi";
8
8
  var homepage = "https://strapi.io";
9
9
  var bugs = {
@@ -62,14 +62,14 @@ var dependencies = {
62
62
  "@koa/cors": "5.0.0",
63
63
  "@koa/router": "12.0.2",
64
64
  "@paralleldrive/cuid2": "2.2.2",
65
- "@strapi/admin": "5.45.0",
66
- "@strapi/database": "5.45.0",
67
- "@strapi/generators": "5.45.0",
68
- "@strapi/logger": "5.45.0",
69
- "@strapi/permissions": "5.45.0",
70
- "@strapi/types": "5.45.0",
71
- "@strapi/typescript-utils": "5.45.0",
72
- "@strapi/utils": "5.45.0",
65
+ "@strapi/admin": "5.46.0",
66
+ "@strapi/database": "5.46.0",
67
+ "@strapi/generators": "5.46.0",
68
+ "@strapi/logger": "5.46.0",
69
+ "@strapi/permissions": "5.46.0",
70
+ "@strapi/types": "5.46.0",
71
+ "@strapi/typescript-utils": "5.46.0",
72
+ "@strapi/utils": "5.46.0",
73
73
  "@vercel/stega": "0.1.2",
74
74
  bcryptjs: "2.4.3",
75
75
  boxen: "5.1.2",
@@ -136,11 +136,11 @@ var devDependencies = {
136
136
  "@types/node": "24.10.0",
137
137
  "@types/node-schedule": "2.1.7",
138
138
  "@types/statuses": "2.0.1",
139
- "eslint-config-custom": "5.45.0",
139
+ "eslint-config-custom": "5.46.0",
140
140
  supertest: "7.2.2",
141
- tsconfig: "5.45.0",
141
+ tsconfig: "5.46.0",
142
142
  vitest: "catalog:",
143
- "vitest-config": "5.45.0"
143
+ "vitest-config": "5.46.0"
144
144
  };
145
145
  var engines = {
146
146
  node: ">=20.0.0 <=24.x.x",
@@ -1,5 +1,5 @@
1
1
  var name = "@strapi/core";
2
- var version = "5.45.0";
2
+ var version = "5.46.0";
3
3
  var description = "Core of Strapi";
4
4
  var homepage = "https://strapi.io";
5
5
  var bugs = {
@@ -58,14 +58,14 @@ var dependencies = {
58
58
  "@koa/cors": "5.0.0",
59
59
  "@koa/router": "12.0.2",
60
60
  "@paralleldrive/cuid2": "2.2.2",
61
- "@strapi/admin": "5.45.0",
62
- "@strapi/database": "5.45.0",
63
- "@strapi/generators": "5.45.0",
64
- "@strapi/logger": "5.45.0",
65
- "@strapi/permissions": "5.45.0",
66
- "@strapi/types": "5.45.0",
67
- "@strapi/typescript-utils": "5.45.0",
68
- "@strapi/utils": "5.45.0",
61
+ "@strapi/admin": "5.46.0",
62
+ "@strapi/database": "5.46.0",
63
+ "@strapi/generators": "5.46.0",
64
+ "@strapi/logger": "5.46.0",
65
+ "@strapi/permissions": "5.46.0",
66
+ "@strapi/types": "5.46.0",
67
+ "@strapi/typescript-utils": "5.46.0",
68
+ "@strapi/utils": "5.46.0",
69
69
  "@vercel/stega": "0.1.2",
70
70
  bcryptjs: "2.4.3",
71
71
  boxen: "5.1.2",
@@ -132,11 +132,11 @@ var devDependencies = {
132
132
  "@types/node": "24.10.0",
133
133
  "@types/node-schedule": "2.1.7",
134
134
  "@types/statuses": "2.0.1",
135
- "eslint-config-custom": "5.45.0",
135
+ "eslint-config-custom": "5.46.0",
136
136
  supertest: "7.2.2",
137
- tsconfig: "5.45.0",
137
+ tsconfig: "5.46.0",
138
138
  vitest: "catalog:",
139
- "vitest-config": "5.45.0"
139
+ "vitest-config": "5.46.0"
140
140
  };
141
141
  var engines = {
142
142
  node: ">=20.0.0 <=24.x.x",
@@ -1 +1 @@
1
- {"version":3,"file":"content-source-maps.d.ts","sourceRoot":"","sources":["../../src/services/content-source-maps.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAO,MAAM,eAAe,CAAC;AAEvD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAwCxE,UAAU,YAAY;IACpB,IAAI,EAAE,GAAG,CAAC;IACV,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC;CACvB;AAMD,QAAA,MAAM,8BAA8B,WAAY,KAAK,MAAM;sBAG/C,MAAM,mDACqC,qBAAqB;kCAyBpC,YAAY,GAAG,QAAQ,GAAG,CAAC;uCAiCtB,YAAY,GAAG,QAAQ,GAAG,CAAC;CAmBvE,CAAC;AAEF,OAAO,EAAE,8BAA8B,EAAE,CAAC"}
1
+ {"version":3,"file":"content-source-maps.d.ts","sourceRoot":"","sources":["../../src/services/content-source-maps.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAO,MAAM,eAAe,CAAC;AAEvD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAwCxE,UAAU,YAAY;IACpB,IAAI,EAAE,GAAG,CAAC;IACV,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC;CACvB;AAMD,QAAA,MAAM,8BAA8B,WAAY,KAAK,MAAM;sBAG/C,MAAM,mDACqC,qBAAqB;kCAiCpC,YAAY,GAAG,QAAQ,GAAG,CAAC;uCA6CtB,YAAY,GAAG,QAAQ,GAAG,CAAC;CAmBvE,CAAC;AAEF,OAAO,EAAE,8BAA8B,EAAE,CAAC"}
@@ -54,21 +54,29 @@ const createContentSourceMapsService = (strapi)=>{
54
54
  if (locale) {
55
55
  strapiSource.set('locale', locale);
56
56
  }
57
- return stega.vercelStegaCombine(text, {
57
+ const encoded = stega.vercelStegaCombine(text, {
58
58
  strapiSource: strapiSource.toString()
59
- });
59
+ }, false);
60
+ return encoded;
60
61
  },
61
62
  async encodeEntry ({ data, schema }) {
62
63
  if (!isObject(data) || data === undefined) {
63
64
  return data;
64
65
  }
65
- return strapiUtils.traverseEntity(({ key, value, attribute, schema, path }, { set })=>{
66
+ return strapiUtils.traverseEntity(({ key, value, attribute, schema, path, parent }, { set })=>{
66
67
  if (!attribute || EXCLUDED_FIELDS.includes(key)) {
67
68
  return;
68
69
  }
69
70
  if (ENCODABLE_TYPES.includes(attribute.type) && typeof value === 'string') {
71
+ // For inner fields of a multi-media field's items (e.g. `medias.0.url`),
72
+ // drop the array index so all items share the same encoded path. The
73
+ // preview groups them under one highlight and opens the multi-media
74
+ // input as a single field, matching the side editor.
75
+ const parentAttr = parent?.attribute;
76
+ const isInsideMultiMedia = parentAttr?.type === 'media' && parentAttr.multiple === true;
77
+ const encodedPath = isInsideMultiMedia && parent?.path?.rawWithIndices ? `${parent.path.rawWithIndices}.${key}` : path.rawWithIndices;
70
78
  set(key, this.encodeField(value, {
71
- path: path.rawWithIndices,
79
+ path: encodedPath,
72
80
  type: attribute.type,
73
81
  kind: schema.kind,
74
82
  model: schema.uid,
@@ -1 +1 @@
1
- {"version":3,"file":"content-source-maps.js","sources":["../../src/services/content-source-maps.ts"],"sourcesContent":["import { vercelStegaCombine } from '@vercel/stega';\nimport type { Core, Struct, UID } from '@strapi/types';\nimport { traverseEntity } from '@strapi/utils';\nimport type { FieldContentSourceMap } from '@strapi/admin/strapi-admin';\n\nconst ENCODABLE_TYPES = [\n 'string',\n 'text',\n 'richtext',\n 'biginteger',\n 'date',\n 'time',\n 'datetime',\n 'timestamp',\n 'boolean',\n 'enumeration',\n 'json',\n 'media',\n 'email',\n 'password',\n /**\n * We cannot modify the response shape, so types that aren't based on string cannot be encoded:\n * - json: object\n * - blocks: object, will require a custom implementation in a dedicated PR\n * - integer, float and decimal: number\n * - boolean: boolean (believe it or not)\n * - uid: can be stringified but would mess up URLs\n */\n];\n\n// TODO: use a centralized store for these fields that would be shared with the CM and CTB\nconst EXCLUDED_FIELDS = [\n 'id',\n 'documentId',\n 'locale',\n 'localizations',\n 'created_by',\n 'updated_by',\n 'created_at',\n 'updated_at',\n 'publishedAt',\n];\n\ninterface EncodingInfo {\n data: any;\n schema: Struct.Schema;\n}\n\nconst isObject = (value: unknown): value is Record<string, any> => {\n return typeof value === 'object' && value !== null;\n};\n\nconst createContentSourceMapsService = (strapi: Core.Strapi) => {\n return {\n encodeField(\n text: string,\n { kind, model, documentId, type, path, locale }: FieldContentSourceMap\n ) {\n /**\n * Combine all metadata into into a one string so we only have to deal with one data-atribute\n * on the frontend. Make it human readable because that data-attribute may be set manually by\n * users for fields that don't support sourcemap encoding.\n */\n const strapiSource = new URLSearchParams();\n strapiSource.set('documentId', documentId);\n strapiSource.set('type', type);\n strapiSource.set('path', path);\n\n if (model) {\n strapiSource.set('model', model);\n }\n if (kind) {\n strapiSource.set('kind', kind);\n }\n if (locale) {\n strapiSource.set('locale', locale);\n }\n\n return vercelStegaCombine(text, { strapiSource: strapiSource.toString() });\n },\n\n async encodeEntry({ data, schema }: EncodingInfo): Promise<any> {\n if (!isObject(data) || data === undefined) {\n return data;\n }\n\n return traverseEntity(\n ({ key, value, attribute, schema, path }, { set }) => {\n if (!attribute || EXCLUDED_FIELDS.includes(key)) {\n return;\n }\n\n if (ENCODABLE_TYPES.includes(attribute.type) && typeof value === 'string') {\n set(\n key,\n this.encodeField(value, {\n path: path.rawWithIndices!,\n type: attribute.type,\n kind: schema.kind,\n model: schema.uid as UID.Schema,\n locale: data.locale,\n documentId: data.documentId,\n }) as any\n );\n }\n },\n {\n schema,\n getModel: (uid) => strapi.getModel(uid as UID.Schema),\n },\n data\n );\n },\n\n async encodeSourceMaps({ data, schema }: EncodingInfo): Promise<any> {\n try {\n if (Array.isArray(data)) {\n return await Promise.all(\n data.map((item) => this.encodeSourceMaps({ data: item, schema }))\n );\n }\n\n if (!isObject(data)) {\n return data;\n }\n\n return await this.encodeEntry({ data, schema });\n } catch (error) {\n strapi.log.error('Error encoding source maps:', error);\n return data;\n }\n },\n };\n};\n\nexport { createContentSourceMapsService };\n"],"names":["ENCODABLE_TYPES","EXCLUDED_FIELDS","isObject","value","createContentSourceMapsService","strapi","encodeField","text","kind","model","documentId","type","path","locale","strapiSource","URLSearchParams","set","vercelStegaCombine","toString","encodeEntry","data","schema","undefined","traverseEntity","key","attribute","includes","rawWithIndices","uid","getModel","encodeSourceMaps","Array","isArray","Promise","all","map","item","error","log"],"mappings":"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"}
1
+ {"version":3,"file":"content-source-maps.js","sources":["../../src/services/content-source-maps.ts"],"sourcesContent":["import { vercelStegaCombine } from '@vercel/stega';\nimport type { Core, Struct, UID } from '@strapi/types';\nimport { traverseEntity } from '@strapi/utils';\nimport type { FieldContentSourceMap } from '@strapi/admin/strapi-admin';\n\nconst ENCODABLE_TYPES = [\n 'string',\n 'text',\n 'richtext',\n 'biginteger',\n 'date',\n 'time',\n 'datetime',\n 'timestamp',\n 'boolean',\n 'enumeration',\n 'json',\n 'media',\n 'email',\n 'password',\n /**\n * We cannot modify the response shape, so types that aren't based on string cannot be encoded:\n * - json: object\n * - blocks: object, will require a custom implementation in a dedicated PR\n * - integer, float and decimal: number\n * - boolean: boolean (believe it or not)\n * - uid: can be stringified but would mess up URLs\n */\n];\n\n// TODO: use a centralized store for these fields that would be shared with the CM and CTB\nconst EXCLUDED_FIELDS = [\n 'id',\n 'documentId',\n 'locale',\n 'localizations',\n 'created_by',\n 'updated_by',\n 'created_at',\n 'updated_at',\n 'publishedAt',\n];\n\ninterface EncodingInfo {\n data: any;\n schema: Struct.Schema;\n}\n\nconst isObject = (value: unknown): value is Record<string, any> => {\n return typeof value === 'object' && value !== null;\n};\n\nconst createContentSourceMapsService = (strapi: Core.Strapi) => {\n return {\n encodeField(\n text: string,\n { kind, model, documentId, type, path, locale }: FieldContentSourceMap\n ) {\n /**\n * Combine all metadata into into a one string so we only have to deal with one data-atribute\n * on the frontend. Make it human readable because that data-attribute may be set manually by\n * users for fields that don't support sourcemap encoding.\n */\n const strapiSource = new URLSearchParams();\n strapiSource.set('documentId', documentId);\n strapiSource.set('type', type);\n strapiSource.set('path', path);\n\n if (model) {\n strapiSource.set('model', model);\n }\n if (kind) {\n strapiSource.set('kind', kind);\n }\n if (locale) {\n strapiSource.set('locale', locale);\n }\n\n const encoded = vercelStegaCombine(\n text,\n {\n strapiSource: strapiSource.toString(),\n },\n false\n );\n\n return encoded;\n },\n\n async encodeEntry({ data, schema }: EncodingInfo): Promise<any> {\n if (!isObject(data) || data === undefined) {\n return data;\n }\n\n return traverseEntity(\n ({ key, value, attribute, schema, path, parent }, { set }) => {\n if (!attribute || EXCLUDED_FIELDS.includes(key)) {\n return;\n }\n\n if (ENCODABLE_TYPES.includes(attribute.type) && typeof value === 'string') {\n // For inner fields of a multi-media field's items (e.g. `medias.0.url`),\n // drop the array index so all items share the same encoded path. The\n // preview groups them under one highlight and opens the multi-media\n // input as a single field, matching the side editor.\n const parentAttr = parent?.attribute;\n const isInsideMultiMedia =\n parentAttr?.type === 'media' && (parentAttr as any).multiple === true;\n const encodedPath =\n isInsideMultiMedia && parent?.path?.rawWithIndices\n ? `${parent.path.rawWithIndices}.${key}`\n : path.rawWithIndices!;\n\n set(\n key,\n this.encodeField(value, {\n path: encodedPath,\n type: attribute.type,\n kind: schema.kind,\n model: schema.uid as UID.Schema,\n locale: data.locale,\n documentId: data.documentId,\n }) as any\n );\n }\n },\n {\n schema,\n getModel: (uid) => strapi.getModel(uid as UID.Schema),\n },\n data\n );\n },\n\n async encodeSourceMaps({ data, schema }: EncodingInfo): Promise<any> {\n try {\n if (Array.isArray(data)) {\n return await Promise.all(\n data.map((item) => this.encodeSourceMaps({ data: item, schema }))\n );\n }\n\n if (!isObject(data)) {\n return data;\n }\n\n return await this.encodeEntry({ data, schema });\n } catch (error) {\n strapi.log.error('Error encoding source maps:', error);\n return data;\n }\n },\n };\n};\n\nexport { createContentSourceMapsService };\n"],"names":["ENCODABLE_TYPES","EXCLUDED_FIELDS","isObject","value","createContentSourceMapsService","strapi","encodeField","text","kind","model","documentId","type","path","locale","strapiSource","URLSearchParams","set","encoded","vercelStegaCombine","toString","encodeEntry","data","schema","undefined","traverseEntity","key","attribute","parent","includes","parentAttr","isInsideMultiMedia","multiple","encodedPath","rawWithIndices","uid","getModel","encodeSourceMaps","Array","isArray","Promise","all","map","item","error","log"],"mappings":"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"}
@@ -52,21 +52,29 @@ const createContentSourceMapsService = (strapi)=>{
52
52
  if (locale) {
53
53
  strapiSource.set('locale', locale);
54
54
  }
55
- return vercelStegaCombine(text, {
55
+ const encoded = vercelStegaCombine(text, {
56
56
  strapiSource: strapiSource.toString()
57
- });
57
+ }, false);
58
+ return encoded;
58
59
  },
59
60
  async encodeEntry ({ data, schema }) {
60
61
  if (!isObject(data) || data === undefined) {
61
62
  return data;
62
63
  }
63
- return traverseEntity(({ key, value, attribute, schema, path }, { set })=>{
64
+ return traverseEntity(({ key, value, attribute, schema, path, parent }, { set })=>{
64
65
  if (!attribute || EXCLUDED_FIELDS.includes(key)) {
65
66
  return;
66
67
  }
67
68
  if (ENCODABLE_TYPES.includes(attribute.type) && typeof value === 'string') {
69
+ // For inner fields of a multi-media field's items (e.g. `medias.0.url`),
70
+ // drop the array index so all items share the same encoded path. The
71
+ // preview groups them under one highlight and opens the multi-media
72
+ // input as a single field, matching the side editor.
73
+ const parentAttr = parent?.attribute;
74
+ const isInsideMultiMedia = parentAttr?.type === 'media' && parentAttr.multiple === true;
75
+ const encodedPath = isInsideMultiMedia && parent?.path?.rawWithIndices ? `${parent.path.rawWithIndices}.${key}` : path.rawWithIndices;
68
76
  set(key, this.encodeField(value, {
69
- path: path.rawWithIndices,
77
+ path: encodedPath,
70
78
  type: attribute.type,
71
79
  kind: schema.kind,
72
80
  model: schema.uid,
@@ -1 +1 @@
1
- {"version":3,"file":"content-source-maps.mjs","sources":["../../src/services/content-source-maps.ts"],"sourcesContent":["import { vercelStegaCombine } from '@vercel/stega';\nimport type { Core, Struct, UID } from '@strapi/types';\nimport { traverseEntity } from '@strapi/utils';\nimport type { FieldContentSourceMap } from '@strapi/admin/strapi-admin';\n\nconst ENCODABLE_TYPES = [\n 'string',\n 'text',\n 'richtext',\n 'biginteger',\n 'date',\n 'time',\n 'datetime',\n 'timestamp',\n 'boolean',\n 'enumeration',\n 'json',\n 'media',\n 'email',\n 'password',\n /**\n * We cannot modify the response shape, so types that aren't based on string cannot be encoded:\n * - json: object\n * - blocks: object, will require a custom implementation in a dedicated PR\n * - integer, float and decimal: number\n * - boolean: boolean (believe it or not)\n * - uid: can be stringified but would mess up URLs\n */\n];\n\n// TODO: use a centralized store for these fields that would be shared with the CM and CTB\nconst EXCLUDED_FIELDS = [\n 'id',\n 'documentId',\n 'locale',\n 'localizations',\n 'created_by',\n 'updated_by',\n 'created_at',\n 'updated_at',\n 'publishedAt',\n];\n\ninterface EncodingInfo {\n data: any;\n schema: Struct.Schema;\n}\n\nconst isObject = (value: unknown): value is Record<string, any> => {\n return typeof value === 'object' && value !== null;\n};\n\nconst createContentSourceMapsService = (strapi: Core.Strapi) => {\n return {\n encodeField(\n text: string,\n { kind, model, documentId, type, path, locale }: FieldContentSourceMap\n ) {\n /**\n * Combine all metadata into into a one string so we only have to deal with one data-atribute\n * on the frontend. Make it human readable because that data-attribute may be set manually by\n * users for fields that don't support sourcemap encoding.\n */\n const strapiSource = new URLSearchParams();\n strapiSource.set('documentId', documentId);\n strapiSource.set('type', type);\n strapiSource.set('path', path);\n\n if (model) {\n strapiSource.set('model', model);\n }\n if (kind) {\n strapiSource.set('kind', kind);\n }\n if (locale) {\n strapiSource.set('locale', locale);\n }\n\n return vercelStegaCombine(text, { strapiSource: strapiSource.toString() });\n },\n\n async encodeEntry({ data, schema }: EncodingInfo): Promise<any> {\n if (!isObject(data) || data === undefined) {\n return data;\n }\n\n return traverseEntity(\n ({ key, value, attribute, schema, path }, { set }) => {\n if (!attribute || EXCLUDED_FIELDS.includes(key)) {\n return;\n }\n\n if (ENCODABLE_TYPES.includes(attribute.type) && typeof value === 'string') {\n set(\n key,\n this.encodeField(value, {\n path: path.rawWithIndices!,\n type: attribute.type,\n kind: schema.kind,\n model: schema.uid as UID.Schema,\n locale: data.locale,\n documentId: data.documentId,\n }) as any\n );\n }\n },\n {\n schema,\n getModel: (uid) => strapi.getModel(uid as UID.Schema),\n },\n data\n );\n },\n\n async encodeSourceMaps({ data, schema }: EncodingInfo): Promise<any> {\n try {\n if (Array.isArray(data)) {\n return await Promise.all(\n data.map((item) => this.encodeSourceMaps({ data: item, schema }))\n );\n }\n\n if (!isObject(data)) {\n return data;\n }\n\n return await this.encodeEntry({ data, schema });\n } catch (error) {\n strapi.log.error('Error encoding source maps:', error);\n return data;\n }\n },\n };\n};\n\nexport { createContentSourceMapsService };\n"],"names":["ENCODABLE_TYPES","EXCLUDED_FIELDS","isObject","value","createContentSourceMapsService","strapi","encodeField","text","kind","model","documentId","type","path","locale","strapiSource","URLSearchParams","set","vercelStegaCombine","toString","encodeEntry","data","schema","undefined","traverseEntity","key","attribute","includes","rawWithIndices","uid","getModel","encodeSourceMaps","Array","isArray","Promise","all","map","item","error","log"],"mappings":";;;AAKA,MAAMA,eAAAA,GAAkB;AACtB,IAAA,QAAA;AACA,IAAA,MAAA;AACA,IAAA,UAAA;AACA,IAAA,YAAA;AACA,IAAA,MAAA;AACA,IAAA,MAAA;AACA,IAAA,UAAA;AACA,IAAA,WAAA;AACA,IAAA,SAAA;AACA,IAAA,aAAA;AACA,IAAA,MAAA;AACA,IAAA,OAAA;AACA,IAAA,OAAA;AACA,IAAA;AASD,CAAA;AAED;AACA,MAAMC,eAAAA,GAAkB;AACtB,IAAA,IAAA;AACA,IAAA,YAAA;AACA,IAAA,QAAA;AACA,IAAA,eAAA;AACA,IAAA,YAAA;AACA,IAAA,YAAA;AACA,IAAA,YAAA;AACA,IAAA,YAAA;AACA,IAAA;AACD,CAAA;AAOD,MAAMC,WAAW,CAACC,KAAAA,GAAAA;IAChB,OAAO,OAAOA,KAAAA,KAAU,QAAA,IAAYA,KAAAA,KAAU,IAAA;AAChD,CAAA;AAEA,MAAMC,iCAAiC,CAACC,MAAAA,GAAAA;IACtC,OAAO;AACLC,QAAAA,WAAAA,CAAAA,CACEC,IAAY,EACZ,EAAEC,IAAI,EAAEC,KAAK,EAAEC,UAAU,EAAEC,IAAI,EAAEC,IAAI,EAAEC,MAAM,EAAyB,EAAA;AAEtE;;;;UAKA,MAAMC,eAAe,IAAIC,eAAAA,EAAAA;YACzBD,YAAAA,CAAaE,GAAG,CAAC,YAAA,EAAcN,UAAAA,CAAAA;YAC/BI,YAAAA,CAAaE,GAAG,CAAC,MAAA,EAAQL,IAAAA,CAAAA;YACzBG,YAAAA,CAAaE,GAAG,CAAC,MAAA,EAAQJ,IAAAA,CAAAA;AAEzB,YAAA,IAAIH,KAAAA,EAAO;gBACTK,YAAAA,CAAaE,GAAG,CAAC,OAAA,EAASP,KAAAA,CAAAA;AAC5B,YAAA;AACA,YAAA,IAAID,IAAAA,EAAM;gBACRM,YAAAA,CAAaE,GAAG,CAAC,MAAA,EAAQR,IAAAA,CAAAA;AAC3B,YAAA;AACA,YAAA,IAAIK,MAAAA,EAAQ;gBACVC,YAAAA,CAAaE,GAAG,CAAC,QAAA,EAAUH,MAAAA,CAAAA;AAC7B,YAAA;AAEA,YAAA,OAAOI,mBAAmBV,IAAAA,EAAM;AAAEO,gBAAAA,YAAAA,EAAcA,aAAaI,QAAQ;AAAG,aAAA,CAAA;AAC1E,QAAA,CAAA;AAEA,QAAA,MAAMC,WAAAA,CAAAA,CAAY,EAAEC,IAAI,EAAEC,MAAM,EAAgB,EAAA;AAC9C,YAAA,IAAI,CAACnB,QAAAA,CAASkB,IAAAA,CAAAA,IAASA,IAAAA,KAASE,SAAAA,EAAW;gBACzC,OAAOF,IAAAA;AACT,YAAA;AAEA,YAAA,OAAOG,eACL,CAAC,EAAEC,GAAG,EAAErB,KAAK,EAAEsB,SAAS,EAAEJ,MAAM,EAAET,IAAI,EAAE,EAAE,EAAEI,GAAG,EAAE,GAAA;AAC/C,gBAAA,IAAI,CAACS,SAAAA,IAAaxB,eAAAA,CAAgByB,QAAQ,CAACF,GAAAA,CAAAA,EAAM;AAC/C,oBAAA;AACF,gBAAA;gBAEA,IAAIxB,eAAAA,CAAgB0B,QAAQ,CAACD,SAAAA,CAAUd,IAAI,CAAA,IAAK,OAAOR,UAAU,QAAA,EAAU;AACzEa,oBAAAA,GAAAA,CACEQ,GAAAA,EACA,IAAI,CAAClB,WAAW,CAACH,KAAAA,EAAO;AACtBS,wBAAAA,IAAAA,EAAMA,KAAKe,cAAc;AACzBhB,wBAAAA,IAAAA,EAAMc,UAAUd,IAAI;AACpBH,wBAAAA,IAAAA,EAAMa,OAAOb,IAAI;AACjBC,wBAAAA,KAAAA,EAAOY,OAAOO,GAAG;AACjBf,wBAAAA,MAAAA,EAAQO,KAAKP,MAAM;AACnBH,wBAAAA,UAAAA,EAAYU,KAAKV;AACnB,qBAAA,CAAA,CAAA;AAEJ,gBAAA;YACF,CAAA,EACA;AACEW,gBAAAA,MAAAA;AACAQ,gBAAAA,QAAAA,EAAU,CAACD,GAAAA,GAAQvB,MAAAA,CAAOwB,QAAQ,CAACD,GAAAA;aACrC,EACAR,IAAAA,CAAAA;AAEJ,QAAA,CAAA;AAEA,QAAA,MAAMU,gBAAAA,CAAAA,CAAiB,EAAEV,IAAI,EAAEC,MAAM,EAAgB,EAAA;YACnD,IAAI;gBACF,IAAIU,KAAAA,CAAMC,OAAO,CAACZ,IAAAA,CAAAA,EAAO;AACvB,oBAAA,OAAO,MAAMa,OAAAA,CAAQC,GAAG,CACtBd,IAAAA,CAAKe,GAAG,CAAC,CAACC,IAAAA,GAAS,IAAI,CAACN,gBAAgB,CAAC;4BAAEV,IAAAA,EAAMgB,IAAAA;AAAMf,4BAAAA;AAAO,yBAAA,CAAA,CAAA,CAAA;AAElE,gBAAA;gBAEA,IAAI,CAACnB,SAASkB,IAAAA,CAAAA,EAAO;oBACnB,OAAOA,IAAAA;AACT,gBAAA;AAEA,gBAAA,OAAO,MAAM,IAAI,CAACD,WAAW,CAAC;AAAEC,oBAAAA,IAAAA;AAAMC,oBAAAA;AAAO,iBAAA,CAAA;AAC/C,YAAA,CAAA,CAAE,OAAOgB,KAAAA,EAAO;AACdhC,gBAAAA,MAAAA,CAAOiC,GAAG,CAACD,KAAK,CAAC,6BAAA,EAA+BA,KAAAA,CAAAA;gBAChD,OAAOjB,IAAAA;AACT,YAAA;AACF,QAAA;AACF,KAAA;AACF;;;;"}
1
+ {"version":3,"file":"content-source-maps.mjs","sources":["../../src/services/content-source-maps.ts"],"sourcesContent":["import { vercelStegaCombine } from '@vercel/stega';\nimport type { Core, Struct, UID } from '@strapi/types';\nimport { traverseEntity } from '@strapi/utils';\nimport type { FieldContentSourceMap } from '@strapi/admin/strapi-admin';\n\nconst ENCODABLE_TYPES = [\n 'string',\n 'text',\n 'richtext',\n 'biginteger',\n 'date',\n 'time',\n 'datetime',\n 'timestamp',\n 'boolean',\n 'enumeration',\n 'json',\n 'media',\n 'email',\n 'password',\n /**\n * We cannot modify the response shape, so types that aren't based on string cannot be encoded:\n * - json: object\n * - blocks: object, will require a custom implementation in a dedicated PR\n * - integer, float and decimal: number\n * - boolean: boolean (believe it or not)\n * - uid: can be stringified but would mess up URLs\n */\n];\n\n// TODO: use a centralized store for these fields that would be shared with the CM and CTB\nconst EXCLUDED_FIELDS = [\n 'id',\n 'documentId',\n 'locale',\n 'localizations',\n 'created_by',\n 'updated_by',\n 'created_at',\n 'updated_at',\n 'publishedAt',\n];\n\ninterface EncodingInfo {\n data: any;\n schema: Struct.Schema;\n}\n\nconst isObject = (value: unknown): value is Record<string, any> => {\n return typeof value === 'object' && value !== null;\n};\n\nconst createContentSourceMapsService = (strapi: Core.Strapi) => {\n return {\n encodeField(\n text: string,\n { kind, model, documentId, type, path, locale }: FieldContentSourceMap\n ) {\n /**\n * Combine all metadata into into a one string so we only have to deal with one data-atribute\n * on the frontend. Make it human readable because that data-attribute may be set manually by\n * users for fields that don't support sourcemap encoding.\n */\n const strapiSource = new URLSearchParams();\n strapiSource.set('documentId', documentId);\n strapiSource.set('type', type);\n strapiSource.set('path', path);\n\n if (model) {\n strapiSource.set('model', model);\n }\n if (kind) {\n strapiSource.set('kind', kind);\n }\n if (locale) {\n strapiSource.set('locale', locale);\n }\n\n const encoded = vercelStegaCombine(\n text,\n {\n strapiSource: strapiSource.toString(),\n },\n false\n );\n\n return encoded;\n },\n\n async encodeEntry({ data, schema }: EncodingInfo): Promise<any> {\n if (!isObject(data) || data === undefined) {\n return data;\n }\n\n return traverseEntity(\n ({ key, value, attribute, schema, path, parent }, { set }) => {\n if (!attribute || EXCLUDED_FIELDS.includes(key)) {\n return;\n }\n\n if (ENCODABLE_TYPES.includes(attribute.type) && typeof value === 'string') {\n // For inner fields of a multi-media field's items (e.g. `medias.0.url`),\n // drop the array index so all items share the same encoded path. The\n // preview groups them under one highlight and opens the multi-media\n // input as a single field, matching the side editor.\n const parentAttr = parent?.attribute;\n const isInsideMultiMedia =\n parentAttr?.type === 'media' && (parentAttr as any).multiple === true;\n const encodedPath =\n isInsideMultiMedia && parent?.path?.rawWithIndices\n ? `${parent.path.rawWithIndices}.${key}`\n : path.rawWithIndices!;\n\n set(\n key,\n this.encodeField(value, {\n path: encodedPath,\n type: attribute.type,\n kind: schema.kind,\n model: schema.uid as UID.Schema,\n locale: data.locale,\n documentId: data.documentId,\n }) as any\n );\n }\n },\n {\n schema,\n getModel: (uid) => strapi.getModel(uid as UID.Schema),\n },\n data\n );\n },\n\n async encodeSourceMaps({ data, schema }: EncodingInfo): Promise<any> {\n try {\n if (Array.isArray(data)) {\n return await Promise.all(\n data.map((item) => this.encodeSourceMaps({ data: item, schema }))\n );\n }\n\n if (!isObject(data)) {\n return data;\n }\n\n return await this.encodeEntry({ data, schema });\n } catch (error) {\n strapi.log.error('Error encoding source maps:', error);\n return data;\n }\n },\n };\n};\n\nexport { createContentSourceMapsService };\n"],"names":["ENCODABLE_TYPES","EXCLUDED_FIELDS","isObject","value","createContentSourceMapsService","strapi","encodeField","text","kind","model","documentId","type","path","locale","strapiSource","URLSearchParams","set","encoded","vercelStegaCombine","toString","encodeEntry","data","schema","undefined","traverseEntity","key","attribute","parent","includes","parentAttr","isInsideMultiMedia","multiple","encodedPath","rawWithIndices","uid","getModel","encodeSourceMaps","Array","isArray","Promise","all","map","item","error","log"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"data-ids.d.ts","sourceRoot":"","sources":["../../../../../../src/services/document-service/transform/relations/extract/data-ids.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAEzC,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAQrC,UAAU,OAAO;IACf,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,GAAG,WAAW,CAAC;CAChC;AA8BD;;;GAGG;AACH,QAAA,MAAM,cAAc,UAAW,KAAK,QAAQ,OAAO,MAAM,EAAE,GAAG,CAAC,UAAU,OAAO,qDA2C/E,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,CAAC"}
1
+ {"version":3,"file":"data-ids.d.ts","sourceRoot":"","sources":["../../../../../../src/services/document-service/transform/relations/extract/data-ids.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAEzC,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AASrC,UAAU,OAAO;IACf,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,GAAG,WAAW,CAAC;CAChC;AA8BD;;;GAGG;AACH,QAAA,MAAM,cAAc,UAAW,KAAK,QAAQ,OAAO,MAAM,EAAE,GAAG,CAAC,UAAU,OAAO,qDA8C/E,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,CAAC"}
@@ -5,6 +5,7 @@ var strapiUtils = require('@strapi/utils');
5
5
  var i18n = require('../utils/i18n.js');
6
6
  var dp = require('../utils/dp.js');
7
7
  var mapRelation = require('../utils/map-relation.js');
8
+ var xtoOne = require('../utils/xto-one.js');
8
9
 
9
10
  const { isPolymorphic } = strapiUtils.relations;
10
11
  /**
@@ -39,6 +40,8 @@ const { isPolymorphic } = strapiUtils.relations;
39
40
  }
40
41
  const isPolymorphicRelation = isPolymorphic(attribute);
41
42
  const addDocId = addRelationDocId(idMap, source);
43
+ // Skip looking up entries we're about to discard.
44
+ const normalizedValue = xtoOne.normalizeXToOneRelationValue(attribute, value);
42
45
  return mapRelation.mapRelation((relation)=>{
43
46
  if (!relation || !relation.documentId) {
44
47
  return relation;
@@ -69,7 +72,7 @@ const { isPolymorphic } = strapiUtils.relations;
69
72
  });
70
73
  }
71
74
  return relation;
72
- }, value);
75
+ }, normalizedValue);
73
76
  }, {
74
77
  schema: strapi.getModel(source.uid),
75
78
  getModel: strapi.getModel.bind(strapi)
@@ -1 +1 @@
1
- {"version":3,"file":"data-ids.js","sources":["../../../../../../src/services/document-service/transform/relations/extract/data-ids.ts"],"sourcesContent":["import { curry } from 'lodash/fp';\n\nimport type { UID } from '@strapi/types';\nimport { relations } from '@strapi/utils';\nimport { IdMap } from '../../id-map';\nimport { getRelationTargetLocale } from '../utils/i18n';\nimport { getRelationTargetStatus } from '../utils/dp';\nimport { mapRelation, traverseEntityRelations } from '../utils/map-relation';\nimport { LongHandDocument } from '../utils/types';\n\nconst { isPolymorphic } = relations;\n\ninterface Options {\n uid: UID.Schema;\n locale?: string | null;\n status?: 'draft' | 'published';\n}\n\n/**\n * Load a relation documentId into the idMap.\n */\nconst addRelationDocId = curry(\n (idMap: IdMap, source: Options, targetUid: UID.Schema, relation: LongHandDocument) => {\n const targetLocale = getRelationTargetLocale(relation, {\n targetUid,\n sourceUid: source.uid,\n sourceLocale: source.locale,\n });\n\n const targetStatus = getRelationTargetStatus(relation, {\n targetUid,\n sourceUid: source.uid,\n sourceStatus: source.status,\n });\n\n targetStatus.forEach((status) => {\n idMap.add({\n uid: targetUid,\n documentId: relation.documentId,\n locale: targetLocale,\n status,\n });\n });\n }\n);\n\n/**\n * Iterate over all relations of a data object and extract all relational document ids.\n * Those will later be transformed to entity ids.\n */\nconst extractDataIds = (idMap: IdMap, data: Record<string, any>, source: Options) => {\n return traverseEntityRelations(\n async ({ attribute, value }) => {\n if (!attribute) {\n return;\n }\n const isPolymorphicRelation = isPolymorphic(attribute);\n const addDocId = addRelationDocId(idMap, source);\n\n return mapRelation((relation) => {\n if (!relation || !relation.documentId) {\n return relation;\n }\n\n // Regular relations will always target the same target\n // if its a polymorphic relation we need to get it from the data itself\n const targetUid = isPolymorphicRelation ? relation.__type : attribute.target;\n\n addDocId(targetUid, relation);\n\n // Handle positional arguments\n const position = relation.position;\n\n // The positional relation target uid can be different for polymorphic relations\n let positionTargetUid = targetUid;\n if (isPolymorphicRelation && position?.__type) {\n positionTargetUid = position.__type;\n }\n\n if (position?.before) {\n addDocId(positionTargetUid, { ...relation, ...position, documentId: position.before });\n }\n\n if (position?.after) {\n addDocId(positionTargetUid, { ...relation, ...position, documentId: position.after });\n }\n\n return relation;\n }, value as any);\n },\n { schema: strapi.getModel(source.uid), getModel: strapi.getModel.bind(strapi) },\n data\n );\n};\n\nexport { extractDataIds };\n"],"names":["isPolymorphic","relations","addRelationDocId","curry","idMap","source","targetUid","relation","targetLocale","getRelationTargetLocale","sourceUid","uid","sourceLocale","locale","targetStatus","getRelationTargetStatus","sourceStatus","status","forEach","add","documentId","extractDataIds","data","traverseEntityRelations","attribute","value","isPolymorphicRelation","addDocId","mapRelation","__type","target","position","positionTargetUid","before","after","schema","strapi","getModel","bind"],"mappings":";;;;;;;;AAUA,MAAM,EAAEA,aAAa,EAAE,GAAGC,qBAAAA;AAQ1B;;AAEC,IACD,MAAMC,gBAAAA,GAAmBC,QAAAA,CACvB,CAACC,KAAAA,EAAcC,QAAiBC,SAAAA,EAAuBC,QAAAA,GAAAA;IACrD,MAAMC,YAAAA,GAAeC,6BAAwBF,QAAAA,EAAU;AACrDD,QAAAA,SAAAA;AACAI,QAAAA,SAAAA,EAAWL,OAAOM,GAAG;AACrBC,QAAAA,YAAAA,EAAcP,OAAOQ;AACvB,KAAA,CAAA;IAEA,MAAMC,YAAAA,GAAeC,2BAAwBR,QAAAA,EAAU;AACrDD,QAAAA,SAAAA;AACAI,QAAAA,SAAAA,EAAWL,OAAOM,GAAG;AACrBK,QAAAA,YAAAA,EAAcX,OAAOY;AACvB,KAAA,CAAA;IAEAH,YAAAA,CAAaI,OAAO,CAAC,CAACD,MAAAA,GAAAA;AACpBb,QAAAA,KAAAA,CAAMe,GAAG,CAAC;YACRR,GAAAA,EAAKL,SAAAA;AACLc,YAAAA,UAAAA,EAAYb,SAASa,UAAU;YAC/BP,MAAAA,EAAQL,YAAAA;AACRS,YAAAA;AACF,SAAA,CAAA;AACF,IAAA,CAAA,CAAA;AACF,CAAA,CAAA;AAGF;;;AAGC,IACD,MAAMI,cAAAA,GAAiB,CAACjB,KAAAA,EAAckB,IAAAA,EAA2BjB,MAAAA,GAAAA;AAC/D,IAAA,OAAOkB,oCACL,OAAO,EAAEC,SAAS,EAAEC,KAAK,EAAE,GAAA;AACzB,QAAA,IAAI,CAACD,SAAAA,EAAW;AACd,YAAA;AACF,QAAA;AACA,QAAA,MAAME,wBAAwB1B,aAAAA,CAAcwB,SAAAA,CAAAA;QAC5C,MAAMG,QAAAA,GAAWzB,iBAAiBE,KAAAA,EAAOC,MAAAA,CAAAA;AAEzC,QAAA,OAAOuB,wBAAY,CAACrB,QAAAA,GAAAA;AAClB,YAAA,IAAI,CAACA,QAAAA,IAAY,CAACA,QAAAA,CAASa,UAAU,EAAE;gBACrC,OAAOb,QAAAA;AACT,YAAA;;;AAIA,YAAA,MAAMD,YAAYoB,qBAAAA,GAAwBnB,QAAAA,CAASsB,MAAM,GAAGL,UAAUM,MAAM;AAE5EH,YAAAA,QAAAA,CAASrB,SAAAA,EAAWC,QAAAA,CAAAA;;YAGpB,MAAMwB,QAAAA,GAAWxB,SAASwB,QAAQ;;AAGlC,YAAA,IAAIC,iBAAAA,GAAoB1B,SAAAA;YACxB,IAAIoB,qBAAAA,IAAyBK,UAAUF,MAAAA,EAAQ;AAC7CG,gBAAAA,iBAAAA,GAAoBD,SAASF,MAAM;AACrC,YAAA;AAEA,YAAA,IAAIE,UAAUE,MAAAA,EAAQ;AACpBN,gBAAAA,QAAAA,CAASK,iBAAAA,EAAmB;AAAE,oBAAA,GAAGzB,QAAQ;AAAE,oBAAA,GAAGwB,QAAQ;AAAEX,oBAAAA,UAAAA,EAAYW,SAASE;AAAO,iBAAA,CAAA;AACtF,YAAA;AAEA,YAAA,IAAIF,UAAUG,KAAAA,EAAO;AACnBP,gBAAAA,QAAAA,CAASK,iBAAAA,EAAmB;AAAE,oBAAA,GAAGzB,QAAQ;AAAE,oBAAA,GAAGwB,QAAQ;AAAEX,oBAAAA,UAAAA,EAAYW,SAASG;AAAM,iBAAA,CAAA;AACrF,YAAA;YAEA,OAAO3B,QAAAA;QACT,CAAA,EAAGkB,KAAAA,CAAAA;IACL,CAAA,EACA;AAAEU,QAAAA,MAAAA,EAAQC,MAAAA,CAAOC,QAAQ,CAAChC,MAAAA,CAAOM,GAAG,CAAA;AAAG0B,QAAAA,QAAAA,EAAUD,MAAAA,CAAOC,QAAQ,CAACC,IAAI,CAACF,MAAAA;KAAQ,EAC9Ed,IAAAA,CAAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"data-ids.js","sources":["../../../../../../src/services/document-service/transform/relations/extract/data-ids.ts"],"sourcesContent":["import { curry } from 'lodash/fp';\n\nimport type { UID } from '@strapi/types';\nimport { relations } from '@strapi/utils';\nimport { IdMap } from '../../id-map';\nimport { getRelationTargetLocale } from '../utils/i18n';\nimport { getRelationTargetStatus } from '../utils/dp';\nimport { mapRelation, traverseEntityRelations } from '../utils/map-relation';\nimport { normalizeXToOneRelationValue } from '../utils/xto-one';\nimport { LongHandDocument } from '../utils/types';\n\nconst { isPolymorphic } = relations;\n\ninterface Options {\n uid: UID.Schema;\n locale?: string | null;\n status?: 'draft' | 'published';\n}\n\n/**\n * Load a relation documentId into the idMap.\n */\nconst addRelationDocId = curry(\n (idMap: IdMap, source: Options, targetUid: UID.Schema, relation: LongHandDocument) => {\n const targetLocale = getRelationTargetLocale(relation, {\n targetUid,\n sourceUid: source.uid,\n sourceLocale: source.locale,\n });\n\n const targetStatus = getRelationTargetStatus(relation, {\n targetUid,\n sourceUid: source.uid,\n sourceStatus: source.status,\n });\n\n targetStatus.forEach((status) => {\n idMap.add({\n uid: targetUid,\n documentId: relation.documentId,\n locale: targetLocale,\n status,\n });\n });\n }\n);\n\n/**\n * Iterate over all relations of a data object and extract all relational document ids.\n * Those will later be transformed to entity ids.\n */\nconst extractDataIds = (idMap: IdMap, data: Record<string, any>, source: Options) => {\n return traverseEntityRelations(\n async ({ attribute, value }) => {\n if (!attribute) {\n return;\n }\n const isPolymorphicRelation = isPolymorphic(attribute);\n const addDocId = addRelationDocId(idMap, source);\n\n // Skip looking up entries we're about to discard.\n const normalizedValue = normalizeXToOneRelationValue(attribute, value as any);\n\n return mapRelation((relation) => {\n if (!relation || !relation.documentId) {\n return relation;\n }\n\n // Regular relations will always target the same target\n // if its a polymorphic relation we need to get it from the data itself\n const targetUid = isPolymorphicRelation ? relation.__type : attribute.target;\n\n addDocId(targetUid, relation);\n\n // Handle positional arguments\n const position = relation.position;\n\n // The positional relation target uid can be different for polymorphic relations\n let positionTargetUid = targetUid;\n if (isPolymorphicRelation && position?.__type) {\n positionTargetUid = position.__type;\n }\n\n if (position?.before) {\n addDocId(positionTargetUid, { ...relation, ...position, documentId: position.before });\n }\n\n if (position?.after) {\n addDocId(positionTargetUid, { ...relation, ...position, documentId: position.after });\n }\n\n return relation;\n }, normalizedValue as any);\n },\n { schema: strapi.getModel(source.uid), getModel: strapi.getModel.bind(strapi) },\n data\n );\n};\n\nexport { extractDataIds };\n"],"names":["isPolymorphic","relations","addRelationDocId","curry","idMap","source","targetUid","relation","targetLocale","getRelationTargetLocale","sourceUid","uid","sourceLocale","locale","targetStatus","getRelationTargetStatus","sourceStatus","status","forEach","add","documentId","extractDataIds","data","traverseEntityRelations","attribute","value","isPolymorphicRelation","addDocId","normalizedValue","normalizeXToOneRelationValue","mapRelation","__type","target","position","positionTargetUid","before","after","schema","strapi","getModel","bind"],"mappings":"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"}
@@ -3,6 +3,7 @@ import { relations } from '@strapi/utils';
3
3
  import { getRelationTargetLocale } from '../utils/i18n.mjs';
4
4
  import { getRelationTargetStatus } from '../utils/dp.mjs';
5
5
  import { traverseEntityRelations as traverseEntityRelationsCurried, mapRelation as mapRelationCurried } from '../utils/map-relation.mjs';
6
+ import { normalizeXToOneRelationValue } from '../utils/xto-one.mjs';
6
7
 
7
8
  const { isPolymorphic } = relations;
8
9
  /**
@@ -37,6 +38,8 @@ const { isPolymorphic } = relations;
37
38
  }
38
39
  const isPolymorphicRelation = isPolymorphic(attribute);
39
40
  const addDocId = addRelationDocId(idMap, source);
41
+ // Skip looking up entries we're about to discard.
42
+ const normalizedValue = normalizeXToOneRelationValue(attribute, value);
40
43
  return mapRelationCurried((relation)=>{
41
44
  if (!relation || !relation.documentId) {
42
45
  return relation;
@@ -67,7 +70,7 @@ const { isPolymorphic } = relations;
67
70
  });
68
71
  }
69
72
  return relation;
70
- }, value);
73
+ }, normalizedValue);
71
74
  }, {
72
75
  schema: strapi.getModel(source.uid),
73
76
  getModel: strapi.getModel.bind(strapi)
@@ -1 +1 @@
1
- {"version":3,"file":"data-ids.mjs","sources":["../../../../../../src/services/document-service/transform/relations/extract/data-ids.ts"],"sourcesContent":["import { curry } from 'lodash/fp';\n\nimport type { UID } from '@strapi/types';\nimport { relations } from '@strapi/utils';\nimport { IdMap } from '../../id-map';\nimport { getRelationTargetLocale } from '../utils/i18n';\nimport { getRelationTargetStatus } from '../utils/dp';\nimport { mapRelation, traverseEntityRelations } from '../utils/map-relation';\nimport { LongHandDocument } from '../utils/types';\n\nconst { isPolymorphic } = relations;\n\ninterface Options {\n uid: UID.Schema;\n locale?: string | null;\n status?: 'draft' | 'published';\n}\n\n/**\n * Load a relation documentId into the idMap.\n */\nconst addRelationDocId = curry(\n (idMap: IdMap, source: Options, targetUid: UID.Schema, relation: LongHandDocument) => {\n const targetLocale = getRelationTargetLocale(relation, {\n targetUid,\n sourceUid: source.uid,\n sourceLocale: source.locale,\n });\n\n const targetStatus = getRelationTargetStatus(relation, {\n targetUid,\n sourceUid: source.uid,\n sourceStatus: source.status,\n });\n\n targetStatus.forEach((status) => {\n idMap.add({\n uid: targetUid,\n documentId: relation.documentId,\n locale: targetLocale,\n status,\n });\n });\n }\n);\n\n/**\n * Iterate over all relations of a data object and extract all relational document ids.\n * Those will later be transformed to entity ids.\n */\nconst extractDataIds = (idMap: IdMap, data: Record<string, any>, source: Options) => {\n return traverseEntityRelations(\n async ({ attribute, value }) => {\n if (!attribute) {\n return;\n }\n const isPolymorphicRelation = isPolymorphic(attribute);\n const addDocId = addRelationDocId(idMap, source);\n\n return mapRelation((relation) => {\n if (!relation || !relation.documentId) {\n return relation;\n }\n\n // Regular relations will always target the same target\n // if its a polymorphic relation we need to get it from the data itself\n const targetUid = isPolymorphicRelation ? relation.__type : attribute.target;\n\n addDocId(targetUid, relation);\n\n // Handle positional arguments\n const position = relation.position;\n\n // The positional relation target uid can be different for polymorphic relations\n let positionTargetUid = targetUid;\n if (isPolymorphicRelation && position?.__type) {\n positionTargetUid = position.__type;\n }\n\n if (position?.before) {\n addDocId(positionTargetUid, { ...relation, ...position, documentId: position.before });\n }\n\n if (position?.after) {\n addDocId(positionTargetUid, { ...relation, ...position, documentId: position.after });\n }\n\n return relation;\n }, value as any);\n },\n { schema: strapi.getModel(source.uid), getModel: strapi.getModel.bind(strapi) },\n data\n );\n};\n\nexport { extractDataIds };\n"],"names":["isPolymorphic","relations","addRelationDocId","curry","idMap","source","targetUid","relation","targetLocale","getRelationTargetLocale","sourceUid","uid","sourceLocale","locale","targetStatus","getRelationTargetStatus","sourceStatus","status","forEach","add","documentId","extractDataIds","data","traverseEntityRelations","attribute","value","isPolymorphicRelation","addDocId","mapRelation","__type","target","position","positionTargetUid","before","after","schema","strapi","getModel","bind"],"mappings":";;;;;;AAUA,MAAM,EAAEA,aAAa,EAAE,GAAGC,SAAAA;AAQ1B;;AAEC,IACD,MAAMC,gBAAAA,GAAmBC,KAAAA,CACvB,CAACC,KAAAA,EAAcC,QAAiBC,SAAAA,EAAuBC,QAAAA,GAAAA;IACrD,MAAMC,YAAAA,GAAeC,wBAAwBF,QAAAA,EAAU;AACrDD,QAAAA,SAAAA;AACAI,QAAAA,SAAAA,EAAWL,OAAOM,GAAG;AACrBC,QAAAA,YAAAA,EAAcP,OAAOQ;AACvB,KAAA,CAAA;IAEA,MAAMC,YAAAA,GAAeC,wBAAwBR,QAAAA,EAAU;AACrDD,QAAAA,SAAAA;AACAI,QAAAA,SAAAA,EAAWL,OAAOM,GAAG;AACrBK,QAAAA,YAAAA,EAAcX,OAAOY;AACvB,KAAA,CAAA;IAEAH,YAAAA,CAAaI,OAAO,CAAC,CAACD,MAAAA,GAAAA;AACpBb,QAAAA,KAAAA,CAAMe,GAAG,CAAC;YACRR,GAAAA,EAAKL,SAAAA;AACLc,YAAAA,UAAAA,EAAYb,SAASa,UAAU;YAC/BP,MAAAA,EAAQL,YAAAA;AACRS,YAAAA;AACF,SAAA,CAAA;AACF,IAAA,CAAA,CAAA;AACF,CAAA,CAAA;AAGF;;;AAGC,IACD,MAAMI,cAAAA,GAAiB,CAACjB,KAAAA,EAAckB,IAAAA,EAA2BjB,MAAAA,GAAAA;AAC/D,IAAA,OAAOkB,+BACL,OAAO,EAAEC,SAAS,EAAEC,KAAK,EAAE,GAAA;AACzB,QAAA,IAAI,CAACD,SAAAA,EAAW;AACd,YAAA;AACF,QAAA;AACA,QAAA,MAAME,wBAAwB1B,aAAAA,CAAcwB,SAAAA,CAAAA;QAC5C,MAAMG,QAAAA,GAAWzB,iBAAiBE,KAAAA,EAAOC,MAAAA,CAAAA;AAEzC,QAAA,OAAOuB,mBAAY,CAACrB,QAAAA,GAAAA;AAClB,YAAA,IAAI,CAACA,QAAAA,IAAY,CAACA,QAAAA,CAASa,UAAU,EAAE;gBACrC,OAAOb,QAAAA;AACT,YAAA;;;AAIA,YAAA,MAAMD,YAAYoB,qBAAAA,GAAwBnB,QAAAA,CAASsB,MAAM,GAAGL,UAAUM,MAAM;AAE5EH,YAAAA,QAAAA,CAASrB,SAAAA,EAAWC,QAAAA,CAAAA;;YAGpB,MAAMwB,QAAAA,GAAWxB,SAASwB,QAAQ;;AAGlC,YAAA,IAAIC,iBAAAA,GAAoB1B,SAAAA;YACxB,IAAIoB,qBAAAA,IAAyBK,UAAUF,MAAAA,EAAQ;AAC7CG,gBAAAA,iBAAAA,GAAoBD,SAASF,MAAM;AACrC,YAAA;AAEA,YAAA,IAAIE,UAAUE,MAAAA,EAAQ;AACpBN,gBAAAA,QAAAA,CAASK,iBAAAA,EAAmB;AAAE,oBAAA,GAAGzB,QAAQ;AAAE,oBAAA,GAAGwB,QAAQ;AAAEX,oBAAAA,UAAAA,EAAYW,SAASE;AAAO,iBAAA,CAAA;AACtF,YAAA;AAEA,YAAA,IAAIF,UAAUG,KAAAA,EAAO;AACnBP,gBAAAA,QAAAA,CAASK,iBAAAA,EAAmB;AAAE,oBAAA,GAAGzB,QAAQ;AAAE,oBAAA,GAAGwB,QAAQ;AAAEX,oBAAAA,UAAAA,EAAYW,SAASG;AAAM,iBAAA,CAAA;AACrF,YAAA;YAEA,OAAO3B,QAAAA;QACT,CAAA,EAAGkB,KAAAA,CAAAA;IACL,CAAA,EACA;AAAEU,QAAAA,MAAAA,EAAQC,MAAAA,CAAOC,QAAQ,CAAChC,MAAAA,CAAOM,GAAG,CAAA;AAAG0B,QAAAA,QAAAA,EAAUD,MAAAA,CAAOC,QAAQ,CAACC,IAAI,CAACF,MAAAA;KAAQ,EAC9Ed,IAAAA,CAAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"data-ids.mjs","sources":["../../../../../../src/services/document-service/transform/relations/extract/data-ids.ts"],"sourcesContent":["import { curry } from 'lodash/fp';\n\nimport type { UID } from '@strapi/types';\nimport { relations } from '@strapi/utils';\nimport { IdMap } from '../../id-map';\nimport { getRelationTargetLocale } from '../utils/i18n';\nimport { getRelationTargetStatus } from '../utils/dp';\nimport { mapRelation, traverseEntityRelations } from '../utils/map-relation';\nimport { normalizeXToOneRelationValue } from '../utils/xto-one';\nimport { LongHandDocument } from '../utils/types';\n\nconst { isPolymorphic } = relations;\n\ninterface Options {\n uid: UID.Schema;\n locale?: string | null;\n status?: 'draft' | 'published';\n}\n\n/**\n * Load a relation documentId into the idMap.\n */\nconst addRelationDocId = curry(\n (idMap: IdMap, source: Options, targetUid: UID.Schema, relation: LongHandDocument) => {\n const targetLocale = getRelationTargetLocale(relation, {\n targetUid,\n sourceUid: source.uid,\n sourceLocale: source.locale,\n });\n\n const targetStatus = getRelationTargetStatus(relation, {\n targetUid,\n sourceUid: source.uid,\n sourceStatus: source.status,\n });\n\n targetStatus.forEach((status) => {\n idMap.add({\n uid: targetUid,\n documentId: relation.documentId,\n locale: targetLocale,\n status,\n });\n });\n }\n);\n\n/**\n * Iterate over all relations of a data object and extract all relational document ids.\n * Those will later be transformed to entity ids.\n */\nconst extractDataIds = (idMap: IdMap, data: Record<string, any>, source: Options) => {\n return traverseEntityRelations(\n async ({ attribute, value }) => {\n if (!attribute) {\n return;\n }\n const isPolymorphicRelation = isPolymorphic(attribute);\n const addDocId = addRelationDocId(idMap, source);\n\n // Skip looking up entries we're about to discard.\n const normalizedValue = normalizeXToOneRelationValue(attribute, value as any);\n\n return mapRelation((relation) => {\n if (!relation || !relation.documentId) {\n return relation;\n }\n\n // Regular relations will always target the same target\n // if its a polymorphic relation we need to get it from the data itself\n const targetUid = isPolymorphicRelation ? relation.__type : attribute.target;\n\n addDocId(targetUid, relation);\n\n // Handle positional arguments\n const position = relation.position;\n\n // The positional relation target uid can be different for polymorphic relations\n let positionTargetUid = targetUid;\n if (isPolymorphicRelation && position?.__type) {\n positionTargetUid = position.__type;\n }\n\n if (position?.before) {\n addDocId(positionTargetUid, { ...relation, ...position, documentId: position.before });\n }\n\n if (position?.after) {\n addDocId(positionTargetUid, { ...relation, ...position, documentId: position.after });\n }\n\n return relation;\n }, normalizedValue as any);\n },\n { schema: strapi.getModel(source.uid), getModel: strapi.getModel.bind(strapi) },\n data\n );\n};\n\nexport { extractDataIds };\n"],"names":["isPolymorphic","relations","addRelationDocId","curry","idMap","source","targetUid","relation","targetLocale","getRelationTargetLocale","sourceUid","uid","sourceLocale","locale","targetStatus","getRelationTargetStatus","sourceStatus","status","forEach","add","documentId","extractDataIds","data","traverseEntityRelations","attribute","value","isPolymorphicRelation","addDocId","normalizedValue","normalizeXToOneRelationValue","mapRelation","__type","target","position","positionTargetUid","before","after","schema","strapi","getModel","bind"],"mappings":";;;;;;;AAWA,MAAM,EAAEA,aAAa,EAAE,GAAGC,SAAAA;AAQ1B;;AAEC,IACD,MAAMC,gBAAAA,GAAmBC,KAAAA,CACvB,CAACC,KAAAA,EAAcC,QAAiBC,SAAAA,EAAuBC,QAAAA,GAAAA;IACrD,MAAMC,YAAAA,GAAeC,wBAAwBF,QAAAA,EAAU;AACrDD,QAAAA,SAAAA;AACAI,QAAAA,SAAAA,EAAWL,OAAOM,GAAG;AACrBC,QAAAA,YAAAA,EAAcP,OAAOQ;AACvB,KAAA,CAAA;IAEA,MAAMC,YAAAA,GAAeC,wBAAwBR,QAAAA,EAAU;AACrDD,QAAAA,SAAAA;AACAI,QAAAA,SAAAA,EAAWL,OAAOM,GAAG;AACrBK,QAAAA,YAAAA,EAAcX,OAAOY;AACvB,KAAA,CAAA;IAEAH,YAAAA,CAAaI,OAAO,CAAC,CAACD,MAAAA,GAAAA;AACpBb,QAAAA,KAAAA,CAAMe,GAAG,CAAC;YACRR,GAAAA,EAAKL,SAAAA;AACLc,YAAAA,UAAAA,EAAYb,SAASa,UAAU;YAC/BP,MAAAA,EAAQL,YAAAA;AACRS,YAAAA;AACF,SAAA,CAAA;AACF,IAAA,CAAA,CAAA;AACF,CAAA,CAAA;AAGF;;;AAGC,IACD,MAAMI,cAAAA,GAAiB,CAACjB,KAAAA,EAAckB,IAAAA,EAA2BjB,MAAAA,GAAAA;AAC/D,IAAA,OAAOkB,+BACL,OAAO,EAAEC,SAAS,EAAEC,KAAK,EAAE,GAAA;AACzB,QAAA,IAAI,CAACD,SAAAA,EAAW;AACd,YAAA;AACF,QAAA;AACA,QAAA,MAAME,wBAAwB1B,aAAAA,CAAcwB,SAAAA,CAAAA;QAC5C,MAAMG,QAAAA,GAAWzB,iBAAiBE,KAAAA,EAAOC,MAAAA,CAAAA;;QAGzC,MAAMuB,eAAAA,GAAkBC,6BAA6BL,SAAAA,EAAWC,KAAAA,CAAAA;AAEhE,QAAA,OAAOK,mBAAY,CAACvB,QAAAA,GAAAA;AAClB,YAAA,IAAI,CAACA,QAAAA,IAAY,CAACA,QAAAA,CAASa,UAAU,EAAE;gBACrC,OAAOb,QAAAA;AACT,YAAA;;;AAIA,YAAA,MAAMD,YAAYoB,qBAAAA,GAAwBnB,QAAAA,CAASwB,MAAM,GAAGP,UAAUQ,MAAM;AAE5EL,YAAAA,QAAAA,CAASrB,SAAAA,EAAWC,QAAAA,CAAAA;;YAGpB,MAAM0B,QAAAA,GAAW1B,SAAS0B,QAAQ;;AAGlC,YAAA,IAAIC,iBAAAA,GAAoB5B,SAAAA;YACxB,IAAIoB,qBAAAA,IAAyBO,UAAUF,MAAAA,EAAQ;AAC7CG,gBAAAA,iBAAAA,GAAoBD,SAASF,MAAM;AACrC,YAAA;AAEA,YAAA,IAAIE,UAAUE,MAAAA,EAAQ;AACpBR,gBAAAA,QAAAA,CAASO,iBAAAA,EAAmB;AAAE,oBAAA,GAAG3B,QAAQ;AAAE,oBAAA,GAAG0B,QAAQ;AAAEb,oBAAAA,UAAAA,EAAYa,SAASE;AAAO,iBAAA,CAAA;AACtF,YAAA;AAEA,YAAA,IAAIF,UAAUG,KAAAA,EAAO;AACnBT,gBAAAA,QAAAA,CAASO,iBAAAA,EAAmB;AAAE,oBAAA,GAAG3B,QAAQ;AAAE,oBAAA,GAAG0B,QAAQ;AAAEb,oBAAAA,UAAAA,EAAYa,SAASG;AAAM,iBAAA,CAAA;AACrF,YAAA;YAEA,OAAO7B,QAAAA;QACT,CAAA,EAAGqB,eAAAA,CAAAA;IACL,CAAA,EACA;AAAES,QAAAA,MAAAA,EAAQC,MAAAA,CAAOC,QAAQ,CAAClC,MAAAA,CAAOM,GAAG,CAAA;AAAG4B,QAAAA,QAAAA,EAAUD,MAAAA,CAAOC,QAAQ,CAACC,IAAI,CAACF,MAAAA;KAAQ,EAC9EhB,IAAAA,CAAAA;AAEJ;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"data-ids.d.ts","sourceRoot":"","sources":["../../../../../../src/services/document-service/transform/relations/transform/data-ids.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAIzC,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAOrC,UAAU,OAAO;IACf,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,GAAG,WAAW,CAAC;IAC/B,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AA+CD;;GAEG;AACH,QAAA,MAAM,uBAAuB,UAAW,KAAK,QAAQ,OAAO,MAAM,EAAE,GAAG,CAAC,UAAU,OAAO,qDA8DxF,CAAC;AAEF,OAAO,EAAE,uBAAuB,EAAE,CAAC"}
1
+ {"version":3,"file":"data-ids.d.ts","sourceRoot":"","sources":["../../../../../../src/services/document-service/transform/relations/transform/data-ids.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAIzC,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAQrC,UAAU,OAAO;IACf,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,GAAG,WAAW,CAAC;IAC/B,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AA+CD;;GAEG;AACH,QAAA,MAAM,uBAAuB,UAAW,KAAK,QAAQ,OAAO,MAAM,EAAE,GAAG,CAAC,UAAU,OAAO,qDAiExF,CAAC;AAEF,OAAO,EAAE,uBAAuB,EAAE,CAAC"}
@@ -5,6 +5,7 @@ var strapiUtils = require('@strapi/utils');
5
5
  var i18n = require('../utils/i18n.js');
6
6
  var dp = require('../utils/dp.js');
7
7
  var mapRelation = require('../utils/map-relation.js');
8
+ var xtoOne = require('../utils/xto-one.js');
8
9
 
9
10
  const { isPolymorphic } = strapiUtils.relations;
10
11
  /**
@@ -49,6 +50,8 @@ const { isPolymorphic } = strapiUtils.relations;
49
50
  }
50
51
  const isPolymorphicRelation = isPolymorphic(attribute);
51
52
  const getIds = getRelationIds(idMap, source);
53
+ // Collapse a "relates to one" payload to a single entry first.
54
+ const normalizedValue = xtoOne.normalizeXToOneRelationValue(attribute, value);
52
55
  // Transform the relation documentId to entity id
53
56
  const newRelation = await mapRelation.mapRelation((relation)=>{
54
57
  if (!relation || !relation.documentId) {
@@ -98,7 +101,7 @@ const { isPolymorphic } = strapiUtils.relations;
98
101
  }
99
102
  return newRelation;
100
103
  });
101
- }, value);
104
+ }, normalizedValue);
102
105
  set(key, newRelation);
103
106
  }, {
104
107
  schema: strapi.getModel(source.uid),