@strapi/core 5.50.2 → 5.51.1

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 (29) hide show
  1. package/dist/migrations/database/5.0.0-discard-drafts.d.ts.map +1 -1
  2. package/dist/migrations/database/5.0.0-discard-drafts.js +77 -7
  3. package/dist/migrations/database/5.0.0-discard-drafts.js.map +1 -1
  4. package/dist/migrations/database/5.0.0-discard-drafts.mjs +77 -7
  5. package/dist/migrations/database/5.0.0-discard-drafts.mjs.map +1 -1
  6. package/dist/package.json.js +14 -14
  7. package/dist/package.json.mjs +14 -14
  8. package/dist/services/document-service/entries.d.ts.map +1 -1
  9. package/dist/services/document-service/entries.js +16 -2
  10. package/dist/services/document-service/entries.js.map +1 -1
  11. package/dist/services/document-service/entries.mjs +16 -2
  12. package/dist/services/document-service/entries.mjs.map +1 -1
  13. package/dist/services/document-service/first-published-at.d.ts.map +1 -1
  14. package/dist/services/document-service/first-published-at.js +9 -2
  15. package/dist/services/document-service/first-published-at.js.map +1 -1
  16. package/dist/services/document-service/first-published-at.mjs +9 -2
  17. package/dist/services/document-service/first-published-at.mjs.map +1 -1
  18. package/dist/services/entity-validator/index.d.ts +1 -0
  19. package/dist/services/entity-validator/index.d.ts.map +1 -1
  20. package/dist/services/entity-validator/index.js +152 -25
  21. package/dist/services/entity-validator/index.js.map +1 -1
  22. package/dist/services/entity-validator/index.mjs +152 -25
  23. package/dist/services/entity-validator/index.mjs.map +1 -1
  24. package/dist/services/entity-validator/validators.d.ts.map +1 -1
  25. package/dist/services/entity-validator/validators.js +6 -0
  26. package/dist/services/entity-validator/validators.js.map +1 -1
  27. package/dist/services/entity-validator/validators.mjs +6 -0
  28. package/dist/services/entity-validator/validators.mjs.map +1 -1
  29. package/package.json +14 -14
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var name = "@strapi/core";
6
- var version = "5.50.2";
6
+ var version = "5.51.1";
7
7
  var description = "Core of Strapi";
8
8
  var homepage = "https://strapi.io";
9
9
  var bugs = {
@@ -65,15 +65,15 @@ var dependencies = {
65
65
  "@koa/router": "12.0.2",
66
66
  "@modelcontextprotocol/sdk": "1.29.0",
67
67
  "@paralleldrive/cuid2": "2.2.2",
68
- "@strapi/admin": "5.50.2",
69
- "@strapi/database": "5.50.2",
70
- "@strapi/generators": "5.50.2",
71
- "@strapi/logger": "5.50.2",
72
- "@strapi/openapi": "5.50.2",
73
- "@strapi/permissions": "5.50.2",
74
- "@strapi/types": "5.50.2",
75
- "@strapi/typescript-utils": "5.50.2",
76
- "@strapi/utils": "5.50.2",
68
+ "@strapi/admin": "5.51.1",
69
+ "@strapi/database": "5.51.1",
70
+ "@strapi/generators": "5.51.1",
71
+ "@strapi/logger": "5.51.1",
72
+ "@strapi/openapi": "5.51.1",
73
+ "@strapi/permissions": "5.51.1",
74
+ "@strapi/types": "5.51.1",
75
+ "@strapi/typescript-utils": "5.51.1",
76
+ "@strapi/utils": "5.51.1",
77
77
  "@vercel/stega": "0.1.2",
78
78
  bcryptjs: "2.4.3",
79
79
  boxen: "5.1.2",
@@ -117,7 +117,7 @@ var dependencies = {
117
117
  typescript: "5.9.3",
118
118
  undici: "6.27.0",
119
119
  yup: "0.32.9",
120
- zod: "3.25.67"
120
+ zod: "3.25.76"
121
121
  };
122
122
  var devDependencies = {
123
123
  "@swc/core": "1.13.5",
@@ -137,12 +137,12 @@ var devDependencies = {
137
137
  "@types/mime-types": "2.1.1",
138
138
  "@types/node": "20.19.41",
139
139
  "@types/node-schedule": "2.1.7",
140
- "eslint-config-custom": "5.50.2",
140
+ "eslint-config-custom": "5.51.1",
141
141
  jest: "29.6.0",
142
142
  supertest: "7.2.2",
143
- tsconfig: "5.50.2",
143
+ tsconfig: "5.51.1",
144
144
  vitest: "catalog:",
145
- "vitest-config": "5.50.2"
145
+ "vitest-config": "5.51.1"
146
146
  };
147
147
  var engines = {
148
148
  node: ">=20.0.0 <=26.x.x",
@@ -1,5 +1,5 @@
1
1
  var name = "@strapi/core";
2
- var version = "5.50.2";
2
+ var version = "5.51.1";
3
3
  var description = "Core of Strapi";
4
4
  var homepage = "https://strapi.io";
5
5
  var bugs = {
@@ -61,15 +61,15 @@ var dependencies = {
61
61
  "@koa/router": "12.0.2",
62
62
  "@modelcontextprotocol/sdk": "1.29.0",
63
63
  "@paralleldrive/cuid2": "2.2.2",
64
- "@strapi/admin": "5.50.2",
65
- "@strapi/database": "5.50.2",
66
- "@strapi/generators": "5.50.2",
67
- "@strapi/logger": "5.50.2",
68
- "@strapi/openapi": "5.50.2",
69
- "@strapi/permissions": "5.50.2",
70
- "@strapi/types": "5.50.2",
71
- "@strapi/typescript-utils": "5.50.2",
72
- "@strapi/utils": "5.50.2",
64
+ "@strapi/admin": "5.51.1",
65
+ "@strapi/database": "5.51.1",
66
+ "@strapi/generators": "5.51.1",
67
+ "@strapi/logger": "5.51.1",
68
+ "@strapi/openapi": "5.51.1",
69
+ "@strapi/permissions": "5.51.1",
70
+ "@strapi/types": "5.51.1",
71
+ "@strapi/typescript-utils": "5.51.1",
72
+ "@strapi/utils": "5.51.1",
73
73
  "@vercel/stega": "0.1.2",
74
74
  bcryptjs: "2.4.3",
75
75
  boxen: "5.1.2",
@@ -113,7 +113,7 @@ var dependencies = {
113
113
  typescript: "5.9.3",
114
114
  undici: "6.27.0",
115
115
  yup: "0.32.9",
116
- zod: "3.25.67"
116
+ zod: "3.25.76"
117
117
  };
118
118
  var devDependencies = {
119
119
  "@swc/core": "1.13.5",
@@ -133,12 +133,12 @@ var devDependencies = {
133
133
  "@types/mime-types": "2.1.1",
134
134
  "@types/node": "20.19.41",
135
135
  "@types/node-schedule": "2.1.7",
136
- "eslint-config-custom": "5.50.2",
136
+ "eslint-config-custom": "5.51.1",
137
137
  jest: "29.6.0",
138
138
  supertest: "7.2.2",
139
- tsconfig: "5.50.2",
139
+ tsconfig: "5.51.1",
140
140
  vitest: "catalog:",
141
- "vitest-config": "5.50.2"
141
+ "vitest-config": "5.51.1"
142
142
  };
143
143
  var engines = {
144
144
  node: ">=20.0.0 <=26.x.x",
@@ -1 +1 @@
1
- {"version":3,"file":"entries.d.ts","sourceRoot":"","sources":["../../../src/services/document-service/entries.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAYlD,QAAA,MAAM,oBAAoB,GACxB,KAAK,GAAG,CAAC,WAAW,EACpB,iBAAiB,OAAO,CAAC,eAAe,CAAC,eAAe;sBAId,GAAG;iBAuEd,MAAM,UAAgB,GAAG;4BAUd,GAAG,WAAiB,GAAG;qBA4B9B,GAAG,WAAiB,GAAG;0BAqBlB,GAAG,WAAiB,GAAG;CA4BhE,CAAC;AAEF,OAAO,EAAE,oBAAoB,EAAE,CAAC"}
1
+ {"version":3,"file":"entries.d.ts","sourceRoot":"","sources":["../../../src/services/document-service/entries.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAkClD,QAAA,MAAM,oBAAoB,GACxB,KAAK,GAAG,CAAC,WAAW,EACpB,iBAAiB,OAAO,CAAC,eAAe,CAAC,eAAe;sBAId,GAAG;iBAwEd,MAAM,UAAgB,GAAG;4BAUd,GAAG,WAAiB,GAAG;qBA6B9B,GAAG,WAAiB,GAAG;0BAqBlB,GAAG,WAAiB,GAAG;CA4BhE,CAAC;AAEF,OAAO,EAAE,oBAAoB,EAAE,CAAC"}
@@ -9,6 +9,18 @@ var params = require('./params.js');
9
9
  var index = require('./attributes/index.js');
10
10
  var data = require('./transform/data.js');
11
11
 
12
+ /**
13
+ * Reads and validates the `api.documents.strictRelations` flag.
14
+ * false/undefined => legacy behaviour (relational required constraints not enforced),
15
+ * true => enforce required media and relations on non-draft writes.
16
+ * Mirrors the validation of `api.documents.strictParams` (see repository.ts).
17
+ */ const isStrictRelationsEnabled = ()=>{
18
+ const rawStrictRelations = strapi.config.get('api.documents.strictRelations', undefined);
19
+ if (rawStrictRelations !== undefined && rawStrictRelations !== false && rawStrictRelations !== true) {
20
+ throw new strapiUtils.errors.ValidationError(`Invalid config.api.documents.strictRelations value: "${rawStrictRelations}". Expected boolean (true or false).`);
21
+ }
22
+ return rawStrictRelations === true;
23
+ };
12
24
  const createEntriesService = (uid, entityValidator)=>{
13
25
  const contentType = strapi.contentType(uid);
14
26
  async function createEntry(params$1 = {}) {
@@ -63,7 +75,8 @@ const createEntriesService = (uid, entityValidator)=>{
63
75
  const validData = await entityValidator.validateEntityCreation(contentType, data, {
64
76
  // Note: publishedAt value will always be set when DP is disabled
65
77
  isDraft: !params$1?.data?.publishedAt,
66
- locale: params$1?.locale
78
+ locale: params$1?.locale,
79
+ strictRelations: isStrictRelationsEnabled()
67
80
  });
68
81
  // Component handling
69
82
  const componentData = await components.createComponents(uid, validData);
@@ -95,7 +108,8 @@ const createEntriesService = (uid, entityValidator)=>{
95
108
  const query$1 = query.transformParamsToQuery(uid, params.pickSelectionParams(restParams)); // select / populate
96
109
  const validData = await entityValidator.validateEntityUpdate(contentType, data, {
97
110
  isDraft: !params$1?.data?.publishedAt,
98
- locale: params$1?.locale
111
+ locale: params$1?.locale,
112
+ strictRelations: isStrictRelationsEnabled()
99
113
  }, entryToUpdate);
100
114
  // Component handling
101
115
  const componentData = await components.updateComponents(uid, entryToUpdate, validData);
@@ -1 +1 @@
1
- {"version":3,"file":"entries.js","sources":["../../../src/services/document-service/entries.ts"],"sourcesContent":["import type { UID, Modules } from '@strapi/types';\nimport { async, errors } from '@strapi/utils';\nimport { assoc, omit } from 'lodash/fp';\n\nimport * as components from './components';\n\nimport { transformParamsDocumentId } from './transform/id-transform';\nimport { transformParamsToQuery } from './transform/query';\nimport { pickSelectionParams } from './params';\nimport { applyTransforms } from './attributes';\nimport { clearTransformDataRequestCache, transformData } from './transform/data';\n\nconst createEntriesService = (\n uid: UID.ContentType,\n entityValidator: Modules.EntityValidator.EntityValidator\n) => {\n const contentType = strapi.contentType(uid);\n\n async function createEntry(params = {} as any) {\n const { data, ...restParams } = await transformParamsDocumentId(uid, params);\n const query = transformParamsToQuery(uid, pickSelectionParams(restParams) as any); // select / populate\n\n // Validation\n if (!data) {\n throw new Error('Create requires data attribute');\n }\n\n // Check for uniqueness based on documentId and locale (if localized)\n if (data.documentId) {\n const i18nService = strapi.plugin('i18n')?.service('content-types');\n const isLocalized = i18nService?.isLocalizedContentType(contentType) ?? false;\n const hasDraftAndPublish = contentType.options?.draftAndPublish === true;\n\n const whereClause: Record<string, unknown> = { documentId: data.documentId };\n\n if (isLocalized) {\n whereClause.locale = data.locale;\n }\n\n let publishedStateDescription = '';\n\n if (hasDraftAndPublish) {\n if (data.publishedAt) {\n // Current entry is published, check for existing published entry\n whereClause.publishedAt = { $notNull: true };\n publishedStateDescription = 'published';\n } else {\n // Current entry is a draft, check for existing draft entry\n whereClause.publishedAt = { $null: true };\n publishedStateDescription = 'draft';\n }\n }\n\n const existingEntry = await strapi.db.query(uid).findOne({\n select: ['id'],\n where: whereClause,\n });\n\n if (existingEntry) {\n let errorMsg = `A ${publishedStateDescription} entry with documentId \"${data.documentId}\"`;\n if (isLocalized && data.locale) {\n errorMsg += ` and locale \"${data.locale}\"`;\n }\n errorMsg += ` already exists for UID \"${uid}\". This combination must be unique.`;\n throw new errors.ApplicationError(errorMsg);\n }\n }\n\n const validData = await entityValidator.validateEntityCreation(contentType, data, {\n // Note: publishedAt value will always be set when DP is disabled\n isDraft: !params?.data?.publishedAt,\n locale: params?.locale,\n });\n\n // Component handling\n const componentData = await components.createComponents(uid, validData);\n const dataWithComponents = components.assignComponentData(\n contentType,\n componentData,\n validData\n );\n\n const entryData = applyTransforms(contentType, dataWithComponents);\n\n const doc = await strapi.db.query(uid).create({ ...query, data: entryData });\n\n return doc;\n }\n\n async function deleteEntry(id: number, query = {} as any) {\n const componentsToDelete = await components.getComponents(uid, { id });\n\n const deletedEntry = await strapi.db.query(uid).delete({ ...query, where: { id } });\n\n await components.deleteComponents(uid, componentsToDelete as any, { loadComponents: false });\n\n return deletedEntry;\n }\n\n async function updateEntry(entryToUpdate: any, params = {} as any) {\n const { data, ...restParams } = await transformParamsDocumentId(uid, params);\n const query = transformParamsToQuery(uid, pickSelectionParams(restParams) as any); // select / populate\n\n const validData = await entityValidator.validateEntityUpdate(\n contentType,\n data,\n {\n isDraft: !params?.data?.publishedAt, // Always update the draft version\n locale: params?.locale,\n },\n entryToUpdate\n );\n // Component handling\n const componentData = await components.updateComponents(uid, entryToUpdate, validData as any);\n const dataWithComponents = components.assignComponentData(\n contentType,\n componentData,\n validData\n );\n\n const entryData = applyTransforms(contentType, dataWithComponents);\n\n return strapi.db\n .query(uid)\n .update({ ...query, where: { id: entryToUpdate.id }, data: entryData });\n }\n\n async function publishEntry(entry: any, params = {} as any) {\n clearTransformDataRequestCache();\n\n return async.pipe(\n omit('id'),\n assoc('publishedAt', new Date()),\n (draft) => {\n const opts = {\n uid,\n locale: draft.locale,\n status: 'published',\n allowMissingId: true,\n useRequestCache: false,\n };\n return transformData(draft, opts);\n },\n // Create the published entry\n (draft) => createEntry({ ...params, data: draft, locale: draft.locale, status: 'published' })\n )(entry);\n }\n\n async function discardDraftEntry(entry: any, params = {} as any) {\n clearTransformDataRequestCache();\n\n return async.pipe(\n omit('id'),\n assoc('publishedAt', null),\n (entry) => {\n const opts = {\n uid,\n locale: entry.locale,\n status: 'draft',\n allowMissingId: true,\n useRequestCache: false,\n };\n return transformData(entry, opts);\n },\n // Create the draft entry\n (data) => createEntry({ ...params, locale: data.locale, data, status: 'draft' })\n )(entry);\n }\n\n return {\n create: createEntry,\n delete: deleteEntry,\n update: updateEntry,\n publish: publishEntry,\n discardDraft: discardDraftEntry,\n };\n};\n\nexport { createEntriesService };\n"],"names":["createEntriesService","uid","entityValidator","contentType","strapi","createEntry","params","data","restParams","transformParamsDocumentId","query","transformParamsToQuery","pickSelectionParams","Error","documentId","i18nService","plugin","service","isLocalized","isLocalizedContentType","hasDraftAndPublish","options","draftAndPublish","whereClause","locale","publishedStateDescription","publishedAt","$notNull","$null","existingEntry","db","findOne","select","where","errorMsg","errors","ApplicationError","validData","validateEntityCreation","isDraft","componentData","components","dataWithComponents","entryData","applyTransforms","doc","create","deleteEntry","id","componentsToDelete","deletedEntry","delete","loadComponents","updateEntry","entryToUpdate","validateEntityUpdate","update","publishEntry","entry","clearTransformDataRequestCache","async","pipe","omit","assoc","Date","draft","opts","status","allowMissingId","useRequestCache","transformData","discardDraftEntry","publish","discardDraft"],"mappings":"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"}
1
+ {"version":3,"file":"entries.js","sources":["../../../src/services/document-service/entries.ts"],"sourcesContent":["import type { UID, Modules } from '@strapi/types';\nimport { async, errors } from '@strapi/utils';\nimport { assoc, omit } from 'lodash/fp';\n\nimport * as components from './components';\n\nimport { transformParamsDocumentId } from './transform/id-transform';\nimport { transformParamsToQuery } from './transform/query';\nimport { pickSelectionParams } from './params';\nimport { applyTransforms } from './attributes';\nimport { clearTransformDataRequestCache, transformData } from './transform/data';\n\n/**\n * Reads and validates the `api.documents.strictRelations` flag.\n * false/undefined => legacy behaviour (relational required constraints not enforced),\n * true => enforce required media and relations on non-draft writes.\n * Mirrors the validation of `api.documents.strictParams` (see repository.ts).\n */\nconst isStrictRelationsEnabled = (): boolean => {\n const rawStrictRelations: unknown = strapi.config.get('api.documents.strictRelations', undefined);\n\n if (\n rawStrictRelations !== undefined &&\n rawStrictRelations !== false &&\n rawStrictRelations !== true\n ) {\n throw new errors.ValidationError(\n `Invalid config.api.documents.strictRelations value: \"${rawStrictRelations}\". Expected boolean (true or false).`\n );\n }\n\n return rawStrictRelations === true;\n};\n\nconst createEntriesService = (\n uid: UID.ContentType,\n entityValidator: Modules.EntityValidator.EntityValidator\n) => {\n const contentType = strapi.contentType(uid);\n\n async function createEntry(params = {} as any) {\n const { data, ...restParams } = await transformParamsDocumentId(uid, params);\n const query = transformParamsToQuery(uid, pickSelectionParams(restParams) as any); // select / populate\n\n // Validation\n if (!data) {\n throw new Error('Create requires data attribute');\n }\n\n // Check for uniqueness based on documentId and locale (if localized)\n if (data.documentId) {\n const i18nService = strapi.plugin('i18n')?.service('content-types');\n const isLocalized = i18nService?.isLocalizedContentType(contentType) ?? false;\n const hasDraftAndPublish = contentType.options?.draftAndPublish === true;\n\n const whereClause: Record<string, unknown> = { documentId: data.documentId };\n\n if (isLocalized) {\n whereClause.locale = data.locale;\n }\n\n let publishedStateDescription = '';\n\n if (hasDraftAndPublish) {\n if (data.publishedAt) {\n // Current entry is published, check for existing published entry\n whereClause.publishedAt = { $notNull: true };\n publishedStateDescription = 'published';\n } else {\n // Current entry is a draft, check for existing draft entry\n whereClause.publishedAt = { $null: true };\n publishedStateDescription = 'draft';\n }\n }\n\n const existingEntry = await strapi.db.query(uid).findOne({\n select: ['id'],\n where: whereClause,\n });\n\n if (existingEntry) {\n let errorMsg = `A ${publishedStateDescription} entry with documentId \"${data.documentId}\"`;\n if (isLocalized && data.locale) {\n errorMsg += ` and locale \"${data.locale}\"`;\n }\n errorMsg += ` already exists for UID \"${uid}\". This combination must be unique.`;\n throw new errors.ApplicationError(errorMsg);\n }\n }\n\n const validData = await entityValidator.validateEntityCreation(contentType, data, {\n // Note: publishedAt value will always be set when DP is disabled\n isDraft: !params?.data?.publishedAt,\n locale: params?.locale,\n strictRelations: isStrictRelationsEnabled(),\n });\n\n // Component handling\n const componentData = await components.createComponents(uid, validData);\n const dataWithComponents = components.assignComponentData(\n contentType,\n componentData,\n validData\n );\n\n const entryData = applyTransforms(contentType, dataWithComponents);\n\n const doc = await strapi.db.query(uid).create({ ...query, data: entryData });\n\n return doc;\n }\n\n async function deleteEntry(id: number, query = {} as any) {\n const componentsToDelete = await components.getComponents(uid, { id });\n\n const deletedEntry = await strapi.db.query(uid).delete({ ...query, where: { id } });\n\n await components.deleteComponents(uid, componentsToDelete as any, { loadComponents: false });\n\n return deletedEntry;\n }\n\n async function updateEntry(entryToUpdate: any, params = {} as any) {\n const { data, ...restParams } = await transformParamsDocumentId(uid, params);\n const query = transformParamsToQuery(uid, pickSelectionParams(restParams) as any); // select / populate\n\n const validData = await entityValidator.validateEntityUpdate(\n contentType,\n data,\n {\n isDraft: !params?.data?.publishedAt, // Always update the draft version\n locale: params?.locale,\n strictRelations: isStrictRelationsEnabled(),\n },\n entryToUpdate\n );\n // Component handling\n const componentData = await components.updateComponents(uid, entryToUpdate, validData as any);\n const dataWithComponents = components.assignComponentData(\n contentType,\n componentData,\n validData\n );\n\n const entryData = applyTransforms(contentType, dataWithComponents);\n\n return strapi.db\n .query(uid)\n .update({ ...query, where: { id: entryToUpdate.id }, data: entryData });\n }\n\n async function publishEntry(entry: any, params = {} as any) {\n clearTransformDataRequestCache();\n\n return async.pipe(\n omit('id'),\n assoc('publishedAt', new Date()),\n (draft) => {\n const opts = {\n uid,\n locale: draft.locale,\n status: 'published',\n allowMissingId: true,\n useRequestCache: false,\n };\n return transformData(draft, opts);\n },\n // Create the published entry\n (draft) => createEntry({ ...params, data: draft, locale: draft.locale, status: 'published' })\n )(entry);\n }\n\n async function discardDraftEntry(entry: any, params = {} as any) {\n clearTransformDataRequestCache();\n\n return async.pipe(\n omit('id'),\n assoc('publishedAt', null),\n (entry) => {\n const opts = {\n uid,\n locale: entry.locale,\n status: 'draft',\n allowMissingId: true,\n useRequestCache: false,\n };\n return transformData(entry, opts);\n },\n // Create the draft entry\n (data) => createEntry({ ...params, locale: data.locale, data, status: 'draft' })\n )(entry);\n }\n\n return {\n create: createEntry,\n delete: deleteEntry,\n update: updateEntry,\n publish: publishEntry,\n discardDraft: discardDraftEntry,\n };\n};\n\nexport { createEntriesService };\n"],"names":["isStrictRelationsEnabled","rawStrictRelations","strapi","config","get","undefined","errors","ValidationError","createEntriesService","uid","entityValidator","contentType","createEntry","params","data","restParams","transformParamsDocumentId","query","transformParamsToQuery","pickSelectionParams","Error","documentId","i18nService","plugin","service","isLocalized","isLocalizedContentType","hasDraftAndPublish","options","draftAndPublish","whereClause","locale","publishedStateDescription","publishedAt","$notNull","$null","existingEntry","db","findOne","select","where","errorMsg","ApplicationError","validData","validateEntityCreation","isDraft","strictRelations","componentData","components","dataWithComponents","entryData","applyTransforms","doc","create","deleteEntry","id","componentsToDelete","deletedEntry","delete","loadComponents","updateEntry","entryToUpdate","validateEntityUpdate","update","publishEntry","entry","clearTransformDataRequestCache","async","pipe","omit","assoc","Date","draft","opts","status","allowMissingId","useRequestCache","transformData","discardDraftEntry","publish","discardDraft"],"mappings":"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"}
@@ -7,6 +7,18 @@ import { pickSelectionParams } from './params.mjs';
7
7
  import { applyTransforms } from './attributes/index.mjs';
8
8
  import { clearTransformDataRequestCache, transformData } from './transform/data.mjs';
9
9
 
10
+ /**
11
+ * Reads and validates the `api.documents.strictRelations` flag.
12
+ * false/undefined => legacy behaviour (relational required constraints not enforced),
13
+ * true => enforce required media and relations on non-draft writes.
14
+ * Mirrors the validation of `api.documents.strictParams` (see repository.ts).
15
+ */ const isStrictRelationsEnabled = ()=>{
16
+ const rawStrictRelations = strapi.config.get('api.documents.strictRelations', undefined);
17
+ if (rawStrictRelations !== undefined && rawStrictRelations !== false && rawStrictRelations !== true) {
18
+ throw new errors.ValidationError(`Invalid config.api.documents.strictRelations value: "${rawStrictRelations}". Expected boolean (true or false).`);
19
+ }
20
+ return rawStrictRelations === true;
21
+ };
10
22
  const createEntriesService = (uid, entityValidator)=>{
11
23
  const contentType = strapi.contentType(uid);
12
24
  async function createEntry(params = {}) {
@@ -61,7 +73,8 @@ const createEntriesService = (uid, entityValidator)=>{
61
73
  const validData = await entityValidator.validateEntityCreation(contentType, data, {
62
74
  // Note: publishedAt value will always be set when DP is disabled
63
75
  isDraft: !params?.data?.publishedAt,
64
- locale: params?.locale
76
+ locale: params?.locale,
77
+ strictRelations: isStrictRelationsEnabled()
65
78
  });
66
79
  // Component handling
67
80
  const componentData = await createComponents(uid, validData);
@@ -93,7 +106,8 @@ const createEntriesService = (uid, entityValidator)=>{
93
106
  const query = transformParamsToQuery(uid, pickSelectionParams(restParams)); // select / populate
94
107
  const validData = await entityValidator.validateEntityUpdate(contentType, data, {
95
108
  isDraft: !params?.data?.publishedAt,
96
- locale: params?.locale
109
+ locale: params?.locale,
110
+ strictRelations: isStrictRelationsEnabled()
97
111
  }, entryToUpdate);
98
112
  // Component handling
99
113
  const componentData = await updateComponents(uid, entryToUpdate, validData);
@@ -1 +1 @@
1
- {"version":3,"file":"entries.mjs","sources":["../../../src/services/document-service/entries.ts"],"sourcesContent":["import type { UID, Modules } from '@strapi/types';\nimport { async, errors } from '@strapi/utils';\nimport { assoc, omit } from 'lodash/fp';\n\nimport * as components from './components';\n\nimport { transformParamsDocumentId } from './transform/id-transform';\nimport { transformParamsToQuery } from './transform/query';\nimport { pickSelectionParams } from './params';\nimport { applyTransforms } from './attributes';\nimport { clearTransformDataRequestCache, transformData } from './transform/data';\n\nconst createEntriesService = (\n uid: UID.ContentType,\n entityValidator: Modules.EntityValidator.EntityValidator\n) => {\n const contentType = strapi.contentType(uid);\n\n async function createEntry(params = {} as any) {\n const { data, ...restParams } = await transformParamsDocumentId(uid, params);\n const query = transformParamsToQuery(uid, pickSelectionParams(restParams) as any); // select / populate\n\n // Validation\n if (!data) {\n throw new Error('Create requires data attribute');\n }\n\n // Check for uniqueness based on documentId and locale (if localized)\n if (data.documentId) {\n const i18nService = strapi.plugin('i18n')?.service('content-types');\n const isLocalized = i18nService?.isLocalizedContentType(contentType) ?? false;\n const hasDraftAndPublish = contentType.options?.draftAndPublish === true;\n\n const whereClause: Record<string, unknown> = { documentId: data.documentId };\n\n if (isLocalized) {\n whereClause.locale = data.locale;\n }\n\n let publishedStateDescription = '';\n\n if (hasDraftAndPublish) {\n if (data.publishedAt) {\n // Current entry is published, check for existing published entry\n whereClause.publishedAt = { $notNull: true };\n publishedStateDescription = 'published';\n } else {\n // Current entry is a draft, check for existing draft entry\n whereClause.publishedAt = { $null: true };\n publishedStateDescription = 'draft';\n }\n }\n\n const existingEntry = await strapi.db.query(uid).findOne({\n select: ['id'],\n where: whereClause,\n });\n\n if (existingEntry) {\n let errorMsg = `A ${publishedStateDescription} entry with documentId \"${data.documentId}\"`;\n if (isLocalized && data.locale) {\n errorMsg += ` and locale \"${data.locale}\"`;\n }\n errorMsg += ` already exists for UID \"${uid}\". This combination must be unique.`;\n throw new errors.ApplicationError(errorMsg);\n }\n }\n\n const validData = await entityValidator.validateEntityCreation(contentType, data, {\n // Note: publishedAt value will always be set when DP is disabled\n isDraft: !params?.data?.publishedAt,\n locale: params?.locale,\n });\n\n // Component handling\n const componentData = await components.createComponents(uid, validData);\n const dataWithComponents = components.assignComponentData(\n contentType,\n componentData,\n validData\n );\n\n const entryData = applyTransforms(contentType, dataWithComponents);\n\n const doc = await strapi.db.query(uid).create({ ...query, data: entryData });\n\n return doc;\n }\n\n async function deleteEntry(id: number, query = {} as any) {\n const componentsToDelete = await components.getComponents(uid, { id });\n\n const deletedEntry = await strapi.db.query(uid).delete({ ...query, where: { id } });\n\n await components.deleteComponents(uid, componentsToDelete as any, { loadComponents: false });\n\n return deletedEntry;\n }\n\n async function updateEntry(entryToUpdate: any, params = {} as any) {\n const { data, ...restParams } = await transformParamsDocumentId(uid, params);\n const query = transformParamsToQuery(uid, pickSelectionParams(restParams) as any); // select / populate\n\n const validData = await entityValidator.validateEntityUpdate(\n contentType,\n data,\n {\n isDraft: !params?.data?.publishedAt, // Always update the draft version\n locale: params?.locale,\n },\n entryToUpdate\n );\n // Component handling\n const componentData = await components.updateComponents(uid, entryToUpdate, validData as any);\n const dataWithComponents = components.assignComponentData(\n contentType,\n componentData,\n validData\n );\n\n const entryData = applyTransforms(contentType, dataWithComponents);\n\n return strapi.db\n .query(uid)\n .update({ ...query, where: { id: entryToUpdate.id }, data: entryData });\n }\n\n async function publishEntry(entry: any, params = {} as any) {\n clearTransformDataRequestCache();\n\n return async.pipe(\n omit('id'),\n assoc('publishedAt', new Date()),\n (draft) => {\n const opts = {\n uid,\n locale: draft.locale,\n status: 'published',\n allowMissingId: true,\n useRequestCache: false,\n };\n return transformData(draft, opts);\n },\n // Create the published entry\n (draft) => createEntry({ ...params, data: draft, locale: draft.locale, status: 'published' })\n )(entry);\n }\n\n async function discardDraftEntry(entry: any, params = {} as any) {\n clearTransformDataRequestCache();\n\n return async.pipe(\n omit('id'),\n assoc('publishedAt', null),\n (entry) => {\n const opts = {\n uid,\n locale: entry.locale,\n status: 'draft',\n allowMissingId: true,\n useRequestCache: false,\n };\n return transformData(entry, opts);\n },\n // Create the draft entry\n (data) => createEntry({ ...params, locale: data.locale, data, status: 'draft' })\n )(entry);\n }\n\n return {\n create: createEntry,\n delete: deleteEntry,\n update: updateEntry,\n publish: publishEntry,\n discardDraft: discardDraftEntry,\n };\n};\n\nexport { createEntriesService };\n"],"names":["createEntriesService","uid","entityValidator","contentType","strapi","createEntry","params","data","restParams","transformParamsDocumentId","query","transformParamsToQuery","pickSelectionParams","Error","documentId","i18nService","plugin","service","isLocalized","isLocalizedContentType","hasDraftAndPublish","options","draftAndPublish","whereClause","locale","publishedStateDescription","publishedAt","$notNull","$null","existingEntry","db","findOne","select","where","errorMsg","errors","ApplicationError","validData","validateEntityCreation","isDraft","componentData","components","dataWithComponents","entryData","applyTransforms","doc","create","deleteEntry","id","componentsToDelete","deletedEntry","delete","loadComponents","updateEntry","entryToUpdate","validateEntityUpdate","update","publishEntry","entry","clearTransformDataRequestCache","async","pipe","omit","assoc","Date","draft","opts","status","allowMissingId","useRequestCache","transformData","discardDraftEntry","publish","discardDraft"],"mappings":";;;;;;;;;AAYA,MAAMA,oBAAAA,GAAuB,CAC3BC,GAAAA,EACAC,eAAAA,GAAAA;IAEA,MAAMC,WAAAA,GAAcC,MAAAA,CAAOD,WAAW,CAACF,GAAAA,CAAAA;IAEvC,eAAeI,WAAAA,CAAYC,MAAAA,GAAS,EAAS,EAAA;QAC3C,MAAM,EAAEC,IAAI,EAAE,GAAGC,YAAY,GAAG,MAAMC,iCAA0BR,GAAAA,EAAKK,MAAAA,CAAAA;AACrE,QAAA,MAAMI,KAAAA,GAAQC,sBAAAA,CAAuBV,GAAAA,EAAKW,mBAAAA,CAAoBJ;;AAG9D,QAAA,IAAI,CAACD,IAAAA,EAAM;AACT,YAAA,MAAM,IAAIM,KAAAA,CAAM,gCAAA,CAAA;AAClB,QAAA;;QAGA,IAAIN,IAAAA,CAAKO,UAAU,EAAE;AACnB,YAAA,MAAMC,WAAAA,GAAcX,MAAAA,CAAOY,MAAM,CAAC,SAASC,OAAAA,CAAQ,eAAA,CAAA;YACnD,MAAMC,WAAAA,GAAcH,WAAAA,EAAaI,sBAAAA,CAAuBhB,WAAAA,CAAAA,IAAgB,KAAA;AACxE,YAAA,MAAMiB,kBAAAA,GAAqBjB,WAAAA,CAAYkB,OAAO,EAAEC,eAAAA,KAAoB,IAAA;AAEpE,YAAA,MAAMC,WAAAA,GAAuC;AAAET,gBAAAA,UAAAA,EAAYP,KAAKO;AAAW,aAAA;AAE3E,YAAA,IAAII,WAAAA,EAAa;gBACfK,WAAAA,CAAYC,MAAM,GAAGjB,IAAAA,CAAKiB,MAAM;AAClC,YAAA;AAEA,YAAA,IAAIC,yBAAAA,GAA4B,EAAA;AAEhC,YAAA,IAAIL,kBAAAA,EAAoB;gBACtB,IAAIb,IAAAA,CAAKmB,WAAW,EAAE;;AAEpBH,oBAAAA,WAAAA,CAAYG,WAAW,GAAG;wBAAEC,QAAAA,EAAU;AAAK,qBAAA;oBAC3CF,yBAAAA,GAA4B,WAAA;gBAC9B,CAAA,MAAO;;AAELF,oBAAAA,WAAAA,CAAYG,WAAW,GAAG;wBAAEE,KAAAA,EAAO;AAAK,qBAAA;oBACxCH,yBAAAA,GAA4B,OAAA;AAC9B,gBAAA;AACF,YAAA;YAEA,MAAMI,aAAAA,GAAgB,MAAMzB,MAAAA,CAAO0B,EAAE,CAACpB,KAAK,CAACT,GAAAA,CAAAA,CAAK8B,OAAO,CAAC;gBACvDC,MAAAA,EAAQ;AAAC,oBAAA;AAAK,iBAAA;gBACdC,KAAAA,EAAOV;AACT,aAAA,CAAA;AAEA,YAAA,IAAIM,aAAAA,EAAe;gBACjB,IAAIK,QAAAA,GAAW,CAAC,EAAE,EAAET,yBAAAA,CAA0B,wBAAwB,EAAElB,IAAAA,CAAKO,UAAU,CAAC,CAAC,CAAC;gBAC1F,IAAII,WAAAA,IAAeX,IAAAA,CAAKiB,MAAM,EAAE;AAC9BU,oBAAAA,QAAAA,IAAY,CAAC,aAAa,EAAE3B,KAAKiB,MAAM,CAAC,CAAC,CAAC;AAC5C,gBAAA;AACAU,gBAAAA,QAAAA,IAAY,CAAC,yBAAyB,EAAEjC,GAAAA,CAAI,mCAAmC,CAAC;gBAChF,MAAM,IAAIkC,MAAAA,CAAOC,gBAAgB,CAACF,QAAAA,CAAAA;AACpC,YAAA;AACF,QAAA;AAEA,QAAA,MAAMG,YAAY,MAAMnC,eAAAA,CAAgBoC,sBAAsB,CAACnC,aAAaI,IAAAA,EAAM;;YAEhFgC,OAAAA,EAAS,CAACjC,QAAQC,IAAAA,EAAMmB,WAAAA;AACxBF,YAAAA,MAAAA,EAAQlB,MAAAA,EAAQkB;AAClB,SAAA,CAAA;;AAGA,QAAA,MAAMgB,aAAAA,GAAgB,MAAMC,gBAA2B,CAACxC,GAAAA,EAAKoC,SAAAA,CAAAA;AAC7D,QAAA,MAAMK,kBAAAA,GAAqBD,mBAA8B,CACvDtC,aACAqC,aAAAA,EACAH,SAAAA,CAAAA;QAGF,MAAMM,SAAAA,GAAYC,gBAAgBzC,WAAAA,EAAauC,kBAAAA,CAAAA;QAE/C,MAAMG,GAAAA,GAAM,MAAMzC,MAAAA,CAAO0B,EAAE,CAACpB,KAAK,CAACT,GAAAA,CAAAA,CAAK6C,MAAM,CAAC;AAAE,YAAA,GAAGpC,KAAK;YAAEH,IAAAA,EAAMoC;AAAU,SAAA,CAAA;QAE1E,OAAOE,GAAAA;AACT,IAAA;AAEA,IAAA,eAAeE,WAAAA,CAAYC,EAAU,EAAEtC,KAAAA,GAAQ,EAAS,EAAA;AACtD,QAAA,MAAMuC,kBAAAA,GAAqB,MAAMR,aAAwB,CAACxC,GAAAA,EAAK;AAAE+C,YAAAA;AAAG,SAAA,CAAA;QAEpE,MAAME,YAAAA,GAAe,MAAM9C,MAAAA,CAAO0B,EAAE,CAACpB,KAAK,CAACT,GAAAA,CAAAA,CAAKkD,MAAM,CAAC;AAAE,YAAA,GAAGzC,KAAK;YAAEuB,KAAAA,EAAO;AAAEe,gBAAAA;AAAG;AAAE,SAAA,CAAA;AAEjF,QAAA,MAAMP,gBAA2B,CAACxC,GAAAA,EAAKgD,kBAAAA,EAA2B;YAAEG,cAAAA,EAAgB;AAAM,SAAA,CAAA;QAE1F,OAAOF,YAAAA;AACT,IAAA;AAEA,IAAA,eAAeG,WAAAA,CAAYC,aAAkB,EAAEhD,MAAAA,GAAS,EAAS,EAAA;QAC/D,MAAM,EAAEC,IAAI,EAAE,GAAGC,YAAY,GAAG,MAAMC,iCAA0BR,GAAAA,EAAKK,MAAAA,CAAAA;AACrE,QAAA,MAAMI,KAAAA,GAAQC,sBAAAA,CAAuBV,GAAAA,EAAKW,mBAAAA,CAAoBJ;AAE9D,QAAA,MAAM6B,YAAY,MAAMnC,eAAAA,CAAgBqD,oBAAoB,CAC1DpD,aACAI,IAAAA,EACA;YACEgC,OAAAA,EAAS,CAACjC,QAAQC,IAAAA,EAAMmB,WAAAA;AACxBF,YAAAA,MAAAA,EAAQlB,MAAAA,EAAQkB;SAClB,EACA8B,aAAAA,CAAAA;;AAGF,QAAA,MAAMd,gBAAgB,MAAMC,gBAA2B,CAACxC,KAAKqD,aAAAA,EAAejB,SAAAA,CAAAA;AAC5E,QAAA,MAAMK,kBAAAA,GAAqBD,mBAA8B,CACvDtC,aACAqC,aAAAA,EACAH,SAAAA,CAAAA;QAGF,MAAMM,SAAAA,GAAYC,gBAAgBzC,WAAAA,EAAauC,kBAAAA,CAAAA;AAE/C,QAAA,OAAOtC,OAAO0B,EAAE,CACbpB,KAAK,CAACT,GAAAA,CAAAA,CACNuD,MAAM,CAAC;AAAE,YAAA,GAAG9C,KAAK;YAAEuB,KAAAA,EAAO;AAAEe,gBAAAA,EAAAA,EAAIM,cAAcN;AAAG,aAAA;YAAGzC,IAAAA,EAAMoC;AAAU,SAAA,CAAA;AACzE,IAAA;AAEA,IAAA,eAAec,YAAAA,CAAaC,KAAU,EAAEpD,MAAAA,GAAS,EAAS,EAAA;AACxDqD,QAAAA,8BAAAA,EAAAA;QAEA,OAAOC,KAAAA,CAAMC,IAAI,CACfC,IAAAA,CAAK,OACLC,KAAAA,CAAM,aAAA,EAAe,IAAIC,IAAAA,EAAAA,CAAAA,EACzB,CAACC,KAAAA,GAAAA;AACC,YAAA,MAAMC,IAAAA,GAAO;AACXjE,gBAAAA,GAAAA;AACAuB,gBAAAA,MAAAA,EAAQyC,MAAMzC,MAAM;gBACpB2C,MAAAA,EAAQ,WAAA;gBACRC,cAAAA,EAAgB,IAAA;gBAChBC,eAAAA,EAAiB;AACnB,aAAA;AACA,YAAA,OAAOC,cAAcL,KAAAA,EAAOC,IAAAA,CAAAA;AAC9B,QAAA,CAAA;AAEA,QAAA,CAACD,QAAU5D,WAAAA,CAAY;AAAE,gBAAA,GAAGC,MAAM;gBAAEC,IAAAA,EAAM0D,KAAAA;AAAOzC,gBAAAA,MAAAA,EAAQyC,MAAMzC,MAAM;gBAAE2C,MAAAA,EAAQ;aAAY,CAAA,CAAA,CAC3FT,KAAAA,CAAAA;AACJ,IAAA;AAEA,IAAA,eAAea,iBAAAA,CAAkBb,KAAU,EAAEpD,MAAAA,GAAS,EAAS,EAAA;AAC7DqD,QAAAA,8BAAAA,EAAAA;QAEA,OAAOC,KAAAA,CAAMC,IAAI,CACfC,IAAAA,CAAK,OACLC,KAAAA,CAAM,aAAA,EAAe,OACrB,CAACL,KAAAA,GAAAA;AACC,YAAA,MAAMQ,IAAAA,GAAO;AACXjE,gBAAAA,GAAAA;AACAuB,gBAAAA,MAAAA,EAAQkC,MAAMlC,MAAM;gBACpB2C,MAAAA,EAAQ,OAAA;gBACRC,cAAAA,EAAgB,IAAA;gBAChBC,eAAAA,EAAiB;AACnB,aAAA;AACA,YAAA,OAAOC,cAAcZ,KAAAA,EAAOQ,IAAAA,CAAAA;AAC9B,QAAA,CAAA;AAEA,QAAA,CAAC3D,OAASF,WAAAA,CAAY;AAAE,gBAAA,GAAGC,MAAM;AAAEkB,gBAAAA,MAAAA,EAAQjB,KAAKiB,MAAM;AAAEjB,gBAAAA,IAAAA;gBAAM4D,MAAAA,EAAQ;aAAQ,CAAA,CAAA,CAC9ET,KAAAA,CAAAA;AACJ,IAAA;IAEA,OAAO;QACLZ,MAAAA,EAAQzC,WAAAA;QACR8C,MAAAA,EAAQJ,WAAAA;QACRS,MAAAA,EAAQH,WAAAA;QACRmB,OAAAA,EAASf,YAAAA;QACTgB,YAAAA,EAAcF;AAChB,KAAA;AACF;;;;"}
1
+ {"version":3,"file":"entries.mjs","sources":["../../../src/services/document-service/entries.ts"],"sourcesContent":["import type { UID, Modules } from '@strapi/types';\nimport { async, errors } from '@strapi/utils';\nimport { assoc, omit } from 'lodash/fp';\n\nimport * as components from './components';\n\nimport { transformParamsDocumentId } from './transform/id-transform';\nimport { transformParamsToQuery } from './transform/query';\nimport { pickSelectionParams } from './params';\nimport { applyTransforms } from './attributes';\nimport { clearTransformDataRequestCache, transformData } from './transform/data';\n\n/**\n * Reads and validates the `api.documents.strictRelations` flag.\n * false/undefined => legacy behaviour (relational required constraints not enforced),\n * true => enforce required media and relations on non-draft writes.\n * Mirrors the validation of `api.documents.strictParams` (see repository.ts).\n */\nconst isStrictRelationsEnabled = (): boolean => {\n const rawStrictRelations: unknown = strapi.config.get('api.documents.strictRelations', undefined);\n\n if (\n rawStrictRelations !== undefined &&\n rawStrictRelations !== false &&\n rawStrictRelations !== true\n ) {\n throw new errors.ValidationError(\n `Invalid config.api.documents.strictRelations value: \"${rawStrictRelations}\". Expected boolean (true or false).`\n );\n }\n\n return rawStrictRelations === true;\n};\n\nconst createEntriesService = (\n uid: UID.ContentType,\n entityValidator: Modules.EntityValidator.EntityValidator\n) => {\n const contentType = strapi.contentType(uid);\n\n async function createEntry(params = {} as any) {\n const { data, ...restParams } = await transformParamsDocumentId(uid, params);\n const query = transformParamsToQuery(uid, pickSelectionParams(restParams) as any); // select / populate\n\n // Validation\n if (!data) {\n throw new Error('Create requires data attribute');\n }\n\n // Check for uniqueness based on documentId and locale (if localized)\n if (data.documentId) {\n const i18nService = strapi.plugin('i18n')?.service('content-types');\n const isLocalized = i18nService?.isLocalizedContentType(contentType) ?? false;\n const hasDraftAndPublish = contentType.options?.draftAndPublish === true;\n\n const whereClause: Record<string, unknown> = { documentId: data.documentId };\n\n if (isLocalized) {\n whereClause.locale = data.locale;\n }\n\n let publishedStateDescription = '';\n\n if (hasDraftAndPublish) {\n if (data.publishedAt) {\n // Current entry is published, check for existing published entry\n whereClause.publishedAt = { $notNull: true };\n publishedStateDescription = 'published';\n } else {\n // Current entry is a draft, check for existing draft entry\n whereClause.publishedAt = { $null: true };\n publishedStateDescription = 'draft';\n }\n }\n\n const existingEntry = await strapi.db.query(uid).findOne({\n select: ['id'],\n where: whereClause,\n });\n\n if (existingEntry) {\n let errorMsg = `A ${publishedStateDescription} entry with documentId \"${data.documentId}\"`;\n if (isLocalized && data.locale) {\n errorMsg += ` and locale \"${data.locale}\"`;\n }\n errorMsg += ` already exists for UID \"${uid}\". This combination must be unique.`;\n throw new errors.ApplicationError(errorMsg);\n }\n }\n\n const validData = await entityValidator.validateEntityCreation(contentType, data, {\n // Note: publishedAt value will always be set when DP is disabled\n isDraft: !params?.data?.publishedAt,\n locale: params?.locale,\n strictRelations: isStrictRelationsEnabled(),\n });\n\n // Component handling\n const componentData = await components.createComponents(uid, validData);\n const dataWithComponents = components.assignComponentData(\n contentType,\n componentData,\n validData\n );\n\n const entryData = applyTransforms(contentType, dataWithComponents);\n\n const doc = await strapi.db.query(uid).create({ ...query, data: entryData });\n\n return doc;\n }\n\n async function deleteEntry(id: number, query = {} as any) {\n const componentsToDelete = await components.getComponents(uid, { id });\n\n const deletedEntry = await strapi.db.query(uid).delete({ ...query, where: { id } });\n\n await components.deleteComponents(uid, componentsToDelete as any, { loadComponents: false });\n\n return deletedEntry;\n }\n\n async function updateEntry(entryToUpdate: any, params = {} as any) {\n const { data, ...restParams } = await transformParamsDocumentId(uid, params);\n const query = transformParamsToQuery(uid, pickSelectionParams(restParams) as any); // select / populate\n\n const validData = await entityValidator.validateEntityUpdate(\n contentType,\n data,\n {\n isDraft: !params?.data?.publishedAt, // Always update the draft version\n locale: params?.locale,\n strictRelations: isStrictRelationsEnabled(),\n },\n entryToUpdate\n );\n // Component handling\n const componentData = await components.updateComponents(uid, entryToUpdate, validData as any);\n const dataWithComponents = components.assignComponentData(\n contentType,\n componentData,\n validData\n );\n\n const entryData = applyTransforms(contentType, dataWithComponents);\n\n return strapi.db\n .query(uid)\n .update({ ...query, where: { id: entryToUpdate.id }, data: entryData });\n }\n\n async function publishEntry(entry: any, params = {} as any) {\n clearTransformDataRequestCache();\n\n return async.pipe(\n omit('id'),\n assoc('publishedAt', new Date()),\n (draft) => {\n const opts = {\n uid,\n locale: draft.locale,\n status: 'published',\n allowMissingId: true,\n useRequestCache: false,\n };\n return transformData(draft, opts);\n },\n // Create the published entry\n (draft) => createEntry({ ...params, data: draft, locale: draft.locale, status: 'published' })\n )(entry);\n }\n\n async function discardDraftEntry(entry: any, params = {} as any) {\n clearTransformDataRequestCache();\n\n return async.pipe(\n omit('id'),\n assoc('publishedAt', null),\n (entry) => {\n const opts = {\n uid,\n locale: entry.locale,\n status: 'draft',\n allowMissingId: true,\n useRequestCache: false,\n };\n return transformData(entry, opts);\n },\n // Create the draft entry\n (data) => createEntry({ ...params, locale: data.locale, data, status: 'draft' })\n )(entry);\n }\n\n return {\n create: createEntry,\n delete: deleteEntry,\n update: updateEntry,\n publish: publishEntry,\n discardDraft: discardDraftEntry,\n };\n};\n\nexport { createEntriesService };\n"],"names":["isStrictRelationsEnabled","rawStrictRelations","strapi","config","get","undefined","errors","ValidationError","createEntriesService","uid","entityValidator","contentType","createEntry","params","data","restParams","transformParamsDocumentId","query","transformParamsToQuery","pickSelectionParams","Error","documentId","i18nService","plugin","service","isLocalized","isLocalizedContentType","hasDraftAndPublish","options","draftAndPublish","whereClause","locale","publishedStateDescription","publishedAt","$notNull","$null","existingEntry","db","findOne","select","where","errorMsg","ApplicationError","validData","validateEntityCreation","isDraft","strictRelations","componentData","components","dataWithComponents","entryData","applyTransforms","doc","create","deleteEntry","id","componentsToDelete","deletedEntry","delete","loadComponents","updateEntry","entryToUpdate","validateEntityUpdate","update","publishEntry","entry","clearTransformDataRequestCache","async","pipe","omit","assoc","Date","draft","opts","status","allowMissingId","useRequestCache","transformData","discardDraftEntry","publish","discardDraft"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"first-published-at.d.ts","sourceRoot":"","sources":["../../../src/services/document-service/first-published-at.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAErD,KAAK,aAAa,GAAG,CAAC,aAAa,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;AACvE,KAAK,eAAe,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,KAAK,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC;AAE9F,QAAA,MAAM,0BAA0B,GAC9B,OAAO,GAAG,EACV,QAAQ,aAAa,EACrB,aAAa,MAAM,CAAC,WAAW,iBAsBhC,CAAC;AAEF,QAAA,MAAM,0BAA0B,EAAE,eAMjC,CAAC;AAEF,OAAO,EAAE,0BAA0B,EAAE,0BAA0B,EAAE,CAAC"}
1
+ {"version":3,"file":"first-published-at.d.ts","sourceRoot":"","sources":["../../../src/services/document-service/first-published-at.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAErD,KAAK,aAAa,GAAG,CAAC,aAAa,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;AACvE,KAAK,eAAe,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,KAAK,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC;AAE9F,QAAA,MAAM,0BAA0B,GAC9B,OAAO,GAAG,EACV,QAAQ,aAAa,EACrB,aAAa,MAAM,CAAC,WAAW,iBA8BhC,CAAC;AAEF,QAAA,MAAM,0BAA0B,EAAE,eAMjC,CAAC;AAEF,OAAO,EAAE,0BAA0B,EAAE,0BAA0B,EAAE,CAAC"}
@@ -16,14 +16,21 @@ const addFirstPublishedAtToDraft = async (draft, update, contentType)=>{
16
16
  // strip media, components, dynamic zones and relations from the draft that
17
17
  // downstream publishEntry relies on. Instead we carry forward the already
18
18
  // populated draft from repository.publish's findMany with the field merged in.
19
- await update(draft, {
19
+ const updatedDraft = await update(draft, {
20
20
  data: {
21
21
  firstPublishedAt: now
22
22
  }
23
23
  });
24
24
  return {
25
25
  ...draft,
26
- firstPublishedAt: now
26
+ firstPublishedAt: now,
27
+ // Propagate the server-side updatedAt so the entry's updatedAt is not
28
+ // earlier than firstPublishedAt. Without this the entry will appear
29
+ // "modified" after its first publish (updatedAt < firstPublishedAt),
30
+ // even though the only change was stamping firstPublishedAt.
31
+ ...updatedDraft.updatedAt && {
32
+ updatedAt: updatedDraft.updatedAt
33
+ }
27
34
  };
28
35
  };
29
36
  const filterDataFirstPublishedAt = (params)=>{
@@ -1 +1 @@
1
- {"version":3,"file":"first-published-at.js","sources":["../../../src/services/document-service/first-published-at.ts"],"sourcesContent":["import { contentTypes } from '@strapi/utils';\nimport { assoc } from 'lodash/fp';\nimport type { Modules, Schema } from '@strapi/types';\n\ntype EntriesUpdate = (entryToUpdate: any, param?: any) => Promise<any>;\ntype ParamsTransform = (params: Modules.Documents.Params.All) => Modules.Documents.Params.All;\n\nconst addFirstPublishedAtToDraft = async (\n draft: any,\n update: EntriesUpdate,\n contentType: Schema.ContentType\n) => {\n if (!contentTypes.hasFirstPublishedAtField(contentType)) {\n return draft;\n }\n\n if (draft.firstPublishedAt) {\n return draft;\n }\n\n const now = new Date();\n\n // Persist to the draft DB row, but discard the return value: entries.update\n // returns an unpopulated findOne (no populate is passed through), which would\n // strip media, components, dynamic zones and relations from the draft that\n // downstream publishEntry relies on. Instead we carry forward the already\n // populated draft from repository.publish's findMany with the field merged in.\n await update(draft, {\n data: { firstPublishedAt: now },\n });\n\n return { ...draft, firstPublishedAt: now };\n};\n\nconst filterDataFirstPublishedAt: ParamsTransform = (params) => {\n if (params?.data?.firstPublishedAt) {\n return assoc(['data', 'firstPublishedAt'], null, params);\n }\n\n return params;\n};\n\nexport { addFirstPublishedAtToDraft, filterDataFirstPublishedAt };\n"],"names":["addFirstPublishedAtToDraft","draft","update","contentType","contentTypes","hasFirstPublishedAtField","firstPublishedAt","now","Date","data","filterDataFirstPublishedAt","params","assoc"],"mappings":";;;;;AAOA,MAAMA,0BAAAA,GAA6B,OACjCC,KAAAA,EACAC,MAAAA,EACAC,WAAAA,GAAAA;AAEA,IAAA,IAAI,CAACC,wBAAAA,CAAaC,wBAAwB,CAACF,WAAAA,CAAAA,EAAc;QACvD,OAAOF,KAAAA;AACT,IAAA;IAEA,IAAIA,KAAAA,CAAMK,gBAAgB,EAAE;QAC1B,OAAOL,KAAAA;AACT,IAAA;AAEA,IAAA,MAAMM,MAAM,IAAIC,IAAAA,EAAAA;;;;;;AAOhB,IAAA,MAAMN,OAAOD,KAAAA,EAAO;QAClBQ,IAAAA,EAAM;YAAEH,gBAAAA,EAAkBC;AAAI;AAChC,KAAA,CAAA;IAEA,OAAO;AAAE,QAAA,GAAGN,KAAK;QAAEK,gBAAAA,EAAkBC;AAAI,KAAA;AAC3C;AAEA,MAAMG,6BAA8C,CAACC,MAAAA,GAAAA;IACnD,IAAIA,MAAAA,EAAQF,MAAMH,gBAAAA,EAAkB;AAClC,QAAA,OAAOM,QAAAA,CAAM;AAAC,YAAA,MAAA;AAAQ,YAAA;AAAmB,SAAA,EAAE,IAAA,EAAMD,MAAAA,CAAAA;AACnD,IAAA;IAEA,OAAOA,MAAAA;AACT;;;;;"}
1
+ {"version":3,"file":"first-published-at.js","sources":["../../../src/services/document-service/first-published-at.ts"],"sourcesContent":["import { contentTypes } from '@strapi/utils';\nimport { assoc } from 'lodash/fp';\nimport type { Modules, Schema } from '@strapi/types';\n\ntype EntriesUpdate = (entryToUpdate: any, param?: any) => Promise<any>;\ntype ParamsTransform = (params: Modules.Documents.Params.All) => Modules.Documents.Params.All;\n\nconst addFirstPublishedAtToDraft = async (\n draft: any,\n update: EntriesUpdate,\n contentType: Schema.ContentType\n) => {\n if (!contentTypes.hasFirstPublishedAtField(contentType)) {\n return draft;\n }\n\n if (draft.firstPublishedAt) {\n return draft;\n }\n\n const now = new Date();\n\n // Persist to the draft DB row, but discard the return value: entries.update\n // returns an unpopulated findOne (no populate is passed through), which would\n // strip media, components, dynamic zones and relations from the draft that\n // downstream publishEntry relies on. Instead we carry forward the already\n // populated draft from repository.publish's findMany with the field merged in.\n const updatedDraft = await update(draft, {\n data: { firstPublishedAt: now },\n });\n\n return {\n ...draft,\n firstPublishedAt: now,\n // Propagate the server-side updatedAt so the entry's updatedAt is not\n // earlier than firstPublishedAt. Without this the entry will appear\n // \"modified\" after its first publish (updatedAt < firstPublishedAt),\n // even though the only change was stamping firstPublishedAt.\n ...(updatedDraft.updatedAt && { updatedAt: updatedDraft.updatedAt }),\n };\n};\n\nconst filterDataFirstPublishedAt: ParamsTransform = (params) => {\n if (params?.data?.firstPublishedAt) {\n return assoc(['data', 'firstPublishedAt'], null, params);\n }\n\n return params;\n};\n\nexport { addFirstPublishedAtToDraft, filterDataFirstPublishedAt };\n"],"names":["addFirstPublishedAtToDraft","draft","update","contentType","contentTypes","hasFirstPublishedAtField","firstPublishedAt","now","Date","updatedDraft","data","updatedAt","filterDataFirstPublishedAt","params","assoc"],"mappings":";;;;;AAOA,MAAMA,0BAAAA,GAA6B,OACjCC,KAAAA,EACAC,MAAAA,EACAC,WAAAA,GAAAA;AAEA,IAAA,IAAI,CAACC,wBAAAA,CAAaC,wBAAwB,CAACF,WAAAA,CAAAA,EAAc;QACvD,OAAOF,KAAAA;AACT,IAAA;IAEA,IAAIA,KAAAA,CAAMK,gBAAgB,EAAE;QAC1B,OAAOL,KAAAA;AACT,IAAA;AAEA,IAAA,MAAMM,MAAM,IAAIC,IAAAA,EAAAA;;;;;;IAOhB,MAAMC,YAAAA,GAAe,MAAMP,MAAAA,CAAOD,KAAAA,EAAO;QACvCS,IAAAA,EAAM;YAAEJ,gBAAAA,EAAkBC;AAAI;AAChC,KAAA,CAAA;IAEA,OAAO;AACL,QAAA,GAAGN,KAAK;QACRK,gBAAAA,EAAkBC,GAAAA;;;;;QAKlB,GAAIE,YAAAA,CAAaE,SAAS,IAAI;AAAEA,YAAAA,SAAAA,EAAWF,aAAaE;;AAC1D,KAAA;AACF;AAEA,MAAMC,6BAA8C,CAACC,MAAAA,GAAAA;IACnD,IAAIA,MAAAA,EAAQH,MAAMJ,gBAAAA,EAAkB;AAClC,QAAA,OAAOQ,QAAAA,CAAM;AAAC,YAAA,MAAA;AAAQ,YAAA;AAAmB,SAAA,EAAE,IAAA,EAAMD,MAAAA,CAAAA;AACnD,IAAA;IAEA,OAAOA,MAAAA;AACT;;;;;"}
@@ -14,14 +14,21 @@ const addFirstPublishedAtToDraft = async (draft, update, contentType)=>{
14
14
  // strip media, components, dynamic zones and relations from the draft that
15
15
  // downstream publishEntry relies on. Instead we carry forward the already
16
16
  // populated draft from repository.publish's findMany with the field merged in.
17
- await update(draft, {
17
+ const updatedDraft = await update(draft, {
18
18
  data: {
19
19
  firstPublishedAt: now
20
20
  }
21
21
  });
22
22
  return {
23
23
  ...draft,
24
- firstPublishedAt: now
24
+ firstPublishedAt: now,
25
+ // Propagate the server-side updatedAt so the entry's updatedAt is not
26
+ // earlier than firstPublishedAt. Without this the entry will appear
27
+ // "modified" after its first publish (updatedAt < firstPublishedAt),
28
+ // even though the only change was stamping firstPublishedAt.
29
+ ...updatedDraft.updatedAt && {
30
+ updatedAt: updatedDraft.updatedAt
31
+ }
25
32
  };
26
33
  };
27
34
  const filterDataFirstPublishedAt = (params)=>{
@@ -1 +1 @@
1
- {"version":3,"file":"first-published-at.mjs","sources":["../../../src/services/document-service/first-published-at.ts"],"sourcesContent":["import { contentTypes } from '@strapi/utils';\nimport { assoc } from 'lodash/fp';\nimport type { Modules, Schema } from '@strapi/types';\n\ntype EntriesUpdate = (entryToUpdate: any, param?: any) => Promise<any>;\ntype ParamsTransform = (params: Modules.Documents.Params.All) => Modules.Documents.Params.All;\n\nconst addFirstPublishedAtToDraft = async (\n draft: any,\n update: EntriesUpdate,\n contentType: Schema.ContentType\n) => {\n if (!contentTypes.hasFirstPublishedAtField(contentType)) {\n return draft;\n }\n\n if (draft.firstPublishedAt) {\n return draft;\n }\n\n const now = new Date();\n\n // Persist to the draft DB row, but discard the return value: entries.update\n // returns an unpopulated findOne (no populate is passed through), which would\n // strip media, components, dynamic zones and relations from the draft that\n // downstream publishEntry relies on. Instead we carry forward the already\n // populated draft from repository.publish's findMany with the field merged in.\n await update(draft, {\n data: { firstPublishedAt: now },\n });\n\n return { ...draft, firstPublishedAt: now };\n};\n\nconst filterDataFirstPublishedAt: ParamsTransform = (params) => {\n if (params?.data?.firstPublishedAt) {\n return assoc(['data', 'firstPublishedAt'], null, params);\n }\n\n return params;\n};\n\nexport { addFirstPublishedAtToDraft, filterDataFirstPublishedAt };\n"],"names":["addFirstPublishedAtToDraft","draft","update","contentType","contentTypes","hasFirstPublishedAtField","firstPublishedAt","now","Date","data","filterDataFirstPublishedAt","params","assoc"],"mappings":";;;AAOA,MAAMA,0BAAAA,GAA6B,OACjCC,KAAAA,EACAC,MAAAA,EACAC,WAAAA,GAAAA;AAEA,IAAA,IAAI,CAACC,YAAAA,CAAaC,wBAAwB,CAACF,WAAAA,CAAAA,EAAc;QACvD,OAAOF,KAAAA;AACT,IAAA;IAEA,IAAIA,KAAAA,CAAMK,gBAAgB,EAAE;QAC1B,OAAOL,KAAAA;AACT,IAAA;AAEA,IAAA,MAAMM,MAAM,IAAIC,IAAAA,EAAAA;;;;;;AAOhB,IAAA,MAAMN,OAAOD,KAAAA,EAAO;QAClBQ,IAAAA,EAAM;YAAEH,gBAAAA,EAAkBC;AAAI;AAChC,KAAA,CAAA;IAEA,OAAO;AAAE,QAAA,GAAGN,KAAK;QAAEK,gBAAAA,EAAkBC;AAAI,KAAA;AAC3C;AAEA,MAAMG,6BAA8C,CAACC,MAAAA,GAAAA;IACnD,IAAIA,MAAAA,EAAQF,MAAMH,gBAAAA,EAAkB;AAClC,QAAA,OAAOM,KAAAA,CAAM;AAAC,YAAA,MAAA;AAAQ,YAAA;AAAmB,SAAA,EAAE,IAAA,EAAMD,MAAAA,CAAAA;AACnD,IAAA;IAEA,OAAOA,MAAAA;AACT;;;;"}
1
+ {"version":3,"file":"first-published-at.mjs","sources":["../../../src/services/document-service/first-published-at.ts"],"sourcesContent":["import { contentTypes } from '@strapi/utils';\nimport { assoc } from 'lodash/fp';\nimport type { Modules, Schema } from '@strapi/types';\n\ntype EntriesUpdate = (entryToUpdate: any, param?: any) => Promise<any>;\ntype ParamsTransform = (params: Modules.Documents.Params.All) => Modules.Documents.Params.All;\n\nconst addFirstPublishedAtToDraft = async (\n draft: any,\n update: EntriesUpdate,\n contentType: Schema.ContentType\n) => {\n if (!contentTypes.hasFirstPublishedAtField(contentType)) {\n return draft;\n }\n\n if (draft.firstPublishedAt) {\n return draft;\n }\n\n const now = new Date();\n\n // Persist to the draft DB row, but discard the return value: entries.update\n // returns an unpopulated findOne (no populate is passed through), which would\n // strip media, components, dynamic zones and relations from the draft that\n // downstream publishEntry relies on. Instead we carry forward the already\n // populated draft from repository.publish's findMany with the field merged in.\n const updatedDraft = await update(draft, {\n data: { firstPublishedAt: now },\n });\n\n return {\n ...draft,\n firstPublishedAt: now,\n // Propagate the server-side updatedAt so the entry's updatedAt is not\n // earlier than firstPublishedAt. Without this the entry will appear\n // \"modified\" after its first publish (updatedAt < firstPublishedAt),\n // even though the only change was stamping firstPublishedAt.\n ...(updatedDraft.updatedAt && { updatedAt: updatedDraft.updatedAt }),\n };\n};\n\nconst filterDataFirstPublishedAt: ParamsTransform = (params) => {\n if (params?.data?.firstPublishedAt) {\n return assoc(['data', 'firstPublishedAt'], null, params);\n }\n\n return params;\n};\n\nexport { addFirstPublishedAtToDraft, filterDataFirstPublishedAt };\n"],"names":["addFirstPublishedAtToDraft","draft","update","contentType","contentTypes","hasFirstPublishedAtField","firstPublishedAt","now","Date","updatedDraft","data","updatedAt","filterDataFirstPublishedAt","params","assoc"],"mappings":";;;AAOA,MAAMA,0BAAAA,GAA6B,OACjCC,KAAAA,EACAC,MAAAA,EACAC,WAAAA,GAAAA;AAEA,IAAA,IAAI,CAACC,YAAAA,CAAaC,wBAAwB,CAACF,WAAAA,CAAAA,EAAc;QACvD,OAAOF,KAAAA;AACT,IAAA;IAEA,IAAIA,KAAAA,CAAMK,gBAAgB,EAAE;QAC1B,OAAOL,KAAAA;AACT,IAAA;AAEA,IAAA,MAAMM,MAAM,IAAIC,IAAAA,EAAAA;;;;;;IAOhB,MAAMC,YAAAA,GAAe,MAAMP,MAAAA,CAAOD,KAAAA,EAAO;QACvCS,IAAAA,EAAM;YAAEJ,gBAAAA,EAAkBC;AAAI;AAChC,KAAA,CAAA;IAEA,OAAO;AACL,QAAA,GAAGN,KAAK;QACRK,gBAAAA,EAAkBC,GAAAA;;;;;QAKlB,GAAIE,YAAAA,CAAaE,SAAS,IAAI;AAAEA,YAAAA,SAAAA,EAAWF,aAAaE;;AAC1D,KAAA;AACF;AAEA,MAAMC,6BAA8C,CAACC,MAAAA,GAAAA;IACnD,IAAIA,MAAAA,EAAQH,MAAMJ,gBAAAA,EAAkB;AAClC,QAAA,OAAOQ,KAAAA,CAAM;AAAC,YAAA,MAAA;AAAQ,YAAA;AAAmB,SAAA,EAAE,IAAA,EAAMD,MAAAA,CAAAA;AACnD,IAAA;IAEA,OAAOA,MAAAA;AACT;;;;"}
@@ -16,6 +16,7 @@ export type ComponentContext = {
16
16
  interface ValidatorContext {
17
17
  isDraft?: boolean;
18
18
  locale?: string | null;
19
+ strictRelations?: boolean;
19
20
  }
20
21
  declare const entityValidator: Modules.EntityValidator.EntityValidator;
21
22
  export default entityValidator;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/entity-validator/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EAAE,OAAO,EAAO,MAAM,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAalE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,aAAa,EAAE;QAEb,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC;QAErB,EAAE,CAAC,EAAE,MAAM,CAAC;QAGZ,OAAO,CAAC,EAAE,gBAAgB,CAAC;KAC5B,CAAC;IAEF,eAAe,EAAE,MAAM,EAAE,CAAC;IAG1B,cAAc,EAAE,OAAO,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC;IACjD,sBAAsB,CAAC,EAAE,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;CAC/E,CAAC;AAWF,UAAU,gBAAgB;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAoiBD,QAAA,MAAM,eAAe,EAAE,OAAO,CAAC,eAAe,CAAC,eAG9C,CAAC;AAEF,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/entity-validator/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EAAE,OAAO,EAAO,MAAM,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAclE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,aAAa,EAAE;QAEb,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC;QAErB,EAAE,CAAC,EAAE,MAAM,CAAC;QAGZ,OAAO,CAAC,EAAE,gBAAgB,CAAC;KAC5B,CAAC;IAEF,eAAe,EAAE,MAAM,EAAE,CAAC;IAG1B,cAAc,EAAE,OAAO,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC;IACjD,sBAAsB,CAAC,EAAE,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;CAC/E,CAAC;AAWF,UAAU,gBAAgB;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AA0tBD,QAAA,MAAM,eAAe,EAAE,OAAO,CAAC,eAAe,CAAC,eAG9C,CAAC;AAEF,eAAe,eAAe,CAAC"}