@strapi/core 5.52.3 → 5.54.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 (116) hide show
  1. package/dist/container.d.ts +1 -0
  2. package/dist/container.d.ts.map +1 -1
  3. package/dist/container.js +3 -0
  4. package/dist/container.js.map +1 -1
  5. package/dist/container.mjs +3 -0
  6. package/dist/container.mjs.map +1 -1
  7. package/dist/core-api/controller/single-type.d.ts.map +1 -1
  8. package/dist/core-api/controller/single-type.js +7 -4
  9. package/dist/core-api/controller/single-type.js.map +1 -1
  10. package/dist/core-api/controller/single-type.mjs +7 -4
  11. package/dist/core-api/controller/single-type.mjs.map +1 -1
  12. package/dist/domain/content-type/index.d.ts.map +1 -1
  13. package/dist/domain/content-type/index.js +3 -1
  14. package/dist/domain/content-type/index.js.map +1 -1
  15. package/dist/domain/content-type/index.mjs +3 -1
  16. package/dist/domain/content-type/index.mjs.map +1 -1
  17. package/dist/package.json.js +20 -17
  18. package/dist/package.json.js.map +1 -1
  19. package/dist/package.json.mjs +20 -17
  20. package/dist/package.json.mjs.map +1 -1
  21. package/dist/services/content-source-maps.d.ts +14 -2
  22. package/dist/services/content-source-maps.d.ts.map +1 -1
  23. package/dist/services/content-source-maps.js +134 -1
  24. package/dist/services/content-source-maps.js.map +1 -1
  25. package/dist/services/content-source-maps.mjs +134 -2
  26. package/dist/services/content-source-maps.mjs.map +1 -1
  27. package/dist/services/cron.d.ts +3 -18
  28. package/dist/services/cron.d.ts.map +1 -1
  29. package/dist/services/cron.js +241 -33
  30. package/dist/services/cron.js.map +1 -1
  31. package/dist/services/cron.mjs +241 -33
  32. package/dist/services/cron.mjs.map +1 -1
  33. package/dist/services/document-service/transform/query.d.ts.map +1 -1
  34. package/dist/services/document-service/transform/query.js +4 -2
  35. package/dist/services/document-service/transform/query.js.map +1 -1
  36. package/dist/services/document-service/transform/query.mjs +4 -2
  37. package/dist/services/document-service/transform/query.mjs.map +1 -1
  38. package/dist/services/document-service/transform/relations/extract/data-ids.d.ts +1 -1
  39. package/dist/services/document-service/transform/relations/extract/data-ids.d.ts.map +1 -1
  40. package/dist/services/document-service/transform/relations/extract/data-ids.js +12 -3
  41. package/dist/services/document-service/transform/relations/extract/data-ids.js.map +1 -1
  42. package/dist/services/document-service/transform/relations/extract/data-ids.mjs +12 -3
  43. package/dist/services/document-service/transform/relations/extract/data-ids.mjs.map +1 -1
  44. package/dist/services/document-service/transform/relations/transform/data-ids.d.ts +1 -1
  45. package/dist/services/document-service/transform/relations/transform/data-ids.d.ts.map +1 -1
  46. package/dist/services/document-service/transform/relations/transform/data-ids.js +12 -3
  47. package/dist/services/document-service/transform/relations/transform/data-ids.js.map +1 -1
  48. package/dist/services/document-service/transform/relations/transform/data-ids.mjs +12 -3
  49. package/dist/services/document-service/transform/relations/transform/data-ids.mjs.map +1 -1
  50. package/dist/services/document-service/transform/relations/utils/map-relation.d.ts +6 -1
  51. package/dist/services/document-service/transform/relations/utils/map-relation.d.ts.map +1 -1
  52. package/dist/services/document-service/transform/relations/utils/map-relation.js +13 -10
  53. package/dist/services/document-service/transform/relations/utils/map-relation.js.map +1 -1
  54. package/dist/services/document-service/transform/relations/utils/map-relation.mjs +13 -10
  55. package/dist/services/document-service/transform/relations/utils/map-relation.mjs.map +1 -1
  56. package/dist/services/entity-validator/blocks-validator.d.ts.map +1 -1
  57. package/dist/services/entity-validator/blocks-validator.js +9 -3
  58. package/dist/services/entity-validator/blocks-validator.js.map +1 -1
  59. package/dist/services/entity-validator/blocks-validator.mjs +9 -3
  60. package/dist/services/entity-validator/blocks-validator.mjs.map +1 -1
  61. package/dist/services/features.d.ts.map +1 -1
  62. package/dist/services/features.js +3 -0
  63. package/dist/services/features.js.map +1 -1
  64. package/dist/services/features.mjs +3 -0
  65. package/dist/services/features.mjs.map +1 -1
  66. package/dist/services/mcp/handlers/handlePost.d.ts.map +1 -1
  67. package/dist/services/mcp/handlers/handlePost.js +2 -3
  68. package/dist/services/mcp/handlers/handlePost.js.map +1 -1
  69. package/dist/services/mcp/handlers/handlePost.mjs +2 -3
  70. package/dist/services/mcp/handlers/handlePost.mjs.map +1 -1
  71. package/dist/services/mcp/internal/McpCapabilityRegistry.d.ts +1 -1
  72. package/dist/services/mcp/internal/McpCapabilityRegistry.d.ts.map +1 -1
  73. package/dist/services/mcp/internal/McpCapabilityRegistry.js.map +1 -1
  74. package/dist/services/mcp/internal/McpCapabilityRegistry.mjs.map +1 -1
  75. package/dist/services/mcp/internal/McpServerFactory.d.ts +1 -1
  76. package/dist/services/mcp/internal/McpServerFactory.d.ts.map +1 -1
  77. package/dist/services/mcp/internal/McpServerFactory.js +2 -3
  78. package/dist/services/mcp/internal/McpServerFactory.js.map +1 -1
  79. package/dist/services/mcp/internal/McpServerFactory.mjs +1 -2
  80. package/dist/services/mcp/internal/McpServerFactory.mjs.map +1 -1
  81. package/dist/services/mcp/prompt-registry.d.ts +1 -1
  82. package/dist/services/mcp/prompt-registry.d.ts.map +1 -1
  83. package/dist/services/mcp/prompt-registry.js +18 -4
  84. package/dist/services/mcp/prompt-registry.js.map +1 -1
  85. package/dist/services/mcp/prompt-registry.mjs +18 -4
  86. package/dist/services/mcp/prompt-registry.mjs.map +1 -1
  87. package/dist/services/mcp/resource-registry.d.ts +1 -1
  88. package/dist/services/mcp/resource-registry.d.ts.map +1 -1
  89. package/dist/services/mcp/resource-registry.js +4 -2
  90. package/dist/services/mcp/resource-registry.js.map +1 -1
  91. package/dist/services/mcp/resource-registry.mjs +4 -2
  92. package/dist/services/mcp/resource-registry.mjs.map +1 -1
  93. package/dist/services/mcp/tool-registry.d.ts +1 -1
  94. package/dist/services/mcp/tool-registry.d.ts.map +1 -1
  95. package/dist/services/mcp/tool-registry.js +18 -11
  96. package/dist/services/mcp/tool-registry.js.map +1 -1
  97. package/dist/services/mcp/tool-registry.mjs +18 -11
  98. package/dist/services/mcp/tool-registry.mjs.map +1 -1
  99. package/dist/services/mcp/utils/createMcpCapabilityHandlerContext.d.ts +7 -0
  100. package/dist/services/mcp/utils/createMcpCapabilityHandlerContext.d.ts.map +1 -0
  101. package/dist/services/mcp/utils/createMcpCapabilityHandlerContext.js +29 -0
  102. package/dist/services/mcp/utils/createMcpCapabilityHandlerContext.js.map +1 -0
  103. package/dist/services/mcp/utils/createMcpCapabilityHandlerContext.mjs +27 -0
  104. package/dist/services/mcp/utils/createMcpCapabilityHandlerContext.mjs.map +1 -0
  105. package/dist/services/mcp/utils/toSdkMcpCapabilityResult.d.ts +18 -0
  106. package/dist/services/mcp/utils/toSdkMcpCapabilityResult.d.ts.map +1 -0
  107. package/dist/services/mcp/utils/toSdkMcpCapabilityResult.js +137 -0
  108. package/dist/services/mcp/utils/toSdkMcpCapabilityResult.js.map +1 -0
  109. package/dist/services/mcp/utils/toSdkMcpCapabilityResult.mjs +131 -0
  110. package/dist/services/mcp/utils/toSdkMcpCapabilityResult.mjs.map +1 -0
  111. package/dist/services/session-manager.d.ts.map +1 -1
  112. package/dist/services/session-manager.js +5 -0
  113. package/dist/services/session-manager.js.map +1 -1
  114. package/dist/services/session-manager.mjs +5 -0
  115. package/dist/services/session-manager.mjs.map +1 -1
  116. package/package.json +20 -17
@@ -34,9 +34,124 @@ const EXCLUDED_FIELDS = [
34
34
  const isObject = (value)=>{
35
35
  return typeof value === 'object' && value !== null;
36
36
  };
37
+ const blocksFieldMetadata = (metadata)=>({
38
+ ...metadata,
39
+ path: metadata.fieldPath,
40
+ type: 'blocks'
41
+ });
42
+ /**
43
+ * Walk a subtree depth-first and stega-encode the first `{ type: 'text', text }` leaf only.
44
+ */ const encodeFirstTextLeaf = (node, metadata, encodeField)=>{
45
+ if (!isObject(node)) {
46
+ return {
47
+ node,
48
+ encoded: false
49
+ };
50
+ }
51
+ if (node.type === 'text' && typeof node.text === 'string') {
52
+ return {
53
+ node: {
54
+ ...node,
55
+ text: encodeField(node.text, blocksFieldMetadata(metadata))
56
+ },
57
+ encoded: true
58
+ };
59
+ }
60
+ if (Array.isArray(node.children)) {
61
+ let encoded = false;
62
+ const children = node.children.map((child)=>{
63
+ if (encoded) {
64
+ return child;
65
+ }
66
+ const result = encodeFirstTextLeaf(child, metadata, encodeField);
67
+ encoded = result.encoded;
68
+ return result.node;
69
+ });
70
+ return {
71
+ node: {
72
+ ...node,
73
+ children
74
+ },
75
+ encoded
76
+ };
77
+ }
78
+ return {
79
+ node,
80
+ encoded: false
81
+ };
82
+ };
83
+ const encodeListBlock = (listNode, metadata, encodeField)=>{
84
+ const children = listNode.children.map((child)=>{
85
+ if (!isObject(child)) {
86
+ return child;
87
+ }
88
+ if (child.type === 'list-item') {
89
+ return encodeFirstTextLeaf(child, metadata, encodeField).node;
90
+ }
91
+ if (child.type === 'list') {
92
+ return encodeListBlock(child, metadata, encodeField);
93
+ }
94
+ return child;
95
+ });
96
+ return {
97
+ ...listNode,
98
+ children
99
+ };
100
+ };
101
+ const encodeImageBlock = (imageNode, metadata, encodeField)=>{
102
+ if (!isObject(imageNode.image)) {
103
+ return imageNode;
104
+ }
105
+ const { alternativeText } = imageNode.image;
106
+ // Encode the alt text (not the URL). Encoding the URL corrupts the src attribute and can
107
+ // cause the preview highlight to expand across the entire page. The alt attribute is a
108
+ // safe target: it's visible to the previewScript via getAttribute and never used as a URL.
109
+ // Only encode when alternativeText is a non-empty string — images with no alt text get
110
+ // no stega marker and won't independently trigger the highlight, but the blocks field
111
+ // as a whole remains highlightable via its other (text) blocks.
112
+ if (typeof alternativeText !== 'string' || alternativeText.length === 0) {
113
+ return imageNode;
114
+ }
115
+ return {
116
+ ...imageNode,
117
+ image: {
118
+ ...imageNode.image,
119
+ alternativeText: encodeField(alternativeText, blocksFieldMetadata(metadata))
120
+ }
121
+ };
122
+ };
123
+ /**
124
+ * Pure transformation over a blocks AST. Injects one stega marker per visual block
125
+ * (first text leaf, or image alt text) using the blocks field path for all markers.
126
+ * Code blocks are skipped entirely.
127
+ */ const encodeBlocks = (blocks, metadata, encodeField)=>{
128
+ if (!Array.isArray(blocks)) {
129
+ return blocks;
130
+ }
131
+ return blocks.map((block)=>{
132
+ if (!isObject(block)) {
133
+ return block;
134
+ }
135
+ switch(block.type){
136
+ case 'code':
137
+ // Skip encoding — encoding code content would corrupt the syntax.
138
+ return block;
139
+ case 'image':
140
+ return encodeImageBlock(block, metadata, encodeField);
141
+ case 'list':
142
+ return encodeListBlock(block, metadata, encodeField);
143
+ case 'paragraph':
144
+ case 'heading':
145
+ case 'quote':
146
+ return encodeFirstTextLeaf(block, metadata, encodeField).node;
147
+ default:
148
+ return block;
149
+ }
150
+ });
151
+ };
37
152
  const createContentSourceMapsService = (strapi)=>{
38
153
  return {
39
- encodeField (text, { kind, model, documentId, type, path, locale }) {
154
+ encodeField (text, { kind, model, documentId, type, path, locale, fieldPath }) {
40
155
  /**
41
156
  * Combine all metadata into into a one string so we only have to deal with one data-atribute
42
157
  * on the frontend. Make it human readable because that data-attribute may be set manually by
@@ -54,11 +169,17 @@ const createContentSourceMapsService = (strapi)=>{
54
169
  if (locale) {
55
170
  strapiSource.set('locale', locale);
56
171
  }
172
+ if (fieldPath) {
173
+ strapiSource.set('fieldPath', fieldPath);
174
+ }
57
175
  const encoded = stega.vercelStegaCombine(text, {
58
176
  strapiSource: strapiSource.toString()
59
177
  }, false);
60
178
  return encoded;
61
179
  },
180
+ encodeBlocks (blocks, metadata) {
181
+ return encodeBlocks(blocks, metadata, this.encodeField.bind(this));
182
+ },
62
183
  async encodeEntry ({ data, schema }) {
63
184
  if (!isObject(data) || data === undefined) {
64
185
  return data;
@@ -67,6 +188,17 @@ const createContentSourceMapsService = (strapi)=>{
67
188
  if (!attribute || EXCLUDED_FIELDS.includes(key)) {
68
189
  return;
69
190
  }
191
+ if (attribute.type === 'blocks' && Array.isArray(value)) {
192
+ const fieldPath = path.rawWithIndices;
193
+ set(key, this.encodeBlocks(value, {
194
+ fieldPath,
195
+ kind: schema.kind,
196
+ model: schema.uid,
197
+ locale: data.locale,
198
+ documentId: data.documentId
199
+ }));
200
+ return;
201
+ }
70
202
  if (ENCODABLE_TYPES.includes(attribute.type) && typeof value === 'string') {
71
203
  // For inner fields of a multi-media field's items (e.g. `medias.0.url`),
72
204
  // drop the array index so all items share the same encoded path. The
@@ -113,4 +245,5 @@ const createContentSourceMapsService = (strapi)=>{
113
245
  };
114
246
 
115
247
  exports.createContentSourceMapsService = createContentSourceMapsService;
248
+ exports.encodeBlocks = encodeBlocks;
116
249
  //# sourceMappingURL=content-source-maps.js.map
@@ -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 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
+ {"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 * - integer, float and decimal: number\n * - boolean: boolean (believe it or not)\n * - uid: can be stringified but would mess up URLs\n *\n * The blocks type is an array of nodes — handled in a dedicated branch below\n * because it requires walking the AST to encode the first text leaf of each visual block.\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\ntype BlocksEncodeMetadata = Omit<FieldContentSourceMap, 'path' | 'type'> & { fieldPath: string };\n\ntype EncodeFieldFn = (text: string, metadata: FieldContentSourceMap) => string;\n\nconst isObject = (value: unknown): value is Record<string, any> => {\n return typeof value === 'object' && value !== null;\n};\n\nconst blocksFieldMetadata = (metadata: BlocksEncodeMetadata): FieldContentSourceMap => ({\n ...metadata,\n path: metadata.fieldPath,\n type: 'blocks',\n});\n\n/**\n * Walk a subtree depth-first and stega-encode the first `{ type: 'text', text }` leaf only.\n */\nconst encodeFirstTextLeaf = (\n node: unknown,\n metadata: BlocksEncodeMetadata,\n encodeField: EncodeFieldFn\n): { node: unknown; encoded: boolean } => {\n if (!isObject(node)) {\n return { node, encoded: false };\n }\n\n if (node.type === 'text' && typeof node.text === 'string') {\n return {\n node: {\n ...node,\n text: encodeField(node.text, blocksFieldMetadata(metadata)),\n },\n encoded: true,\n };\n }\n\n if (Array.isArray(node.children)) {\n let encoded = false;\n const children = node.children.map((child) => {\n if (encoded) {\n return child;\n }\n\n const result = encodeFirstTextLeaf(child, metadata, encodeField);\n encoded = result.encoded;\n return result.node;\n });\n\n return {\n node: { ...node, children },\n encoded,\n };\n }\n\n return { node, encoded: false };\n};\n\nconst encodeListBlock = (\n listNode: Record<string, unknown>,\n metadata: BlocksEncodeMetadata,\n encodeField: EncodeFieldFn\n): Record<string, unknown> => {\n const children = (listNode.children as unknown[]).map((child) => {\n if (!isObject(child)) {\n return child;\n }\n\n if (child.type === 'list-item') {\n return encodeFirstTextLeaf(child, metadata, encodeField).node;\n }\n\n if (child.type === 'list') {\n return encodeListBlock(child, metadata, encodeField);\n }\n\n return child;\n });\n\n return { ...listNode, children };\n};\n\nconst encodeImageBlock = (\n imageNode: Record<string, unknown>,\n metadata: BlocksEncodeMetadata,\n encodeField: EncodeFieldFn\n): Record<string, unknown> => {\n if (!isObject(imageNode.image)) {\n return imageNode;\n }\n\n const { alternativeText } = imageNode.image as Record<string, unknown>;\n // Encode the alt text (not the URL). Encoding the URL corrupts the src attribute and can\n // cause the preview highlight to expand across the entire page. The alt attribute is a\n // safe target: it's visible to the previewScript via getAttribute and never used as a URL.\n // Only encode when alternativeText is a non-empty string — images with no alt text get\n // no stega marker and won't independently trigger the highlight, but the blocks field\n // as a whole remains highlightable via its other (text) blocks.\n if (typeof alternativeText !== 'string' || alternativeText.length === 0) {\n return imageNode;\n }\n\n return {\n ...imageNode,\n image: {\n ...(imageNode.image as Record<string, unknown>),\n alternativeText: encodeField(alternativeText, blocksFieldMetadata(metadata)),\n },\n };\n};\n\n/**\n * Pure transformation over a blocks AST. Injects one stega marker per visual block\n * (first text leaf, or image alt text) using the blocks field path for all markers.\n * Code blocks are skipped entirely.\n */\nconst encodeBlocks = (\n blocks: unknown,\n metadata: BlocksEncodeMetadata,\n encodeField: EncodeFieldFn\n): unknown => {\n if (!Array.isArray(blocks)) {\n return blocks;\n }\n\n return blocks.map((block) => {\n if (!isObject(block)) {\n return block;\n }\n\n switch (block.type) {\n case 'code':\n // Skip encoding — encoding code content would corrupt the syntax.\n return block;\n case 'image':\n return encodeImageBlock(block, metadata, encodeField);\n case 'list':\n return encodeListBlock(block, metadata, encodeField);\n case 'paragraph':\n case 'heading':\n case 'quote':\n return encodeFirstTextLeaf(block, metadata, encodeField).node;\n default:\n return block;\n }\n });\n};\n\nconst createContentSourceMapsService = (strapi: Core.Strapi) => {\n return {\n encodeField(\n text: string,\n { kind, model, documentId, type, path, locale, fieldPath }: 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 if (fieldPath) {\n strapiSource.set('fieldPath', fieldPath);\n }\n\n const encoded = vercelStegaCombine(\n text,\n {\n strapiSource: strapiSource.toString(),\n },\n false\n );\n\n return encoded;\n },\n\n encodeBlocks(blocks: unknown, metadata: BlocksEncodeMetadata): unknown {\n return encodeBlocks(blocks, metadata, this.encodeField.bind(this));\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 (attribute.type === 'blocks' && Array.isArray(value)) {\n const fieldPath = path.rawWithIndices!;\n set(\n key,\n this.encodeBlocks(value, {\n fieldPath,\n kind: schema.kind,\n model: schema.uid as UID.Schema,\n locale: data.locale,\n documentId: data.documentId,\n }) as any\n );\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, encodeBlocks };\nexport type { BlocksEncodeMetadata, EncodeFieldFn };\n"],"names":["ENCODABLE_TYPES","EXCLUDED_FIELDS","isObject","value","blocksFieldMetadata","metadata","path","fieldPath","type","encodeFirstTextLeaf","node","encodeField","encoded","text","Array","isArray","children","map","child","result","encodeListBlock","listNode","encodeImageBlock","imageNode","image","alternativeText","length","encodeBlocks","blocks","block","createContentSourceMapsService","strapi","kind","model","documentId","locale","strapiSource","URLSearchParams","set","vercelStegaCombine","toString","bind","encodeEntry","data","schema","undefined","traverseEntity","key","attribute","parent","includes","rawWithIndices","uid","parentAttr","isInsideMultiMedia","multiple","encodedPath","getModel","encodeSourceMaps","Promise","all","item","error","log"],"mappings":"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"}
@@ -32,9 +32,124 @@ const EXCLUDED_FIELDS = [
32
32
  const isObject = (value)=>{
33
33
  return typeof value === 'object' && value !== null;
34
34
  };
35
+ const blocksFieldMetadata = (metadata)=>({
36
+ ...metadata,
37
+ path: metadata.fieldPath,
38
+ type: 'blocks'
39
+ });
40
+ /**
41
+ * Walk a subtree depth-first and stega-encode the first `{ type: 'text', text }` leaf only.
42
+ */ const encodeFirstTextLeaf = (node, metadata, encodeField)=>{
43
+ if (!isObject(node)) {
44
+ return {
45
+ node,
46
+ encoded: false
47
+ };
48
+ }
49
+ if (node.type === 'text' && typeof node.text === 'string') {
50
+ return {
51
+ node: {
52
+ ...node,
53
+ text: encodeField(node.text, blocksFieldMetadata(metadata))
54
+ },
55
+ encoded: true
56
+ };
57
+ }
58
+ if (Array.isArray(node.children)) {
59
+ let encoded = false;
60
+ const children = node.children.map((child)=>{
61
+ if (encoded) {
62
+ return child;
63
+ }
64
+ const result = encodeFirstTextLeaf(child, metadata, encodeField);
65
+ encoded = result.encoded;
66
+ return result.node;
67
+ });
68
+ return {
69
+ node: {
70
+ ...node,
71
+ children
72
+ },
73
+ encoded
74
+ };
75
+ }
76
+ return {
77
+ node,
78
+ encoded: false
79
+ };
80
+ };
81
+ const encodeListBlock = (listNode, metadata, encodeField)=>{
82
+ const children = listNode.children.map((child)=>{
83
+ if (!isObject(child)) {
84
+ return child;
85
+ }
86
+ if (child.type === 'list-item') {
87
+ return encodeFirstTextLeaf(child, metadata, encodeField).node;
88
+ }
89
+ if (child.type === 'list') {
90
+ return encodeListBlock(child, metadata, encodeField);
91
+ }
92
+ return child;
93
+ });
94
+ return {
95
+ ...listNode,
96
+ children
97
+ };
98
+ };
99
+ const encodeImageBlock = (imageNode, metadata, encodeField)=>{
100
+ if (!isObject(imageNode.image)) {
101
+ return imageNode;
102
+ }
103
+ const { alternativeText } = imageNode.image;
104
+ // Encode the alt text (not the URL). Encoding the URL corrupts the src attribute and can
105
+ // cause the preview highlight to expand across the entire page. The alt attribute is a
106
+ // safe target: it's visible to the previewScript via getAttribute and never used as a URL.
107
+ // Only encode when alternativeText is a non-empty string — images with no alt text get
108
+ // no stega marker and won't independently trigger the highlight, but the blocks field
109
+ // as a whole remains highlightable via its other (text) blocks.
110
+ if (typeof alternativeText !== 'string' || alternativeText.length === 0) {
111
+ return imageNode;
112
+ }
113
+ return {
114
+ ...imageNode,
115
+ image: {
116
+ ...imageNode.image,
117
+ alternativeText: encodeField(alternativeText, blocksFieldMetadata(metadata))
118
+ }
119
+ };
120
+ };
121
+ /**
122
+ * Pure transformation over a blocks AST. Injects one stega marker per visual block
123
+ * (first text leaf, or image alt text) using the blocks field path for all markers.
124
+ * Code blocks are skipped entirely.
125
+ */ const encodeBlocks = (blocks, metadata, encodeField)=>{
126
+ if (!Array.isArray(blocks)) {
127
+ return blocks;
128
+ }
129
+ return blocks.map((block)=>{
130
+ if (!isObject(block)) {
131
+ return block;
132
+ }
133
+ switch(block.type){
134
+ case 'code':
135
+ // Skip encoding — encoding code content would corrupt the syntax.
136
+ return block;
137
+ case 'image':
138
+ return encodeImageBlock(block, metadata, encodeField);
139
+ case 'list':
140
+ return encodeListBlock(block, metadata, encodeField);
141
+ case 'paragraph':
142
+ case 'heading':
143
+ case 'quote':
144
+ return encodeFirstTextLeaf(block, metadata, encodeField).node;
145
+ default:
146
+ return block;
147
+ }
148
+ });
149
+ };
35
150
  const createContentSourceMapsService = (strapi)=>{
36
151
  return {
37
- encodeField (text, { kind, model, documentId, type, path, locale }) {
152
+ encodeField (text, { kind, model, documentId, type, path, locale, fieldPath }) {
38
153
  /**
39
154
  * Combine all metadata into into a one string so we only have to deal with one data-atribute
40
155
  * on the frontend. Make it human readable because that data-attribute may be set manually by
@@ -52,11 +167,17 @@ const createContentSourceMapsService = (strapi)=>{
52
167
  if (locale) {
53
168
  strapiSource.set('locale', locale);
54
169
  }
170
+ if (fieldPath) {
171
+ strapiSource.set('fieldPath', fieldPath);
172
+ }
55
173
  const encoded = vercelStegaCombine(text, {
56
174
  strapiSource: strapiSource.toString()
57
175
  }, false);
58
176
  return encoded;
59
177
  },
178
+ encodeBlocks (blocks, metadata) {
179
+ return encodeBlocks(blocks, metadata, this.encodeField.bind(this));
180
+ },
60
181
  async encodeEntry ({ data, schema }) {
61
182
  if (!isObject(data) || data === undefined) {
62
183
  return data;
@@ -65,6 +186,17 @@ const createContentSourceMapsService = (strapi)=>{
65
186
  if (!attribute || EXCLUDED_FIELDS.includes(key)) {
66
187
  return;
67
188
  }
189
+ if (attribute.type === 'blocks' && Array.isArray(value)) {
190
+ const fieldPath = path.rawWithIndices;
191
+ set(key, this.encodeBlocks(value, {
192
+ fieldPath,
193
+ kind: schema.kind,
194
+ model: schema.uid,
195
+ locale: data.locale,
196
+ documentId: data.documentId
197
+ }));
198
+ return;
199
+ }
68
200
  if (ENCODABLE_TYPES.includes(attribute.type) && typeof value === 'string') {
69
201
  // For inner fields of a multi-media field's items (e.g. `medias.0.url`),
70
202
  // drop the array index so all items share the same encoded path. The
@@ -110,5 +242,5 @@ const createContentSourceMapsService = (strapi)=>{
110
242
  };
111
243
  };
112
244
 
113
- export { createContentSourceMapsService };
245
+ export { createContentSourceMapsService, encodeBlocks };
114
246
  //# sourceMappingURL=content-source-maps.mjs.map
@@ -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 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
+ {"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 * - integer, float and decimal: number\n * - boolean: boolean (believe it or not)\n * - uid: can be stringified but would mess up URLs\n *\n * The blocks type is an array of nodes — handled in a dedicated branch below\n * because it requires walking the AST to encode the first text leaf of each visual block.\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\ntype BlocksEncodeMetadata = Omit<FieldContentSourceMap, 'path' | 'type'> & { fieldPath: string };\n\ntype EncodeFieldFn = (text: string, metadata: FieldContentSourceMap) => string;\n\nconst isObject = (value: unknown): value is Record<string, any> => {\n return typeof value === 'object' && value !== null;\n};\n\nconst blocksFieldMetadata = (metadata: BlocksEncodeMetadata): FieldContentSourceMap => ({\n ...metadata,\n path: metadata.fieldPath,\n type: 'blocks',\n});\n\n/**\n * Walk a subtree depth-first and stega-encode the first `{ type: 'text', text }` leaf only.\n */\nconst encodeFirstTextLeaf = (\n node: unknown,\n metadata: BlocksEncodeMetadata,\n encodeField: EncodeFieldFn\n): { node: unknown; encoded: boolean } => {\n if (!isObject(node)) {\n return { node, encoded: false };\n }\n\n if (node.type === 'text' && typeof node.text === 'string') {\n return {\n node: {\n ...node,\n text: encodeField(node.text, blocksFieldMetadata(metadata)),\n },\n encoded: true,\n };\n }\n\n if (Array.isArray(node.children)) {\n let encoded = false;\n const children = node.children.map((child) => {\n if (encoded) {\n return child;\n }\n\n const result = encodeFirstTextLeaf(child, metadata, encodeField);\n encoded = result.encoded;\n return result.node;\n });\n\n return {\n node: { ...node, children },\n encoded,\n };\n }\n\n return { node, encoded: false };\n};\n\nconst encodeListBlock = (\n listNode: Record<string, unknown>,\n metadata: BlocksEncodeMetadata,\n encodeField: EncodeFieldFn\n): Record<string, unknown> => {\n const children = (listNode.children as unknown[]).map((child) => {\n if (!isObject(child)) {\n return child;\n }\n\n if (child.type === 'list-item') {\n return encodeFirstTextLeaf(child, metadata, encodeField).node;\n }\n\n if (child.type === 'list') {\n return encodeListBlock(child, metadata, encodeField);\n }\n\n return child;\n });\n\n return { ...listNode, children };\n};\n\nconst encodeImageBlock = (\n imageNode: Record<string, unknown>,\n metadata: BlocksEncodeMetadata,\n encodeField: EncodeFieldFn\n): Record<string, unknown> => {\n if (!isObject(imageNode.image)) {\n return imageNode;\n }\n\n const { alternativeText } = imageNode.image as Record<string, unknown>;\n // Encode the alt text (not the URL). Encoding the URL corrupts the src attribute and can\n // cause the preview highlight to expand across the entire page. The alt attribute is a\n // safe target: it's visible to the previewScript via getAttribute and never used as a URL.\n // Only encode when alternativeText is a non-empty string — images with no alt text get\n // no stega marker and won't independently trigger the highlight, but the blocks field\n // as a whole remains highlightable via its other (text) blocks.\n if (typeof alternativeText !== 'string' || alternativeText.length === 0) {\n return imageNode;\n }\n\n return {\n ...imageNode,\n image: {\n ...(imageNode.image as Record<string, unknown>),\n alternativeText: encodeField(alternativeText, blocksFieldMetadata(metadata)),\n },\n };\n};\n\n/**\n * Pure transformation over a blocks AST. Injects one stega marker per visual block\n * (first text leaf, or image alt text) using the blocks field path for all markers.\n * Code blocks are skipped entirely.\n */\nconst encodeBlocks = (\n blocks: unknown,\n metadata: BlocksEncodeMetadata,\n encodeField: EncodeFieldFn\n): unknown => {\n if (!Array.isArray(blocks)) {\n return blocks;\n }\n\n return blocks.map((block) => {\n if (!isObject(block)) {\n return block;\n }\n\n switch (block.type) {\n case 'code':\n // Skip encoding — encoding code content would corrupt the syntax.\n return block;\n case 'image':\n return encodeImageBlock(block, metadata, encodeField);\n case 'list':\n return encodeListBlock(block, metadata, encodeField);\n case 'paragraph':\n case 'heading':\n case 'quote':\n return encodeFirstTextLeaf(block, metadata, encodeField).node;\n default:\n return block;\n }\n });\n};\n\nconst createContentSourceMapsService = (strapi: Core.Strapi) => {\n return {\n encodeField(\n text: string,\n { kind, model, documentId, type, path, locale, fieldPath }: 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 if (fieldPath) {\n strapiSource.set('fieldPath', fieldPath);\n }\n\n const encoded = vercelStegaCombine(\n text,\n {\n strapiSource: strapiSource.toString(),\n },\n false\n );\n\n return encoded;\n },\n\n encodeBlocks(blocks: unknown, metadata: BlocksEncodeMetadata): unknown {\n return encodeBlocks(blocks, metadata, this.encodeField.bind(this));\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 (attribute.type === 'blocks' && Array.isArray(value)) {\n const fieldPath = path.rawWithIndices!;\n set(\n key,\n this.encodeBlocks(value, {\n fieldPath,\n kind: schema.kind,\n model: schema.uid as UID.Schema,\n locale: data.locale,\n documentId: data.documentId,\n }) as any\n );\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, encodeBlocks };\nexport type { BlocksEncodeMetadata, EncodeFieldFn };\n"],"names":["ENCODABLE_TYPES","EXCLUDED_FIELDS","isObject","value","blocksFieldMetadata","metadata","path","fieldPath","type","encodeFirstTextLeaf","node","encodeField","encoded","text","Array","isArray","children","map","child","result","encodeListBlock","listNode","encodeImageBlock","imageNode","image","alternativeText","length","encodeBlocks","blocks","block","createContentSourceMapsService","strapi","kind","model","documentId","locale","strapiSource","URLSearchParams","set","vercelStegaCombine","toString","bind","encodeEntry","data","schema","undefined","traverseEntity","key","attribute","parent","includes","rawWithIndices","uid","parentAttr","isInsideMultiMedia","multiple","encodedPath","getModel","encodeSourceMaps","Promise","all","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;AAWD,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;AAWD,MAAMC,WAAW,CAACC,KAAAA,GAAAA;IAChB,OAAO,OAAOA,KAAAA,KAAU,QAAA,IAAYA,KAAAA,KAAU,IAAA;AAChD,CAAA;AAEA,MAAMC,mBAAAA,GAAsB,CAACC,QAAAA,IAA2D;AACtF,QAAA,GAAGA,QAAQ;AACXC,QAAAA,IAAAA,EAAMD,SAASE,SAAS;QACxBC,IAAAA,EAAM;KACR,CAAA;AAEA;;AAEC,IACD,MAAMC,mBAAAA,GAAsB,CAC1BC,IAAAA,EACAL,QAAAA,EACAM,WAAAA,GAAAA;IAEA,IAAI,CAACT,SAASQ,IAAAA,CAAAA,EAAO;QACnB,OAAO;AAAEA,YAAAA,IAAAA;YAAME,OAAAA,EAAS;AAAM,SAAA;AAChC,IAAA;IAEA,IAAIF,IAAAA,CAAKF,IAAI,KAAK,MAAA,IAAU,OAAOE,IAAAA,CAAKG,IAAI,KAAK,QAAA,EAAU;QACzD,OAAO;YACLH,IAAAA,EAAM;AACJ,gBAAA,GAAGA,IAAI;AACPG,gBAAAA,IAAAA,EAAMF,WAAAA,CAAYD,IAAAA,CAAKG,IAAI,EAAET,mBAAAA,CAAoBC,QAAAA,CAAAA;AACnD,aAAA;YACAO,OAAAA,EAAS;AACX,SAAA;AACF,IAAA;AAEA,IAAA,IAAIE,KAAAA,CAAMC,OAAO,CAACL,IAAAA,CAAKM,QAAQ,CAAA,EAAG;AAChC,QAAA,IAAIJ,OAAAA,GAAU,KAAA;AACd,QAAA,MAAMI,WAAWN,IAAAA,CAAKM,QAAQ,CAACC,GAAG,CAAC,CAACC,KAAAA,GAAAA;AAClC,YAAA,IAAIN,OAAAA,EAAS;gBACX,OAAOM,KAAAA;AACT,YAAA;YAEA,MAAMC,MAAAA,GAASV,mBAAAA,CAAoBS,KAAAA,EAAOb,QAAAA,EAAUM,WAAAA,CAAAA;AACpDC,YAAAA,OAAAA,GAAUO,OAAOP,OAAO;AACxB,YAAA,OAAOO,OAAOT,IAAI;AACpB,QAAA,CAAA,CAAA;QAEA,OAAO;YACLA,IAAAA,EAAM;AAAE,gBAAA,GAAGA,IAAI;AAAEM,gBAAAA;AAAS,aAAA;AAC1BJ,YAAAA;AACF,SAAA;AACF,IAAA;IAEA,OAAO;AAAEF,QAAAA,IAAAA;QAAME,OAAAA,EAAS;AAAM,KAAA;AAChC,CAAA;AAEA,MAAMQ,eAAAA,GAAkB,CACtBC,QAAAA,EACAhB,QAAAA,EACAM,WAAAA,GAAAA;AAEA,IAAA,MAAMK,WAAW,QAACK,CAASL,QAAQ,CAAeC,GAAG,CAAC,CAACC,KAAAA,GAAAA;QACrD,IAAI,CAAChB,SAASgB,KAAAA,CAAAA,EAAQ;YACpB,OAAOA,KAAAA;AACT,QAAA;QAEA,IAAIA,KAAAA,CAAMV,IAAI,KAAK,WAAA,EAAa;AAC9B,YAAA,OAAOC,mBAAAA,CAAoBS,KAAAA,EAAOb,QAAAA,EAAUM,WAAAA,CAAAA,CAAaD,IAAI;AAC/D,QAAA;QAEA,IAAIQ,KAAAA,CAAMV,IAAI,KAAK,MAAA,EAAQ;YACzB,OAAOY,eAAAA,CAAgBF,OAAOb,QAAAA,EAAUM,WAAAA,CAAAA;AAC1C,QAAA;QAEA,OAAOO,KAAAA;AACT,IAAA,CAAA,CAAA;IAEA,OAAO;AAAE,QAAA,GAAGG,QAAQ;AAAEL,QAAAA;AAAS,KAAA;AACjC,CAAA;AAEA,MAAMM,gBAAAA,GAAmB,CACvBC,SAAAA,EACAlB,QAAAA,EACAM,WAAAA,GAAAA;AAEA,IAAA,IAAI,CAACT,QAAAA,CAASqB,SAAAA,CAAUC,KAAK,CAAA,EAAG;QAC9B,OAAOD,SAAAA;AACT,IAAA;AAEA,IAAA,MAAM,EAAEE,eAAe,EAAE,GAAGF,UAAUC,KAAK;;;;;;;AAO3C,IAAA,IAAI,OAAOC,eAAAA,KAAoB,QAAA,IAAYA,eAAAA,CAAgBC,MAAM,KAAK,CAAA,EAAG;QACvE,OAAOH,SAAAA;AACT,IAAA;IAEA,OAAO;AACL,QAAA,GAAGA,SAAS;QACZC,KAAAA,EAAO;AACL,YAAA,GAAID,UAAUC,KAAK;YACnBC,eAAAA,EAAiBd,WAAAA,CAAYc,iBAAiBrB,mBAAAA,CAAoBC,QAAAA,CAAAA;AACpE;AACF,KAAA;AACF,CAAA;AAEA;;;;AAIC,IACD,MAAMsB,YAAAA,GAAe,CACnBC,MAAAA,EACAvB,QAAAA,EACAM,WAAAA,GAAAA;AAEA,IAAA,IAAI,CAACG,KAAAA,CAAMC,OAAO,CAACa,MAAAA,CAAAA,EAAS;QAC1B,OAAOA,MAAAA;AACT,IAAA;IAEA,OAAOA,MAAAA,CAAOX,GAAG,CAAC,CAACY,KAAAA,GAAAA;QACjB,IAAI,CAAC3B,SAAS2B,KAAAA,CAAAA,EAAQ;YACpB,OAAOA,KAAAA;AACT,QAAA;AAEA,QAAA,OAAQA,MAAMrB,IAAI;YAChB,KAAK,MAAA;;gBAEH,OAAOqB,KAAAA;YACT,KAAK,OAAA;gBACH,OAAOP,gBAAAA,CAAiBO,OAAOxB,QAAAA,EAAUM,WAAAA,CAAAA;YAC3C,KAAK,MAAA;gBACH,OAAOS,eAAAA,CAAgBS,OAAOxB,QAAAA,EAAUM,WAAAA,CAAAA;YAC1C,KAAK,WAAA;YACL,KAAK,SAAA;YACL,KAAK,OAAA;AACH,gBAAA,OAAOF,mBAAAA,CAAoBoB,KAAAA,EAAOxB,QAAAA,EAAUM,WAAAA,CAAAA,CAAaD,IAAI;AAC/D,YAAA;gBACE,OAAOmB,KAAAA;AACX;AACF,IAAA,CAAA,CAAA;AACF;AAEA,MAAMC,iCAAiC,CAACC,MAAAA,GAAAA;IACtC,OAAO;AACLpB,QAAAA,WAAAA,CAAAA,CACEE,IAAY,EACZ,EAAEmB,IAAI,EAAEC,KAAK,EAAEC,UAAU,EAAE1B,IAAI,EAAEF,IAAI,EAAE6B,MAAM,EAAE5B,SAAS,EAAyB,EAAA;AAEjF;;;;UAKA,MAAM6B,eAAe,IAAIC,eAAAA,EAAAA;YACzBD,YAAAA,CAAaE,GAAG,CAAC,YAAA,EAAcJ,UAAAA,CAAAA;YAC/BE,YAAAA,CAAaE,GAAG,CAAC,MAAA,EAAQ9B,IAAAA,CAAAA;YACzB4B,YAAAA,CAAaE,GAAG,CAAC,MAAA,EAAQhC,IAAAA,CAAAA;AAEzB,YAAA,IAAI2B,KAAAA,EAAO;gBACTG,YAAAA,CAAaE,GAAG,CAAC,OAAA,EAASL,KAAAA,CAAAA;AAC5B,YAAA;AACA,YAAA,IAAID,IAAAA,EAAM;gBACRI,YAAAA,CAAaE,GAAG,CAAC,MAAA,EAAQN,IAAAA,CAAAA;AAC3B,YAAA;AACA,YAAA,IAAIG,MAAAA,EAAQ;gBACVC,YAAAA,CAAaE,GAAG,CAAC,QAAA,EAAUH,MAAAA,CAAAA;AAC7B,YAAA;AACA,YAAA,IAAI5B,SAAAA,EAAW;gBACb6B,YAAAA,CAAaE,GAAG,CAAC,WAAA,EAAa/B,SAAAA,CAAAA;AAChC,YAAA;YAEA,MAAMK,OAAAA,GAAU2B,mBACd1B,IAAAA,EACA;AACEuB,gBAAAA,YAAAA,EAAcA,aAAaI,QAAQ;aACrC,EACA,KAAA,CAAA;YAGF,OAAO5B,OAAAA;AACT,QAAA,CAAA;QAEAe,YAAAA,CAAAA,CAAaC,MAAe,EAAEvB,QAA8B,EAAA;YAC1D,OAAOsB,YAAAA,CAAaC,QAAQvB,QAAAA,EAAU,IAAI,CAACM,WAAW,CAAC8B,IAAI,CAAC,IAAI,CAAA,CAAA;AAClE,QAAA,CAAA;AAEA,QAAA,MAAMC,WAAAA,CAAAA,CAAY,EAAEC,IAAI,EAAEC,MAAM,EAAgB,EAAA;AAC9C,YAAA,IAAI,CAAC1C,QAAAA,CAASyC,IAAAA,CAAAA,IAASA,IAAAA,KAASE,SAAAA,EAAW;gBACzC,OAAOF,IAAAA;AACT,YAAA;AAEA,YAAA,OAAOG,eACL,CAAC,EAAEC,GAAG,EAAE5C,KAAK,EAAE6C,SAAS,EAAEJ,MAAM,EAAEtC,IAAI,EAAE2C,MAAM,EAAE,EAAE,EAAEX,GAAG,EAAE,GAAA;AACvD,gBAAA,IAAI,CAACU,SAAAA,IAAa/C,eAAAA,CAAgBiD,QAAQ,CAACH,GAAAA,CAAAA,EAAM;AAC/C,oBAAA;AACF,gBAAA;AAEA,gBAAA,IAAIC,UAAUxC,IAAI,KAAK,YAAYM,KAAAA,CAAMC,OAAO,CAACZ,KAAAA,CAAAA,EAAQ;oBACvD,MAAMI,SAAAA,GAAYD,KAAK6C,cAAc;AACrCb,oBAAAA,GAAAA,CACES,GAAAA,EACA,IAAI,CAACpB,YAAY,CAACxB,KAAAA,EAAO;AACvBI,wBAAAA,SAAAA;AACAyB,wBAAAA,IAAAA,EAAMY,OAAOZ,IAAI;AACjBC,wBAAAA,KAAAA,EAAOW,OAAOQ,GAAG;AACjBjB,wBAAAA,MAAAA,EAAQQ,KAAKR,MAAM;AACnBD,wBAAAA,UAAAA,EAAYS,KAAKT;AACnB,qBAAA,CAAA,CAAA;AAEF,oBAAA;AACF,gBAAA;gBAEA,IAAIlC,eAAAA,CAAgBkD,QAAQ,CAACF,SAAAA,CAAUxC,IAAI,CAAA,IAAK,OAAOL,UAAU,QAAA,EAAU;;;;;AAKzE,oBAAA,MAAMkD,aAAaJ,MAAAA,EAAQD,SAAAA;AAC3B,oBAAA,MAAMM,qBACJD,UAAAA,EAAY7C,IAAAA,KAAS,WAAW,UAAC6C,CAAmBE,QAAQ,KAAK,IAAA;AACnE,oBAAA,MAAMC,cACJF,kBAAAA,IAAsBL,MAAAA,EAAQ3C,IAAAA,EAAM6C,cAAAA,GAChC,GAAGF,MAAAA,CAAO3C,IAAI,CAAC6C,cAAc,CAAC,CAAC,EAAEJ,GAAAA,CAAAA,CAAK,GACtCzC,KAAK6C,cAAc;AAEzBb,oBAAAA,GAAAA,CACES,GAAAA,EACA,IAAI,CAACpC,WAAW,CAACR,KAAAA,EAAO;wBACtBG,IAAAA,EAAMkD,WAAAA;AACNhD,wBAAAA,IAAAA,EAAMwC,UAAUxC,IAAI;AACpBwB,wBAAAA,IAAAA,EAAMY,OAAOZ,IAAI;AACjBC,wBAAAA,KAAAA,EAAOW,OAAOQ,GAAG;AACjBjB,wBAAAA,MAAAA,EAAQQ,KAAKR,MAAM;AACnBD,wBAAAA,UAAAA,EAAYS,KAAKT;AACnB,qBAAA,CAAA,CAAA;AAEJ,gBAAA;YACF,CAAA,EACA;AACEU,gBAAAA,MAAAA;AACAa,gBAAAA,QAAAA,EAAU,CAACL,GAAAA,GAAQrB,MAAAA,CAAO0B,QAAQ,CAACL,GAAAA;aACrC,EACAT,IAAAA,CAAAA;AAEJ,QAAA,CAAA;AAEA,QAAA,MAAMe,gBAAAA,CAAAA,CAAiB,EAAEf,IAAI,EAAEC,MAAM,EAAgB,EAAA;YACnD,IAAI;gBACF,IAAI9B,KAAAA,CAAMC,OAAO,CAAC4B,IAAAA,CAAAA,EAAO;AACvB,oBAAA,OAAO,MAAMgB,OAAAA,CAAQC,GAAG,CACtBjB,IAAAA,CAAK1B,GAAG,CAAC,CAAC4C,IAAAA,GAAS,IAAI,CAACH,gBAAgB,CAAC;4BAAEf,IAAAA,EAAMkB,IAAAA;AAAMjB,4BAAAA;AAAO,yBAAA,CAAA,CAAA,CAAA;AAElE,gBAAA;gBAEA,IAAI,CAAC1C,SAASyC,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,OAAOkB,KAAAA,EAAO;AACd/B,gBAAAA,MAAAA,CAAOgC,GAAG,CAACD,KAAK,CAAC,6BAAA,EAA+BA,KAAAA,CAAAA;gBAChD,OAAOnB,IAAAA;AACT,YAAA;AACF,QAAA;AACF,KAAA;AACF;;;;"}
@@ -1,27 +1,12 @@
1
- import type { Job, Spec } from 'node-schedule';
2
- import type { Core } from '@strapi/types';
3
- interface JobSpec {
4
- job: Job;
5
- options: Spec;
6
- name: string | null;
7
- }
8
- type TaskFn = ({ strapi }: {
9
- strapi: Core.Strapi;
10
- }, ...args: unknown[]) => Promise<unknown>;
11
- type Task = TaskFn | {
12
- task: TaskFn;
13
- options: Spec;
14
- };
15
- interface Tasks {
16
- [key: string]: Task;
17
- }
1
+ import type { Modules } from '@strapi/types';
2
+ type Tasks = Modules.Cron.CronTasks;
18
3
  declare const createCronService: () => {
19
4
  add(tasks?: Tasks): /*elided*/ any;
20
5
  remove(name: string): /*elided*/ any;
21
6
  start(): /*elided*/ any;
22
7
  stop(): /*elided*/ any;
23
8
  destroy(): /*elided*/ any;
24
- jobs: JobSpec[];
9
+ readonly jobs: Modules.Cron.JobSpec[];
25
10
  };
26
11
  export default createCronService;
27
12
  //# sourceMappingURL=cron.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cron.d.ts","sourceRoot":"","sources":["../../src/services/cron.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE/C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAY1C,UAAU,OAAO;IACf,GAAG,EAAE,GAAG,CAAC;IACT,OAAO,EAAE,IAAI,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAED,KAAK,MAAM,GAAG,CAAC,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAA;CAAE,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAE5F,KAAK,IAAI,GACL,MAAM,GACN;IACE,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,IAAI,CAAC;CACf,CAAC;AAEN,UAAU,KAAK;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAED,QAAA,MAAM,iBAAiB;gBAKR,KAAK;iBAuCH,MAAM;;;;;CAgCtB,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
1
+ {"version":3,"file":"cron.d.ts","sourceRoot":"","sources":["../../src/services/cron.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAS7C,KAAK,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC;AA2JpC,QAAA,MAAM,iBAAiB;gBAoGR,KAAK;iBAuCH,MAAM;;;;;CAqCtB,CAAC;AAEF,eAAe,iBAAiB,CAAC"}