@strapi/core 5.0.0-rc.2 → 5.0.0-rc.20

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 (196) hide show
  1. package/dist/Strapi.js +2 -2
  2. package/dist/Strapi.js.map +1 -1
  3. package/dist/configuration/get-dirs.js +2 -2
  4. package/dist/configuration/get-dirs.js.map +1 -1
  5. package/dist/configuration/index.js +2 -2
  6. package/dist/configuration/index.js.map +1 -1
  7. package/dist/core-api/controller/collection-type.js +3 -3
  8. package/dist/core-api/controller/collection-type.js.map +1 -1
  9. package/dist/core-api/controller/index.js +2 -2
  10. package/dist/core-api/controller/index.js.map +1 -1
  11. package/dist/core-api/controller/single-type.js +2 -2
  12. package/dist/core-api/controller/single-type.js.map +1 -1
  13. package/dist/core-api/controller/transform.js +8 -8
  14. package/dist/core-api/controller/transform.js.map +1 -1
  15. package/dist/core-api/service/collection-type.d.ts +2 -2
  16. package/dist/core-api/service/pagination.js +8 -8
  17. package/dist/core-api/service/pagination.js.map +1 -1
  18. package/dist/domain/content-type/index.js +4 -4
  19. package/dist/domain/content-type/index.js.map +1 -1
  20. package/dist/ee/index.js +3 -3
  21. package/dist/ee/index.js.map +1 -1
  22. package/dist/factories.js +4 -4
  23. package/dist/factories.js.map +1 -1
  24. package/dist/factories.mjs.map +1 -1
  25. package/dist/loaders/apis.js +2 -2
  26. package/dist/loaders/apis.js.map +1 -1
  27. package/dist/loaders/plugins/get-enabled-plugins.d.ts.map +1 -1
  28. package/dist/loaders/plugins/get-enabled-plugins.js +39 -11
  29. package/dist/loaders/plugins/get-enabled-plugins.js.map +1 -1
  30. package/dist/loaders/plugins/get-enabled-plugins.mjs +9 -3
  31. package/dist/loaders/plugins/get-enabled-plugins.mjs.map +1 -1
  32. package/dist/loaders/plugins/get-user-plugins-config.js +2 -2
  33. package/dist/loaders/plugins/get-user-plugins-config.js.map +1 -1
  34. package/dist/loaders/plugins/index.d.ts.map +1 -1
  35. package/dist/loaders/plugins/index.js +34 -7
  36. package/dist/loaders/plugins/index.js.map +1 -1
  37. package/dist/loaders/plugins/index.mjs +9 -1
  38. package/dist/loaders/plugins/index.mjs.map +1 -1
  39. package/dist/middlewares/body.js +2 -2
  40. package/dist/middlewares/body.js.map +1 -1
  41. package/dist/middlewares/public.js +2 -2
  42. package/dist/middlewares/public.js.map +1 -1
  43. package/dist/middlewares/query.js.map +1 -1
  44. package/dist/middlewares/query.mjs.map +1 -1
  45. package/dist/middlewares/responses.js +2 -2
  46. package/dist/middlewares/responses.js.map +1 -1
  47. package/dist/middlewares/security.d.ts.map +1 -1
  48. package/dist/middlewares/security.js +4 -4
  49. package/dist/middlewares/security.js.map +1 -1
  50. package/dist/middlewares/security.mjs +1 -1
  51. package/dist/middlewares/security.mjs.map +1 -1
  52. package/dist/middlewares/session.js +2 -2
  53. package/dist/middlewares/session.js.map +1 -1
  54. package/dist/migrations/database/5.0.0-discard-drafts.d.ts +12 -9
  55. package/dist/migrations/database/5.0.0-discard-drafts.d.ts.map +1 -1
  56. package/dist/migrations/database/5.0.0-discard-drafts.js +50 -11
  57. package/dist/migrations/database/5.0.0-discard-drafts.js.map +1 -1
  58. package/dist/migrations/database/5.0.0-discard-drafts.mjs +51 -12
  59. package/dist/migrations/database/5.0.0-discard-drafts.mjs.map +1 -1
  60. package/dist/providers/admin.d.ts.map +1 -1
  61. package/dist/providers/admin.js.map +1 -1
  62. package/dist/providers/admin.mjs.map +1 -1
  63. package/dist/registries/apis.js +2 -2
  64. package/dist/registries/apis.js.map +1 -1
  65. package/dist/registries/components.js +2 -2
  66. package/dist/registries/components.js.map +1 -1
  67. package/dist/registries/content-types.js +3 -3
  68. package/dist/registries/content-types.js.map +1 -1
  69. package/dist/registries/controllers.js +3 -3
  70. package/dist/registries/controllers.js.map +1 -1
  71. package/dist/registries/custom-fields.js +4 -4
  72. package/dist/registries/custom-fields.js.map +1 -1
  73. package/dist/registries/hooks.js +2 -2
  74. package/dist/registries/hooks.js.map +1 -1
  75. package/dist/registries/middlewares.js +3 -3
  76. package/dist/registries/middlewares.js.map +1 -1
  77. package/dist/registries/modules.js +3 -3
  78. package/dist/registries/modules.js.map +1 -1
  79. package/dist/registries/plugins.js +2 -2
  80. package/dist/registries/plugins.js.map +1 -1
  81. package/dist/registries/policies.d.ts +1 -1
  82. package/dist/registries/policies.d.ts.map +1 -1
  83. package/dist/registries/policies.js +5 -5
  84. package/dist/registries/policies.js.map +1 -1
  85. package/dist/registries/policies.mjs +1 -1
  86. package/dist/registries/policies.mjs.map +1 -1
  87. package/dist/registries/services.js +3 -3
  88. package/dist/registries/services.js.map +1 -1
  89. package/dist/services/auth/index.js +3 -3
  90. package/dist/services/auth/index.js.map +1 -1
  91. package/dist/services/content-api/index.d.ts +10 -12
  92. package/dist/services/content-api/index.d.ts.map +1 -1
  93. package/dist/services/content-api/permissions/index.d.ts +10 -12
  94. package/dist/services/content-api/permissions/index.d.ts.map +1 -1
  95. package/dist/services/content-api/permissions/providers/action.d.ts +5 -6
  96. package/dist/services/content-api/permissions/providers/action.d.ts.map +1 -1
  97. package/dist/services/content-api/permissions/providers/condition.d.ts +5 -6
  98. package/dist/services/content-api/permissions/providers/condition.d.ts.map +1 -1
  99. package/dist/services/core-store.js +3 -3
  100. package/dist/services/core-store.js.map +1 -1
  101. package/dist/services/cron.d.ts +3 -3
  102. package/dist/services/cron.d.ts.map +1 -1
  103. package/dist/services/cron.js +3 -3
  104. package/dist/services/cron.js.map +1 -1
  105. package/dist/services/cron.mjs.map +1 -1
  106. package/dist/services/document-service/attributes/index.js +2 -2
  107. package/dist/services/document-service/attributes/index.js.map +1 -1
  108. package/dist/services/document-service/attributes/transforms.js +3 -3
  109. package/dist/services/document-service/attributes/transforms.js.map +1 -1
  110. package/dist/services/document-service/components.js +15 -15
  111. package/dist/services/document-service/components.js.map +1 -1
  112. package/dist/services/document-service/draft-and-publish.js +16 -16
  113. package/dist/services/document-service/draft-and-publish.js.map +1 -1
  114. package/dist/services/document-service/entries.js +5 -5
  115. package/dist/services/document-service/entries.js.map +1 -1
  116. package/dist/services/document-service/internationalization.js +9 -9
  117. package/dist/services/document-service/internationalization.js.map +1 -1
  118. package/dist/services/document-service/params.js +2 -2
  119. package/dist/services/document-service/params.js.map +1 -1
  120. package/dist/services/document-service/repository.d.ts.map +1 -1
  121. package/dist/services/document-service/repository.js +51 -15
  122. package/dist/services/document-service/repository.js.map +1 -1
  123. package/dist/services/document-service/repository.mjs +43 -7
  124. package/dist/services/document-service/repository.mjs.map +1 -1
  125. package/dist/services/document-service/transform/id-transform.js +2 -2
  126. package/dist/services/document-service/transform/id-transform.js.map +1 -1
  127. package/dist/services/document-service/transform/query.js +3 -3
  128. package/dist/services/document-service/transform/query.js.map +1 -1
  129. package/dist/services/document-service/transform/relations/extract/data-ids.js +2 -2
  130. package/dist/services/document-service/transform/relations/extract/data-ids.js.map +1 -1
  131. package/dist/services/document-service/transform/relations/transform/data-ids.js +2 -2
  132. package/dist/services/document-service/transform/relations/transform/data-ids.js.map +1 -1
  133. package/dist/services/document-service/transform/relations/utils/dp.js +2 -2
  134. package/dist/services/document-service/transform/relations/utils/dp.js.map +1 -1
  135. package/dist/services/document-service/transform/relations/utils/map-relation.js +6 -6
  136. package/dist/services/document-service/transform/relations/utils/map-relation.js.map +1 -1
  137. package/dist/services/document-service/utils/populate.d.ts.map +1 -1
  138. package/dist/services/document-service/utils/populate.js +3 -1
  139. package/dist/services/document-service/utils/populate.js.map +1 -1
  140. package/dist/services/document-service/utils/populate.mjs +3 -1
  141. package/dist/services/document-service/utils/populate.mjs.map +1 -1
  142. package/dist/services/document-service/utils/unidirectional-relations.d.ts +33 -0
  143. package/dist/services/document-service/utils/unidirectional-relations.d.ts.map +1 -0
  144. package/dist/services/document-service/utils/unidirectional-relations.js +58 -0
  145. package/dist/services/document-service/utils/unidirectional-relations.js.map +1 -0
  146. package/dist/services/document-service/utils/unidirectional-relations.mjs +58 -0
  147. package/dist/services/document-service/utils/unidirectional-relations.mjs.map +1 -0
  148. package/dist/services/entity-validator/blocks-validator.d.ts +1 -2
  149. package/dist/services/entity-validator/blocks-validator.d.ts.map +1 -1
  150. package/dist/services/entity-validator/blocks-validator.js +4 -3
  151. package/dist/services/entity-validator/blocks-validator.js.map +1 -1
  152. package/dist/services/entity-validator/blocks-validator.mjs +3 -3
  153. package/dist/services/entity-validator/blocks-validator.mjs.map +1 -1
  154. package/dist/services/entity-validator/index.d.ts +2 -1
  155. package/dist/services/entity-validator/index.d.ts.map +1 -1
  156. package/dist/services/entity-validator/index.js +28 -33
  157. package/dist/services/entity-validator/index.js.map +1 -1
  158. package/dist/services/entity-validator/index.mjs +14 -19
  159. package/dist/services/entity-validator/index.mjs.map +1 -1
  160. package/dist/services/entity-validator/validators.d.ts +32 -23
  161. package/dist/services/entity-validator/validators.d.ts.map +1 -1
  162. package/dist/services/entity-validator/validators.js +136 -63
  163. package/dist/services/entity-validator/validators.js.map +1 -1
  164. package/dist/services/entity-validator/validators.mjs +135 -63
  165. package/dist/services/entity-validator/validators.mjs.map +1 -1
  166. package/dist/services/server/compose-endpoint.js +7 -7
  167. package/dist/services/server/compose-endpoint.js.map +1 -1
  168. package/dist/services/server/koa.js +3 -3
  169. package/dist/services/server/koa.js.map +1 -1
  170. package/dist/services/server/middleware.js +3 -3
  171. package/dist/services/server/middleware.js.map +1 -1
  172. package/dist/services/server/routing.js +2 -2
  173. package/dist/services/server/routing.js.map +1 -1
  174. package/dist/services/utils/dynamic-zones.js +5 -5
  175. package/dist/services/utils/dynamic-zones.js.map +1 -1
  176. package/dist/utils/cron.js +3 -3
  177. package/dist/utils/cron.js.map +1 -1
  178. package/dist/utils/filepath-to-prop-path.d.ts +1 -1
  179. package/dist/utils/filepath-to-prop-path.d.ts.map +1 -1
  180. package/dist/utils/filepath-to-prop-path.js +27 -6
  181. package/dist/utils/filepath-to-prop-path.js.map +1 -1
  182. package/dist/utils/filepath-to-prop-path.mjs +25 -5
  183. package/dist/utils/filepath-to-prop-path.mjs.map +1 -1
  184. package/dist/utils/is-initialized.js +3 -3
  185. package/dist/utils/is-initialized.js.map +1 -1
  186. package/dist/utils/startup-logger.js +4 -4
  187. package/dist/utils/startup-logger.js.map +1 -1
  188. package/dist/utils/startup-logger.mjs +3 -3
  189. package/dist/utils/startup-logger.mjs.map +1 -1
  190. package/dist/utils/transform-content-types-to-models.d.ts +2 -2
  191. package/dist/utils/transform-content-types-to-models.d.ts.map +1 -1
  192. package/dist/utils/transform-content-types-to-models.js +6 -5
  193. package/dist/utils/transform-content-types-to-models.js.map +1 -1
  194. package/dist/utils/transform-content-types-to-models.mjs +5 -4
  195. package/dist/utils/transform-content-types-to-models.mjs.map +1 -1
  196. package/package.json +15 -15
@@ -1,6 +1,7 @@
1
1
  import { join } from "path";
2
2
  import fse from "fs-extra";
3
3
  import { defaults, get, getOr, defaultsDeep } from "lodash/fp";
4
+ import * as resolve from "resolve.exports";
4
5
  import { env } from "@strapi/utils";
5
6
  import { loadConfigFile } from "../../utils/load-config-file.mjs";
6
7
  import { loadFiles } from "../../utils/load-files.mjs";
@@ -75,8 +76,15 @@ async function loadPlugins(strapi2) {
75
76
  for (const pluginName of Object.keys(enabledPlugins)) {
76
77
  const enabledPlugin = enabledPlugins[pluginName];
77
78
  let serverEntrypointPath;
79
+ let resolvedExport = "./strapi-server.js";
78
80
  try {
79
- serverEntrypointPath = join(enabledPlugin.pathToPlugin, "strapi-server.js");
81
+ resolvedExport = (resolve.exports(enabledPlugin.packageInfo, "strapi-server", {
82
+ require: true
83
+ }) ?? "./strapi-server.js").toString();
84
+ } catch (e) {
85
+ }
86
+ try {
87
+ serverEntrypointPath = join(enabledPlugin.pathToPlugin, resolvedExport);
80
88
  } catch (e) {
81
89
  throw new Error(
82
90
  `Error loading the plugin ${pluginName} because ${pluginName} is not installed. Please either install the plugin or remove it's configuration.`
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../../../src/loaders/plugins/index.ts"],"sourcesContent":["import { join } from 'path';\nimport fse from 'fs-extra';\nimport { defaultsDeep, defaults, getOr, get } from 'lodash/fp';\nimport { env } from '@strapi/utils';\nimport type { Core, Plugin, Struct } from '@strapi/types';\nimport { loadConfigFile } from '../../utils/load-config-file';\nimport { loadFiles } from '../../utils/load-files';\nimport { getEnabledPlugins } from './get-enabled-plugins';\nimport { getUserPluginsConfig } from './get-user-plugins-config';\nimport { getGlobalId } from '../../domain/content-type';\n\ninterface Plugins {\n [key: string]: Plugin.LoadedPlugin;\n}\n\nconst defaultPlugin = {\n bootstrap() {},\n destroy() {},\n register() {},\n config: {\n default: {},\n validator() {},\n },\n routes: [],\n controllers: {},\n services: {},\n policies: {},\n middlewares: {},\n contentTypes: {},\n};\n\nconst applyUserExtension = async (plugins: Plugins) => {\n const extensionsDir = strapi.dirs.dist.extensions;\n if (!(await fse.pathExists(extensionsDir))) {\n return;\n }\n\n const extendedSchemas = await loadFiles(extensionsDir, '**/content-types/**/schema.json');\n const strapiServers = await loadFiles(extensionsDir, '**/strapi-server.js');\n\n for (const pluginName of Object.keys(plugins)) {\n const plugin = plugins[pluginName];\n // first: load json schema\n for (const ctName of Object.keys(plugin.contentTypes)) {\n const extendedSchema = get([pluginName, 'content-types', ctName, 'schema'], extendedSchemas);\n if (extendedSchema) {\n plugin.contentTypes[ctName].schema = {\n ...plugin.contentTypes[ctName].schema,\n ...extendedSchema,\n };\n }\n }\n // second: execute strapi-server extension\n const strapiServer = get([pluginName, 'strapi-server'], strapiServers);\n if (strapiServer) {\n plugins[pluginName] = await strapiServer(plugin);\n }\n }\n};\n\nconst applyUserConfig = async (plugins: Plugins) => {\n const userPluginsConfig = await getUserPluginsConfig();\n\n for (const pluginName of Object.keys(plugins)) {\n const plugin = plugins[pluginName];\n const userPluginConfig = getOr({}, `${pluginName}.config`, userPluginsConfig);\n const defaultConfig =\n typeof plugin.config.default === 'function'\n ? plugin.config.default({ env })\n : plugin.config.default;\n\n const config = defaultsDeep(defaultConfig, userPluginConfig);\n try {\n plugin.config.validator(config);\n } catch (e) {\n if (e instanceof Error) {\n throw new Error(`Error regarding ${pluginName} config: ${e.message}`);\n }\n\n throw e;\n }\n plugin.config = config;\n }\n};\n\nexport default async function loadPlugins(strapi: Core.Strapi) {\n const plugins: Plugins = {};\n\n const enabledPlugins = await getEnabledPlugins(strapi);\n\n strapi.config.set('enabledPlugins', enabledPlugins);\n\n for (const pluginName of Object.keys(enabledPlugins)) {\n const enabledPlugin = enabledPlugins[pluginName];\n\n let serverEntrypointPath;\n\n try {\n serverEntrypointPath = join(enabledPlugin.pathToPlugin, 'strapi-server.js');\n } catch (e) {\n throw new Error(\n `Error loading the plugin ${pluginName} because ${pluginName} is not installed. Please either install the plugin or remove it's configuration.`\n );\n }\n\n // only load plugins with a server entrypoint\n if (!(await fse.pathExists(serverEntrypointPath))) {\n continue;\n }\n\n const pluginServer = loadConfigFile(serverEntrypointPath);\n plugins[pluginName] = {\n ...defaultPlugin,\n ...pluginServer,\n contentTypes: formatContentTypes(pluginName, pluginServer.contentTypes ?? {}),\n config: defaults(defaultPlugin.config, pluginServer.config),\n routes: pluginServer.routes ?? defaultPlugin.routes,\n };\n }\n\n // TODO: validate plugin format\n await applyUserConfig(plugins);\n await applyUserExtension(plugins);\n\n for (const pluginName of Object.keys(plugins)) {\n strapi.get('plugins').add(pluginName, plugins[pluginName]);\n }\n}\n\nconst formatContentTypes = (\n pluginName: string,\n contentTypes: Record<string, { schema: Struct.ContentTypeSchema }>\n) => {\n Object.values(contentTypes).forEach((definition) => {\n const { schema } = definition;\n\n Object.assign(schema, {\n plugin: pluginName,\n collectionName:\n schema.collectionName || `${pluginName}_${schema.info.singularName}`.toLowerCase(),\n globalId: getGlobalId(schema, pluginName),\n });\n });\n\n return contentTypes;\n};\n"],"names":["strapi"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","sources":["../../../src/loaders/plugins/index.ts"],"sourcesContent":["import { join } from 'path';\nimport fse from 'fs-extra';\nimport { defaultsDeep, defaults, getOr, get } from 'lodash/fp';\nimport * as resolve from 'resolve.exports';\n\nimport { env } from '@strapi/utils';\nimport type { Core, Plugin, Struct } from '@strapi/types';\nimport { loadConfigFile } from '../../utils/load-config-file';\nimport { loadFiles } from '../../utils/load-files';\nimport { getEnabledPlugins } from './get-enabled-plugins';\nimport { getUserPluginsConfig } from './get-user-plugins-config';\nimport { getGlobalId } from '../../domain/content-type';\n\ninterface Plugins {\n [key: string]: Plugin.LoadedPlugin;\n}\n\nconst defaultPlugin = {\n bootstrap() {},\n destroy() {},\n register() {},\n config: {\n default: {},\n validator() {},\n },\n routes: [],\n controllers: {},\n services: {},\n policies: {},\n middlewares: {},\n contentTypes: {},\n};\n\nconst applyUserExtension = async (plugins: Plugins) => {\n const extensionsDir = strapi.dirs.dist.extensions;\n if (!(await fse.pathExists(extensionsDir))) {\n return;\n }\n\n const extendedSchemas = await loadFiles(extensionsDir, '**/content-types/**/schema.json');\n const strapiServers = await loadFiles(extensionsDir, '**/strapi-server.js');\n\n for (const pluginName of Object.keys(plugins)) {\n const plugin = plugins[pluginName];\n // first: load json schema\n for (const ctName of Object.keys(plugin.contentTypes)) {\n const extendedSchema = get([pluginName, 'content-types', ctName, 'schema'], extendedSchemas);\n if (extendedSchema) {\n plugin.contentTypes[ctName].schema = {\n ...plugin.contentTypes[ctName].schema,\n ...extendedSchema,\n };\n }\n }\n // second: execute strapi-server extension\n const strapiServer = get([pluginName, 'strapi-server'], strapiServers);\n if (strapiServer) {\n plugins[pluginName] = await strapiServer(plugin);\n }\n }\n};\n\nconst applyUserConfig = async (plugins: Plugins) => {\n const userPluginsConfig = await getUserPluginsConfig();\n\n for (const pluginName of Object.keys(plugins)) {\n const plugin = plugins[pluginName];\n const userPluginConfig = getOr({}, `${pluginName}.config`, userPluginsConfig);\n const defaultConfig =\n typeof plugin.config.default === 'function'\n ? plugin.config.default({ env })\n : plugin.config.default;\n\n const config = defaultsDeep(defaultConfig, userPluginConfig);\n try {\n plugin.config.validator(config);\n } catch (e) {\n if (e instanceof Error) {\n throw new Error(`Error regarding ${pluginName} config: ${e.message}`);\n }\n\n throw e;\n }\n plugin.config = config;\n }\n};\n\nexport default async function loadPlugins(strapi: Core.Strapi) {\n const plugins: Plugins = {};\n\n const enabledPlugins = await getEnabledPlugins(strapi);\n\n strapi.config.set('enabledPlugins', enabledPlugins);\n\n for (const pluginName of Object.keys(enabledPlugins)) {\n const enabledPlugin = enabledPlugins[pluginName];\n\n let serverEntrypointPath;\n let resolvedExport = './strapi-server.js';\n\n try {\n resolvedExport = (\n resolve.exports(enabledPlugin.packageInfo, 'strapi-server', {\n require: true,\n }) ?? './strapi-server.js'\n ).toString();\n } catch (e) {\n // no export map or missing strapi-server export => fallback to default\n }\n\n try {\n serverEntrypointPath = join(enabledPlugin.pathToPlugin, resolvedExport);\n } catch (e) {\n throw new Error(\n `Error loading the plugin ${pluginName} because ${pluginName} is not installed. Please either install the plugin or remove it's configuration.`\n );\n }\n\n // only load plugins with a server entrypoint\n if (!(await fse.pathExists(serverEntrypointPath))) {\n continue;\n }\n\n const pluginServer = loadConfigFile(serverEntrypointPath);\n plugins[pluginName] = {\n ...defaultPlugin,\n ...pluginServer,\n contentTypes: formatContentTypes(pluginName, pluginServer.contentTypes ?? {}),\n config: defaults(defaultPlugin.config, pluginServer.config),\n routes: pluginServer.routes ?? defaultPlugin.routes,\n };\n }\n\n // TODO: validate plugin format\n await applyUserConfig(plugins);\n await applyUserExtension(plugins);\n\n for (const pluginName of Object.keys(plugins)) {\n strapi.get('plugins').add(pluginName, plugins[pluginName]);\n }\n}\n\nconst formatContentTypes = (\n pluginName: string,\n contentTypes: Record<string, { schema: Struct.ContentTypeSchema }>\n) => {\n Object.values(contentTypes).forEach((definition) => {\n const { schema } = definition;\n\n Object.assign(schema, {\n plugin: pluginName,\n collectionName:\n schema.collectionName || `${pluginName}_${schema.info.singularName}`.toLowerCase(),\n globalId: getGlobalId(schema, pluginName),\n });\n });\n\n return contentTypes;\n};\n"],"names":["strapi"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const fse = require("fs-extra");
4
- const _ = require("lodash/fp");
4
+ const fp = require("lodash/fp");
5
5
  const body = require("koa-body");
6
6
  const mime = require("mime-types");
7
7
  const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
@@ -21,7 +21,7 @@ function getFiles(ctx) {
21
21
  return ctx?.request?.files?.files;
22
22
  }
23
23
  const bodyMiddleware = (config, { strapi }) => {
24
- const bodyConfig = _.defaultsDeep(defaults, config);
24
+ const bodyConfig = fp.defaultsDeep(defaults, config);
25
25
  let gqlEndpoint;
26
26
  if (strapi.plugin("graphql")) {
27
27
  const { config: gqlConfig } = strapi.plugin("graphql");
@@ -1 +1 @@
1
- {"version":3,"file":"body.js","sources":["../../src/middlewares/body.ts"],"sourcesContent":["import fse from 'fs-extra';\nimport { defaultsDeep } from 'lodash/fp';\nimport body, { KoaBodyMiddlewareOptions } from 'koa-body';\nimport mime from 'mime-types';\nimport type Koa from 'koa';\nimport type { Core } from '@strapi/types';\n\nexport type Config = KoaBodyMiddlewareOptions;\n\nconst defaults = {\n multipart: true,\n patchKoa: true,\n};\n\nfunction ensureFileMimeType(file: any): void {\n if (!file.type) {\n file.type = mime.lookup(file.name) || 'application/octet-stream';\n }\n}\n\nfunction getFiles(ctx: Koa.Context) {\n return ctx?.request?.files?.files;\n}\n\nconst bodyMiddleware: Core.MiddlewareFactory<Config> = (config, { strapi }) => {\n const bodyConfig: Config = defaultsDeep(defaults, config);\n\n let gqlEndpoint: string | undefined;\n if (strapi.plugin('graphql')) {\n const { config: gqlConfig } = strapi.plugin('graphql');\n gqlEndpoint = gqlConfig('endpoint');\n }\n\n return async (ctx, next) => {\n // TODO: find a better way later\n if (gqlEndpoint && ctx.url === gqlEndpoint) {\n await next();\n } else {\n try {\n await body(bodyConfig)(ctx, async () => {});\n\n const files = getFiles(ctx);\n\n /**\n * in case the mime-type wasn't sent, Strapi tries to guess it\n * from the file extension, to avoid a corrupt database state\n */\n if (files) {\n if (Array.isArray(files)) {\n files.forEach(ensureFileMimeType);\n } else {\n ensureFileMimeType(files);\n }\n }\n\n await next();\n } catch (error) {\n if (\n error instanceof Error &&\n error.message &&\n error.message.includes('maxFileSize exceeded')\n ) {\n return ctx.payloadTooLarge('FileTooBig');\n }\n\n throw error;\n }\n }\n\n const files = getFiles(ctx);\n\n // clean any file that was uploaded\n if (files) {\n if (Array.isArray(files)) {\n // not awaiting to not slow the request\n Promise.all(files.map((file) => fse.remove(file.filepath)));\n } else if (files && files.filepath) {\n // not awaiting to not slow the request\n fse.remove(files.filepath);\n }\n delete ctx.request.files;\n }\n };\n};\n\nexport { bodyMiddleware as body };\n"],"names":["mime","defaultsDeep","body","files","fse"],"mappings":";;;;;;;;;;AASA,MAAM,WAAW;AAAA,EACf,WAAW;AAAA,EACX,UAAU;AACZ;AAEA,SAAS,mBAAmB,MAAiB;AACvC,MAAA,CAAC,KAAK,MAAM;AACd,SAAK,OAAOA,sBAAK,OAAO,KAAK,IAAI,KAAK;AAAA,EACxC;AACF;AAEA,SAAS,SAAS,KAAkB;AAC3B,SAAA,KAAK,SAAS,OAAO;AAC9B;AAEA,MAAM,iBAAiD,CAAC,QAAQ,EAAE,aAAa;AACvE,QAAA,aAAqBC,EAAAA,aAAa,UAAU,MAAM;AAEpD,MAAA;AACA,MAAA,OAAO,OAAO,SAAS,GAAG;AAC5B,UAAM,EAAE,QAAQ,UAAA,IAAc,OAAO,OAAO,SAAS;AACrD,kBAAc,UAAU,UAAU;AAAA,EACpC;AAEO,SAAA,OAAO,KAAK,SAAS;AAEtB,QAAA,eAAe,IAAI,QAAQ,aAAa;AAC1C,YAAM,KAAK;AAAA,IAAA,OACN;AACD,UAAA;AACF,cAAMC,sBAAK,UAAU,EAAE,KAAK,YAAY;AAAA,QAAA,CAAE;AAEpCC,cAAAA,SAAQ,SAAS,GAAG;AAM1B,YAAIA,QAAO;AACL,cAAA,MAAM,QAAQA,MAAK,GAAG;AACxBA,mBAAM,QAAQ,kBAAkB;AAAA,UAAA,OAC3B;AACL,+BAAmBA,MAAK;AAAA,UAC1B;AAAA,QACF;AAEA,cAAM,KAAK;AAAA,eACJ,OAAO;AAEZ,YAAA,iBAAiB,SACjB,MAAM,WACN,MAAM,QAAQ,SAAS,sBAAsB,GAC7C;AACO,iBAAA,IAAI,gBAAgB,YAAY;AAAA,QACzC;AAEM,cAAA;AAAA,MACR;AAAA,IACF;AAEM,UAAA,QAAQ,SAAS,GAAG;AAG1B,QAAI,OAAO;AACL,UAAA,MAAM,QAAQ,KAAK,GAAG;AAEhB,gBAAA,IAAI,MAAM,IAAI,CAAC,SAASC,qBAAI,OAAO,KAAK,QAAQ,CAAC,CAAC;AAAA,MAAA,WACjD,SAAS,MAAM,UAAU;AAE9BA,qBAAAA,QAAA,OAAO,MAAM,QAAQ;AAAA,MAC3B;AACA,aAAO,IAAI,QAAQ;AAAA,IACrB;AAAA,EAAA;AAEJ;;"}
1
+ {"version":3,"file":"body.js","sources":["../../src/middlewares/body.ts"],"sourcesContent":["import fse from 'fs-extra';\nimport { defaultsDeep } from 'lodash/fp';\nimport body, { KoaBodyMiddlewareOptions } from 'koa-body';\nimport mime from 'mime-types';\nimport type Koa from 'koa';\nimport type { Core } from '@strapi/types';\n\nexport type Config = KoaBodyMiddlewareOptions;\n\nconst defaults = {\n multipart: true,\n patchKoa: true,\n};\n\nfunction ensureFileMimeType(file: any): void {\n if (!file.type) {\n file.type = mime.lookup(file.name) || 'application/octet-stream';\n }\n}\n\nfunction getFiles(ctx: Koa.Context) {\n return ctx?.request?.files?.files;\n}\n\nconst bodyMiddleware: Core.MiddlewareFactory<Config> = (config, { strapi }) => {\n const bodyConfig: Config = defaultsDeep(defaults, config);\n\n let gqlEndpoint: string | undefined;\n if (strapi.plugin('graphql')) {\n const { config: gqlConfig } = strapi.plugin('graphql');\n gqlEndpoint = gqlConfig('endpoint');\n }\n\n return async (ctx, next) => {\n // TODO: find a better way later\n if (gqlEndpoint && ctx.url === gqlEndpoint) {\n await next();\n } else {\n try {\n await body(bodyConfig)(ctx, async () => {});\n\n const files = getFiles(ctx);\n\n /**\n * in case the mime-type wasn't sent, Strapi tries to guess it\n * from the file extension, to avoid a corrupt database state\n */\n if (files) {\n if (Array.isArray(files)) {\n files.forEach(ensureFileMimeType);\n } else {\n ensureFileMimeType(files);\n }\n }\n\n await next();\n } catch (error) {\n if (\n error instanceof Error &&\n error.message &&\n error.message.includes('maxFileSize exceeded')\n ) {\n return ctx.payloadTooLarge('FileTooBig');\n }\n\n throw error;\n }\n }\n\n const files = getFiles(ctx);\n\n // clean any file that was uploaded\n if (files) {\n if (Array.isArray(files)) {\n // not awaiting to not slow the request\n Promise.all(files.map((file) => fse.remove(file.filepath)));\n } else if (files && files.filepath) {\n // not awaiting to not slow the request\n fse.remove(files.filepath);\n }\n delete ctx.request.files;\n }\n };\n};\n\nexport { bodyMiddleware as body };\n"],"names":["mime","defaultsDeep","body","files","fse"],"mappings":";;;;;;;;;;AASA,MAAM,WAAW;AAAA,EACf,WAAW;AAAA,EACX,UAAU;AACZ;AAEA,SAAS,mBAAmB,MAAiB;AACvC,MAAA,CAAC,KAAK,MAAM;AACd,SAAK,OAAOA,sBAAK,OAAO,KAAK,IAAI,KAAK;AAAA,EACxC;AACF;AAEA,SAAS,SAAS,KAAkB;AAC3B,SAAA,KAAK,SAAS,OAAO;AAC9B;AAEA,MAAM,iBAAiD,CAAC,QAAQ,EAAE,aAAa;AACvE,QAAA,aAAqBC,GAAAA,aAAa,UAAU,MAAM;AAEpD,MAAA;AACA,MAAA,OAAO,OAAO,SAAS,GAAG;AAC5B,UAAM,EAAE,QAAQ,UAAA,IAAc,OAAO,OAAO,SAAS;AACrD,kBAAc,UAAU,UAAU;AAAA,EACpC;AAEO,SAAA,OAAO,KAAK,SAAS;AAEtB,QAAA,eAAe,IAAI,QAAQ,aAAa;AAC1C,YAAM,KAAK;AAAA,IAAA,OACN;AACD,UAAA;AACF,cAAMC,sBAAK,UAAU,EAAE,KAAK,YAAY;AAAA,QAAA,CAAE;AAEpCC,cAAAA,SAAQ,SAAS,GAAG;AAM1B,YAAIA,QAAO;AACL,cAAA,MAAM,QAAQA,MAAK,GAAG;AACxBA,mBAAM,QAAQ,kBAAkB;AAAA,UAAA,OAC3B;AACL,+BAAmBA,MAAK;AAAA,UAC1B;AAAA,QACF;AAEA,cAAM,KAAK;AAAA,eACJ,OAAO;AAEZ,YAAA,iBAAiB,SACjB,MAAM,WACN,MAAM,QAAQ,SAAS,sBAAsB,GAC7C;AACO,iBAAA,IAAI,gBAAgB,YAAY;AAAA,QACzC;AAEM,cAAA;AAAA,MACR;AAAA,IACF;AAEM,UAAA,QAAQ,SAAS,GAAG;AAG1B,QAAI,OAAO;AACL,UAAA,MAAM,QAAQ,KAAK,GAAG;AAEhB,gBAAA,IAAI,MAAM,IAAI,CAAC,SAASC,qBAAI,OAAO,KAAK,QAAQ,CAAC,CAAC;AAAA,MAAA,WACjD,SAAS,MAAM,UAAU;AAE9BA,qBAAAA,QAAA,OAAO,MAAM,QAAQ;AAAA,MAC3B;AACA,aAAO,IAAI,QAAQ;AAAA,IACrB;AAAA,EAAA;AAEJ;;"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const _ = require("lodash/fp");
3
+ const fp = require("lodash/fp");
4
4
  const koaStatic = require("koa-static");
5
5
  const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
6
6
  const koaStatic__default = /* @__PURE__ */ _interopDefault(koaStatic);
@@ -8,7 +8,7 @@ const defaults = {
8
8
  maxAge: 6e4
9
9
  };
10
10
  const publicStatic = (config, { strapi }) => {
11
- const { maxAge } = _.defaultsDeep(defaults, config);
11
+ const { maxAge } = fp.defaultsDeep(defaults, config);
12
12
  strapi.server.routes([
13
13
  {
14
14
  method: "GET",
@@ -1 +1 @@
1
- {"version":3,"file":"public.js","sources":["../../src/middlewares/public.ts"],"sourcesContent":["import { defaultsDeep } from 'lodash/fp';\nimport koaStatic from 'koa-static';\nimport type { Core } from '@strapi/types';\n\ntype Config = koaStatic.Options;\n\nconst defaults = {\n maxAge: 60000,\n};\n\nexport const publicStatic: Core.MiddlewareFactory = (\n config: Config,\n { strapi }: { strapi: Core.Strapi }\n) => {\n const { maxAge } = defaultsDeep(defaults, config);\n\n strapi.server.routes([\n {\n method: 'GET',\n path: '/',\n handler(ctx) {\n ctx.redirect(strapi.config.get('admin.url', '/admin'));\n },\n config: { auth: false },\n },\n // All other public GET-routes except /uploads/(.*) which is handled in upload middleware\n {\n method: 'GET',\n path: '/((?!uploads/).+)',\n handler: koaStatic(strapi.dirs.static.public, {\n maxage: maxAge,\n defer: true,\n }),\n config: { auth: false },\n },\n ]);\n};\n"],"names":["defaultsDeep","koaStatic"],"mappings":";;;;;;AAMA,MAAM,WAAW;AAAA,EACf,QAAQ;AACV;AAEO,MAAM,eAAuC,CAClD,QACA,EAAE,aACC;AACH,QAAM,EAAE,OAAW,IAAAA,EAAA,aAAa,UAAU,MAAM;AAEhD,SAAO,OAAO,OAAO;AAAA,IACnB;AAAA,MACE,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,QAAQ,KAAK;AACX,YAAI,SAAS,OAAO,OAAO,IAAI,aAAa,QAAQ,CAAC;AAAA,MACvD;AAAA,MACA,QAAQ,EAAE,MAAM,MAAM;AAAA,IACxB;AAAA;AAAA,IAEA;AAAA,MACE,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAASC,mBAAAA,QAAU,OAAO,KAAK,OAAO,QAAQ;AAAA,QAC5C,QAAQ;AAAA,QACR,OAAO;AAAA,MAAA,CACR;AAAA,MACD,QAAQ,EAAE,MAAM,MAAM;AAAA,IACxB;AAAA,EAAA,CACD;AACH;;"}
1
+ {"version":3,"file":"public.js","sources":["../../src/middlewares/public.ts"],"sourcesContent":["import { defaultsDeep } from 'lodash/fp';\nimport koaStatic from 'koa-static';\nimport type { Core } from '@strapi/types';\n\ntype Config = koaStatic.Options;\n\nconst defaults = {\n maxAge: 60000,\n};\n\nexport const publicStatic: Core.MiddlewareFactory = (\n config: Config,\n { strapi }: { strapi: Core.Strapi }\n) => {\n const { maxAge } = defaultsDeep(defaults, config);\n\n strapi.server.routes([\n {\n method: 'GET',\n path: '/',\n handler(ctx) {\n ctx.redirect(strapi.config.get('admin.url', '/admin'));\n },\n config: { auth: false },\n },\n // All other public GET-routes except /uploads/(.*) which is handled in upload middleware\n {\n method: 'GET',\n path: '/((?!uploads/).+)',\n handler: koaStatic(strapi.dirs.static.public, {\n maxage: maxAge,\n defer: true,\n }),\n config: { auth: false },\n },\n ]);\n};\n"],"names":["defaultsDeep","koaStatic"],"mappings":";;;;;;AAMA,MAAM,WAAW;AAAA,EACf,QAAQ;AACV;AAEO,MAAM,eAAuC,CAClD,QACA,EAAE,aACC;AACH,QAAM,EAAE,OAAW,IAAAA,GAAA,aAAa,UAAU,MAAM;AAEhD,SAAO,OAAO,OAAO;AAAA,IACnB;AAAA,MACE,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,QAAQ,KAAK;AACX,YAAI,SAAS,OAAO,OAAO,IAAI,aAAa,QAAQ,CAAC;AAAA,MACvD;AAAA,MACA,QAAQ,EAAE,MAAM,MAAM;AAAA,IACxB;AAAA;AAAA,IAEA;AAAA,MACE,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAASC,mBAAAA,QAAU,OAAO,KAAK,OAAO,QAAQ;AAAA,QAC5C,QAAQ;AAAA,QACR,OAAO;AAAA,MAAA,CACR;AAAA,MACD,QAAQ,EAAE,MAAM,MAAM;AAAA,IACxB;AAAA,EAAA,CACD;AACH;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"query.js","sources":["../../src/middlewares/query.ts"],"sourcesContent":["import qs from 'qs';\nimport type Koa from 'koa';\nimport type { Core } from '@strapi/types';\n\ntype Config = Parameters<typeof qs.parse>[1];\n\nconst defaults: Config = {\n strictNullHandling: true,\n arrayLimit: 100,\n depth: 20,\n};\n\n/**\n * Body parser hook\n */\nconst addQsParser = (app: Koa, settings: Config) => {\n Object.defineProperty(app.request, 'query', {\n configurable: false,\n enumerable: true,\n /*\n * Get parsed query-string.\n */\n get() {\n const qstr = this.querystring;\n\n this._querycache = this._querycache || {};\n const cache = this._querycache;\n\n if (!cache[qstr]) {\n cache[qstr] = qs.parse(qstr, settings);\n }\n\n return cache[qstr];\n },\n\n /*\n * Set query-string as an object.\n */\n set(obj) {\n this.querystring = qs.stringify(obj);\n },\n } satisfies PropertyDescriptor & ThisType<Koa.BaseRequest>);\n\n return app;\n};\n\nexport const query: Core.MiddlewareFactory = (\n config: Partial<Config>,\n { strapi }: { strapi: Core.Strapi }\n) => {\n addQsParser(strapi.server.app, { ...defaults, ...config });\n};\n"],"names":["qs"],"mappings":";;;;;AAMA,MAAM,WAAmB;AAAA,EACvB,oBAAoB;AAAA,EACpB,YAAY;AAAA,EACZ,OAAO;AACT;AAKA,MAAM,cAAc,CAAC,KAAU,aAAqB;AAC3C,SAAA,eAAe,IAAI,SAAS,SAAS;AAAA,IAC1C,cAAc;AAAA,IACd,YAAY;AAAA;AAAA;AAAA;AAAA,IAIZ,MAAM;AACJ,YAAM,OAAO,KAAK;AAEb,WAAA,cAAc,KAAK,eAAe,CAAA;AACvC,YAAM,QAAQ,KAAK;AAEf,UAAA,CAAC,MAAM,IAAI,GAAG;AAChB,cAAM,IAAI,IAAIA,YAAAA,QAAG,MAAM,MAAM,QAAQ;AAAA,MACvC;AAEA,aAAO,MAAM,IAAI;AAAA,IACnB;AAAA;AAAA;AAAA;AAAA,IAKA,IAAI,KAAK;AACF,WAAA,cAAcA,YAAAA,QAAG,UAAU,GAAG;AAAA,IACrC;AAAA,EAAA,CACwD;AAEnD,SAAA;AACT;AAEO,MAAM,QAAgC,CAC3C,QACA,EAAE,aACC;AACS,cAAA,OAAO,OAAO,KAAK,EAAE,GAAG,UAAU,GAAG,QAAQ;AAC3D;;"}
1
+ {"version":3,"file":"query.js","sources":["../../src/middlewares/query.ts"],"sourcesContent":["import qs from 'qs';\nimport type Koa from 'koa';\nimport type { Core } from '@strapi/types';\n\ntype Config = Parameters<typeof qs.parse>[1];\n\nconst defaults: Config = {\n strictNullHandling: true,\n arrayLimit: 100,\n depth: 20,\n};\n\n/**\n * Body parser hook\n */\nconst addQsParser = (app: Koa, settings: Config) => {\n Object.defineProperty(app.request, 'query', {\n configurable: false,\n enumerable: true,\n /*\n * Get parsed query-string.\n */\n get() {\n const qstr = this.querystring;\n\n this._querycache = this._querycache || {};\n const cache = this._querycache;\n\n if (!cache[qstr]) {\n cache[qstr] = qs.parse(qstr, settings);\n }\n\n return cache[qstr];\n },\n\n /*\n * Set query-string as an object.\n */\n set(obj) {\n this.querystring = qs.stringify(obj);\n },\n } satisfies PropertyDescriptor & ThisType<Koa.BaseRequest>);\n\n return app;\n};\n\nexport const query: Core.MiddlewareFactory = (\n config: Partial<Config>,\n { strapi }: { strapi: Core.Strapi }\n) => {\n addQsParser(strapi.server.app, { ...defaults, ...config } as Config);\n};\n"],"names":["qs"],"mappings":";;;;;AAMA,MAAM,WAAmB;AAAA,EACvB,oBAAoB;AAAA,EACpB,YAAY;AAAA,EACZ,OAAO;AACT;AAKA,MAAM,cAAc,CAAC,KAAU,aAAqB;AAC3C,SAAA,eAAe,IAAI,SAAS,SAAS;AAAA,IAC1C,cAAc;AAAA,IACd,YAAY;AAAA;AAAA;AAAA;AAAA,IAIZ,MAAM;AACJ,YAAM,OAAO,KAAK;AAEb,WAAA,cAAc,KAAK,eAAe,CAAA;AACvC,YAAM,QAAQ,KAAK;AAEf,UAAA,CAAC,MAAM,IAAI,GAAG;AAChB,cAAM,IAAI,IAAIA,YAAAA,QAAG,MAAM,MAAM,QAAQ;AAAA,MACvC;AAEA,aAAO,MAAM,IAAI;AAAA,IACnB;AAAA;AAAA;AAAA;AAAA,IAKA,IAAI,KAAK;AACF,WAAA,cAAcA,YAAAA,QAAG,UAAU,GAAG;AAAA,IACrC;AAAA,EAAA,CACwD;AAEnD,SAAA;AACT;AAEO,MAAM,QAAgC,CAC3C,QACA,EAAE,aACC;AACS,cAAA,OAAO,OAAO,KAAK,EAAE,GAAG,UAAU,GAAG,QAAkB;AACrE;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"query.mjs","sources":["../../src/middlewares/query.ts"],"sourcesContent":["import qs from 'qs';\nimport type Koa from 'koa';\nimport type { Core } from '@strapi/types';\n\ntype Config = Parameters<typeof qs.parse>[1];\n\nconst defaults: Config = {\n strictNullHandling: true,\n arrayLimit: 100,\n depth: 20,\n};\n\n/**\n * Body parser hook\n */\nconst addQsParser = (app: Koa, settings: Config) => {\n Object.defineProperty(app.request, 'query', {\n configurable: false,\n enumerable: true,\n /*\n * Get parsed query-string.\n */\n get() {\n const qstr = this.querystring;\n\n this._querycache = this._querycache || {};\n const cache = this._querycache;\n\n if (!cache[qstr]) {\n cache[qstr] = qs.parse(qstr, settings);\n }\n\n return cache[qstr];\n },\n\n /*\n * Set query-string as an object.\n */\n set(obj) {\n this.querystring = qs.stringify(obj);\n },\n } satisfies PropertyDescriptor & ThisType<Koa.BaseRequest>);\n\n return app;\n};\n\nexport const query: Core.MiddlewareFactory = (\n config: Partial<Config>,\n { strapi }: { strapi: Core.Strapi }\n) => {\n addQsParser(strapi.server.app, { ...defaults, ...config });\n};\n"],"names":[],"mappings":";AAMA,MAAM,WAAmB;AAAA,EACvB,oBAAoB;AAAA,EACpB,YAAY;AAAA,EACZ,OAAO;AACT;AAKA,MAAM,cAAc,CAAC,KAAU,aAAqB;AAC3C,SAAA,eAAe,IAAI,SAAS,SAAS;AAAA,IAC1C,cAAc;AAAA,IACd,YAAY;AAAA;AAAA;AAAA;AAAA,IAIZ,MAAM;AACJ,YAAM,OAAO,KAAK;AAEb,WAAA,cAAc,KAAK,eAAe,CAAA;AACvC,YAAM,QAAQ,KAAK;AAEf,UAAA,CAAC,MAAM,IAAI,GAAG;AAChB,cAAM,IAAI,IAAI,GAAG,MAAM,MAAM,QAAQ;AAAA,MACvC;AAEA,aAAO,MAAM,IAAI;AAAA,IACnB;AAAA;AAAA;AAAA;AAAA,IAKA,IAAI,KAAK;AACF,WAAA,cAAc,GAAG,UAAU,GAAG;AAAA,IACrC;AAAA,EAAA,CACwD;AAEnD,SAAA;AACT;AAEO,MAAM,QAAgC,CAC3C,QACA,EAAE,aACC;AACS,cAAA,OAAO,OAAO,KAAK,EAAE,GAAG,UAAU,GAAG,QAAQ;AAC3D;"}
1
+ {"version":3,"file":"query.mjs","sources":["../../src/middlewares/query.ts"],"sourcesContent":["import qs from 'qs';\nimport type Koa from 'koa';\nimport type { Core } from '@strapi/types';\n\ntype Config = Parameters<typeof qs.parse>[1];\n\nconst defaults: Config = {\n strictNullHandling: true,\n arrayLimit: 100,\n depth: 20,\n};\n\n/**\n * Body parser hook\n */\nconst addQsParser = (app: Koa, settings: Config) => {\n Object.defineProperty(app.request, 'query', {\n configurable: false,\n enumerable: true,\n /*\n * Get parsed query-string.\n */\n get() {\n const qstr = this.querystring;\n\n this._querycache = this._querycache || {};\n const cache = this._querycache;\n\n if (!cache[qstr]) {\n cache[qstr] = qs.parse(qstr, settings);\n }\n\n return cache[qstr];\n },\n\n /*\n * Set query-string as an object.\n */\n set(obj) {\n this.querystring = qs.stringify(obj);\n },\n } satisfies PropertyDescriptor & ThisType<Koa.BaseRequest>);\n\n return app;\n};\n\nexport const query: Core.MiddlewareFactory = (\n config: Partial<Config>,\n { strapi }: { strapi: Core.Strapi }\n) => {\n addQsParser(strapi.server.app, { ...defaults, ...config } as Config);\n};\n"],"names":[],"mappings":";AAMA,MAAM,WAAmB;AAAA,EACvB,oBAAoB;AAAA,EACpB,YAAY;AAAA,EACZ,OAAO;AACT;AAKA,MAAM,cAAc,CAAC,KAAU,aAAqB;AAC3C,SAAA,eAAe,IAAI,SAAS,SAAS;AAAA,IAC1C,cAAc;AAAA,IACd,YAAY;AAAA;AAAA;AAAA;AAAA,IAIZ,MAAM;AACJ,YAAM,OAAO,KAAK;AAEb,WAAA,cAAc,KAAK,eAAe,CAAA;AACvC,YAAM,QAAQ,KAAK;AAEf,UAAA,CAAC,MAAM,IAAI,GAAG;AAChB,cAAM,IAAI,IAAI,GAAG,MAAM,MAAM,QAAQ;AAAA,MACvC;AAEA,aAAO,MAAM,IAAI;AAAA,IACnB;AAAA;AAAA;AAAA;AAAA,IAKA,IAAI,KAAK;AACF,WAAA,cAAc,GAAG,UAAU,GAAG;AAAA,IACrC;AAAA,EAAA,CACwD;AAEnD,SAAA;AACT;AAEO,MAAM,QAAgC,CAC3C,QACA,EAAE,aACC;AACS,cAAA,OAAO,OAAO,KAAK,EAAE,GAAG,UAAU,GAAG,QAAkB;AACrE;"}
@@ -1,12 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const _ = require("lodash/fp");
3
+ const fp = require("lodash/fp");
4
4
  const responses = (config = {}) => {
5
5
  return async (ctx, next) => {
6
6
  await next();
7
7
  const { status } = ctx;
8
8
  const handler = config?.handlers?.[status];
9
- if (_.isFunction(handler)) {
9
+ if (fp.isFunction(handler)) {
10
10
  await handler(ctx, next);
11
11
  }
12
12
  };
@@ -1 +1 @@
1
- {"version":3,"file":"responses.js","sources":["../../src/middlewares/responses.ts"],"sourcesContent":["import { isFunction } from 'lodash/fp';\nimport type { Core } from '@strapi/types';\n\nexport interface Config {\n handlers?: Record<number, Core.MiddlewareHandler>;\n}\n\nexport const responses: Core.MiddlewareFactory<Config> = (config = {}) => {\n return async (ctx, next) => {\n await next();\n\n const { status } = ctx;\n const handler = config?.handlers?.[status];\n\n if (isFunction(handler)) {\n await handler(ctx, next);\n }\n };\n};\n"],"names":["isFunction"],"mappings":";;;AAOO,MAAM,YAA4C,CAAC,SAAS,OAAO;AACjE,SAAA,OAAO,KAAK,SAAS;AAC1B,UAAM,KAAK;AAEL,UAAA,EAAE,OAAW,IAAA;AACb,UAAA,UAAU,QAAQ,WAAW,MAAM;AAErC,QAAAA,EAAAA,WAAW,OAAO,GAAG;AACjB,YAAA,QAAQ,KAAK,IAAI;AAAA,IACzB;AAAA,EAAA;AAEJ;;"}
1
+ {"version":3,"file":"responses.js","sources":["../../src/middlewares/responses.ts"],"sourcesContent":["import { isFunction } from 'lodash/fp';\nimport type { Core } from '@strapi/types';\n\nexport interface Config {\n handlers?: Record<number, Core.MiddlewareHandler>;\n}\n\nexport const responses: Core.MiddlewareFactory<Config> = (config = {}) => {\n return async (ctx, next) => {\n await next();\n\n const { status } = ctx;\n const handler = config?.handlers?.[status];\n\n if (isFunction(handler)) {\n await handler(ctx, next);\n }\n };\n};\n"],"names":["isFunction"],"mappings":";;;AAOO,MAAM,YAA4C,CAAC,SAAS,OAAO;AACjE,SAAA,OAAO,KAAK,SAAS;AAC1B,UAAM,KAAK;AAEL,UAAA,EAAE,OAAW,IAAA;AACb,UAAA,UAAU,QAAQ,WAAW,MAAM;AAErC,QAAAA,GAAAA,WAAW,OAAO,GAAG;AACjB,YAAA,QAAQ,KAAK,IAAI;AAAA,IACzB;AAAA,EAAA;AAEJ;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../../src/middlewares/security.ts"],"names":[],"mappings":"AACA,OAAe,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE/C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE1C,MAAM,MAAM,MAAM,GAAG,WAAW,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAkC3D,eAAO,MAAM,QAAQ,EAAE,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAkEjD,CAAC"}
1
+ {"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../../src/middlewares/security.ts"],"names":[],"mappings":"AACA,OAAe,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE/C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE1C,MAAM,MAAM,MAAM,GAAG,WAAW,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAkC3D,eAAO,MAAM,QAAQ,EAAE,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAmEjD,CAAC"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const _ = require("lodash/fp");
3
+ const fp = require("lodash/fp");
4
4
  const helmet = require("koa-helmet");
5
5
  const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
6
6
  const helmet__default = /* @__PURE__ */ _interopDefault(helmet);
@@ -28,14 +28,14 @@ const defaults = {
28
28
  }
29
29
  };
30
30
  const mergeConfig = (existingConfig, newConfig) => {
31
- return _.mergeWith(
31
+ return fp.mergeWith(
32
32
  (obj, src) => Array.isArray(obj) && Array.isArray(src) ? obj.concat(src) : void 0,
33
33
  existingConfig,
34
34
  newConfig
35
35
  );
36
36
  };
37
37
  const security = (config, { strapi }) => (ctx, next) => {
38
- let helmetConfig = _.defaultsDeep(defaults, config);
38
+ let helmetConfig = fp.defaultsDeep(defaults, config);
39
39
  const specialPaths = ["/documentation"];
40
40
  const directives = {
41
41
  "script-src": ["'self'", "'unsafe-inline'", "cdn.jsdelivr.net"],
@@ -62,7 +62,7 @@ const security = (config, { strapi }) => (ctx, next) => {
62
62
  }
63
63
  });
64
64
  }
65
- if (["development", "test"].includes(process.env.NODE_ENV ?? "") && ctx.method === "GET" && ["/admin"].some((str) => ctx.path.startsWith(str))) {
65
+ if (["development", "test"].includes(process.env.NODE_ENV ?? "") && ctx.method === "GET" && ctx.path.startsWith(strapi.config.get("admin.path"))) {
66
66
  helmetConfig = mergeConfig(helmetConfig, {
67
67
  contentSecurityPolicy: {
68
68
  directives: {
@@ -1 +1 @@
1
- {"version":3,"file":"security.js","sources":["../../src/middlewares/security.ts"],"sourcesContent":["import { defaultsDeep, mergeWith } from 'lodash/fp';\nimport helmet, { KoaHelmet } from 'koa-helmet';\n\nimport type { Core } from '@strapi/types';\n\nexport type Config = NonNullable<Parameters<KoaHelmet>[0]>;\n\nconst defaults: Config = {\n crossOriginEmbedderPolicy: false,\n crossOriginOpenerPolicy: false,\n crossOriginResourcePolicy: false,\n originAgentCluster: false,\n contentSecurityPolicy: {\n useDefaults: true,\n directives: {\n 'connect-src': [\"'self'\", 'https:'],\n 'img-src': [\"'self'\", 'data:', 'blob:', 'https://market-assets.strapi.io'],\n 'media-src': [\"'self'\", 'data:', 'blob:'],\n upgradeInsecureRequests: null,\n },\n },\n xssFilter: false,\n hsts: {\n maxAge: 31536000,\n includeSubDomains: true,\n },\n frameguard: {\n action: 'sameorigin',\n },\n};\n\nconst mergeConfig = (existingConfig: Config, newConfig: Config) => {\n return mergeWith(\n (obj, src) => (Array.isArray(obj) && Array.isArray(src) ? obj.concat(src) : undefined),\n existingConfig,\n newConfig\n );\n};\n\nexport const security: Core.MiddlewareFactory<Config> =\n (config, { strapi }) =>\n (ctx, next) => {\n let helmetConfig: Config = defaultsDeep(defaults, config);\n\n const specialPaths = ['/documentation'];\n\n const directives: {\n 'script-src': string[];\n 'img-src': string[];\n 'manifest-src': string[];\n 'frame-src': string[];\n } = {\n 'script-src': [\"'self'\", \"'unsafe-inline'\", 'cdn.jsdelivr.net'],\n 'img-src': [\"'self'\", 'data:', 'cdn.jsdelivr.net', 'strapi.io'],\n 'manifest-src': [],\n 'frame-src': [],\n };\n\n // if apollo graphql playground is enabled, add exceptions for it\n if (strapi.plugin('graphql')?.service('utils').playground.isEnabled()) {\n const { config: gqlConfig } = strapi.plugin('graphql');\n specialPaths.push(gqlConfig('endpoint'));\n\n directives['script-src'].push(`https: 'unsafe-inline'`);\n directives['img-src'].push(`'apollo-server-landing-page.cdn.apollographql.com'`);\n directives['manifest-src'].push(`'self'`);\n directives['manifest-src'].push('apollo-server-landing-page.cdn.apollographql.com');\n directives['frame-src'].push(`'self'`);\n directives['frame-src'].push('sandbox.embed.apollographql.com');\n }\n\n // TODO: we shouldn't combine playground exceptions with documentation for all routes, we should first check the path and then return exceptions specific to that\n if (ctx.method === 'GET' && specialPaths.some((str) => ctx.path.startsWith(str))) {\n helmetConfig = mergeConfig(helmetConfig, {\n crossOriginEmbedderPolicy: false, // TODO: only use this for graphql playground\n contentSecurityPolicy: {\n directives,\n },\n });\n }\n\n /**\n * These are for vite's watch mode so it can accurately\n * connect to the HMR websocket & reconnect on failure\n * or when the server restarts.\n *\n * It only applies in development, and only on GET requests\n * that are part of the admin route.\n */\n if (\n ['development', 'test'].includes(process.env.NODE_ENV ?? '') &&\n ctx.method === 'GET' &&\n ['/admin'].some((str) => ctx.path.startsWith(str))\n ) {\n helmetConfig = mergeConfig(helmetConfig, {\n contentSecurityPolicy: {\n directives: {\n 'script-src': [\"'self'\", \"'unsafe-inline'\"],\n 'connect-src': [\"'self'\", 'http:', 'https:', 'ws:'],\n },\n },\n });\n }\n\n return helmet(helmetConfig)(ctx, next);\n };\n"],"names":["mergeWith","defaultsDeep","helmet"],"mappings":";;;;;;AAOA,MAAM,WAAmB;AAAA,EACvB,2BAA2B;AAAA,EAC3B,yBAAyB;AAAA,EACzB,2BAA2B;AAAA,EAC3B,oBAAoB;AAAA,EACpB,uBAAuB;AAAA,IACrB,aAAa;AAAA,IACb,YAAY;AAAA,MACV,eAAe,CAAC,UAAU,QAAQ;AAAA,MAClC,WAAW,CAAC,UAAU,SAAS,SAAS,iCAAiC;AAAA,MACzE,aAAa,CAAC,UAAU,SAAS,OAAO;AAAA,MACxC,yBAAyB;AAAA,IAC3B;AAAA,EACF;AAAA,EACA,WAAW;AAAA,EACX,MAAM;AAAA,IACJ,QAAQ;AAAA,IACR,mBAAmB;AAAA,EACrB;AAAA,EACA,YAAY;AAAA,IACV,QAAQ;AAAA,EACV;AACF;AAEA,MAAM,cAAc,CAAC,gBAAwB,cAAsB;AAC1D,SAAAA,EAAA;AAAA,IACL,CAAC,KAAK,QAAS,MAAM,QAAQ,GAAG,KAAK,MAAM,QAAQ,GAAG,IAAI,IAAI,OAAO,GAAG,IAAI;AAAA,IAC5E;AAAA,IACA;AAAA,EAAA;AAEJ;AAEa,MAAA,WACX,CAAC,QAAQ,EAAE,aACX,CAAC,KAAK,SAAS;AACT,MAAA,eAAuBC,EAAAA,aAAa,UAAU,MAAM;AAElD,QAAA,eAAe,CAAC,gBAAgB;AAEtC,QAAM,aAKF;AAAA,IACF,cAAc,CAAC,UAAU,mBAAmB,kBAAkB;AAAA,IAC9D,WAAW,CAAC,UAAU,SAAS,oBAAoB,WAAW;AAAA,IAC9D,gBAAgB,CAAC;AAAA,IACjB,aAAa,CAAC;AAAA,EAAA;AAIZ,MAAA,OAAO,OAAO,SAAS,GAAG,QAAQ,OAAO,EAAE,WAAW,aAAa;AACrE,UAAM,EAAE,QAAQ,UAAA,IAAc,OAAO,OAAO,SAAS;AACxC,iBAAA,KAAK,UAAU,UAAU,CAAC;AAE5B,eAAA,YAAY,EAAE,KAAK,wBAAwB;AAC3C,eAAA,SAAS,EAAE,KAAK,oDAAoD;AACpE,eAAA,cAAc,EAAE,KAAK,QAAQ;AAC7B,eAAA,cAAc,EAAE,KAAK,kDAAkD;AACvE,eAAA,WAAW,EAAE,KAAK,QAAQ;AAC1B,eAAA,WAAW,EAAE,KAAK,iCAAiC;AAAA,EAChE;AAGA,MAAI,IAAI,WAAW,SAAS,aAAa,KAAK,CAAC,QAAQ,IAAI,KAAK,WAAW,GAAG,CAAC,GAAG;AAChF,mBAAe,YAAY,cAAc;AAAA,MACvC,2BAA2B;AAAA;AAAA,MAC3B,uBAAuB;AAAA,QACrB;AAAA,MACF;AAAA,IAAA,CACD;AAAA,EACH;AAWE,MAAA,CAAC,eAAe,MAAM,EAAE,SAAS,QAAQ,IAAI,YAAY,EAAE,KAC3D,IAAI,WAAW,SACf,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,KAAK,WAAW,GAAG,CAAC,GACjD;AACA,mBAAe,YAAY,cAAc;AAAA,MACvC,uBAAuB;AAAA,QACrB,YAAY;AAAA,UACV,cAAc,CAAC,UAAU,iBAAiB;AAAA,UAC1C,eAAe,CAAC,UAAU,SAAS,UAAU,KAAK;AAAA,QACpD;AAAA,MACF;AAAA,IAAA,CACD;AAAA,EACH;AAEA,SAAOC,gBAAO,QAAA,YAAY,EAAE,KAAK,IAAI;AACvC;;"}
1
+ {"version":3,"file":"security.js","sources":["../../src/middlewares/security.ts"],"sourcesContent":["import { defaultsDeep, mergeWith } from 'lodash/fp';\nimport helmet, { KoaHelmet } from 'koa-helmet';\n\nimport type { Core } from '@strapi/types';\n\nexport type Config = NonNullable<Parameters<KoaHelmet>[0]>;\n\nconst defaults: Config = {\n crossOriginEmbedderPolicy: false,\n crossOriginOpenerPolicy: false,\n crossOriginResourcePolicy: false,\n originAgentCluster: false,\n contentSecurityPolicy: {\n useDefaults: true,\n directives: {\n 'connect-src': [\"'self'\", 'https:'],\n 'img-src': [\"'self'\", 'data:', 'blob:', 'https://market-assets.strapi.io'],\n 'media-src': [\"'self'\", 'data:', 'blob:'],\n upgradeInsecureRequests: null,\n },\n },\n xssFilter: false,\n hsts: {\n maxAge: 31536000,\n includeSubDomains: true,\n },\n frameguard: {\n action: 'sameorigin',\n },\n};\n\nconst mergeConfig = (existingConfig: Config, newConfig: Config) => {\n return mergeWith(\n (obj, src) => (Array.isArray(obj) && Array.isArray(src) ? obj.concat(src) : undefined),\n existingConfig,\n newConfig\n );\n};\n\nexport const security: Core.MiddlewareFactory<Config> =\n (config, { strapi }) =>\n (ctx, next) => {\n let helmetConfig: Config = defaultsDeep(defaults, config);\n\n const specialPaths = ['/documentation'];\n\n const directives: {\n 'script-src': string[];\n 'img-src': string[];\n 'manifest-src': string[];\n 'frame-src': string[];\n } = {\n 'script-src': [\"'self'\", \"'unsafe-inline'\", 'cdn.jsdelivr.net'],\n 'img-src': [\"'self'\", 'data:', 'cdn.jsdelivr.net', 'strapi.io'],\n 'manifest-src': [],\n 'frame-src': [],\n };\n\n // if apollo graphql playground is enabled, add exceptions for it\n if (strapi.plugin('graphql')?.service('utils').playground.isEnabled()) {\n const { config: gqlConfig } = strapi.plugin('graphql');\n specialPaths.push(gqlConfig('endpoint'));\n\n directives['script-src'].push(`https: 'unsafe-inline'`);\n directives['img-src'].push(`'apollo-server-landing-page.cdn.apollographql.com'`);\n directives['manifest-src'].push(`'self'`);\n directives['manifest-src'].push('apollo-server-landing-page.cdn.apollographql.com');\n directives['frame-src'].push(`'self'`);\n directives['frame-src'].push('sandbox.embed.apollographql.com');\n }\n\n // TODO: we shouldn't combine playground exceptions with documentation for all routes, we should first check the path and then return exceptions specific to that\n if (ctx.method === 'GET' && specialPaths.some((str) => ctx.path.startsWith(str))) {\n helmetConfig = mergeConfig(helmetConfig, {\n crossOriginEmbedderPolicy: false, // TODO: only use this for graphql playground\n contentSecurityPolicy: {\n directives,\n },\n });\n }\n\n /**\n * These are for vite's watch mode so it can accurately\n * connect to the HMR websocket & reconnect on failure\n * or when the server restarts.\n *\n * It only applies in development, and only on GET requests\n * that are part of the admin route.\n */\n\n if (\n ['development', 'test'].includes(process.env.NODE_ENV ?? '') &&\n ctx.method === 'GET' &&\n ctx.path.startsWith(strapi.config.get('admin.path'))\n ) {\n helmetConfig = mergeConfig(helmetConfig, {\n contentSecurityPolicy: {\n directives: {\n 'script-src': [\"'self'\", \"'unsafe-inline'\"],\n 'connect-src': [\"'self'\", 'http:', 'https:', 'ws:'],\n },\n },\n });\n }\n\n return helmet(helmetConfig)(ctx, next);\n };\n"],"names":["mergeWith","defaultsDeep","helmet"],"mappings":";;;;;;AAOA,MAAM,WAAmB;AAAA,EACvB,2BAA2B;AAAA,EAC3B,yBAAyB;AAAA,EACzB,2BAA2B;AAAA,EAC3B,oBAAoB;AAAA,EACpB,uBAAuB;AAAA,IACrB,aAAa;AAAA,IACb,YAAY;AAAA,MACV,eAAe,CAAC,UAAU,QAAQ;AAAA,MAClC,WAAW,CAAC,UAAU,SAAS,SAAS,iCAAiC;AAAA,MACzE,aAAa,CAAC,UAAU,SAAS,OAAO;AAAA,MACxC,yBAAyB;AAAA,IAC3B;AAAA,EACF;AAAA,EACA,WAAW;AAAA,EACX,MAAM;AAAA,IACJ,QAAQ;AAAA,IACR,mBAAmB;AAAA,EACrB;AAAA,EACA,YAAY;AAAA,IACV,QAAQ;AAAA,EACV;AACF;AAEA,MAAM,cAAc,CAAC,gBAAwB,cAAsB;AAC1D,SAAAA,GAAA;AAAA,IACL,CAAC,KAAK,QAAS,MAAM,QAAQ,GAAG,KAAK,MAAM,QAAQ,GAAG,IAAI,IAAI,OAAO,GAAG,IAAI;AAAA,IAC5E;AAAA,IACA;AAAA,EAAA;AAEJ;AAEa,MAAA,WACX,CAAC,QAAQ,EAAE,aACX,CAAC,KAAK,SAAS;AACT,MAAA,eAAuBC,GAAAA,aAAa,UAAU,MAAM;AAElD,QAAA,eAAe,CAAC,gBAAgB;AAEtC,QAAM,aAKF;AAAA,IACF,cAAc,CAAC,UAAU,mBAAmB,kBAAkB;AAAA,IAC9D,WAAW,CAAC,UAAU,SAAS,oBAAoB,WAAW;AAAA,IAC9D,gBAAgB,CAAC;AAAA,IACjB,aAAa,CAAC;AAAA,EAAA;AAIZ,MAAA,OAAO,OAAO,SAAS,GAAG,QAAQ,OAAO,EAAE,WAAW,aAAa;AACrE,UAAM,EAAE,QAAQ,UAAA,IAAc,OAAO,OAAO,SAAS;AACxC,iBAAA,KAAK,UAAU,UAAU,CAAC;AAE5B,eAAA,YAAY,EAAE,KAAK,wBAAwB;AAC3C,eAAA,SAAS,EAAE,KAAK,oDAAoD;AACpE,eAAA,cAAc,EAAE,KAAK,QAAQ;AAC7B,eAAA,cAAc,EAAE,KAAK,kDAAkD;AACvE,eAAA,WAAW,EAAE,KAAK,QAAQ;AAC1B,eAAA,WAAW,EAAE,KAAK,iCAAiC;AAAA,EAChE;AAGA,MAAI,IAAI,WAAW,SAAS,aAAa,KAAK,CAAC,QAAQ,IAAI,KAAK,WAAW,GAAG,CAAC,GAAG;AAChF,mBAAe,YAAY,cAAc;AAAA,MACvC,2BAA2B;AAAA;AAAA,MAC3B,uBAAuB;AAAA,QACrB;AAAA,MACF;AAAA,IAAA,CACD;AAAA,EACH;AAYE,MAAA,CAAC,eAAe,MAAM,EAAE,SAAS,QAAQ,IAAI,YAAY,EAAE,KAC3D,IAAI,WAAW,SACf,IAAI,KAAK,WAAW,OAAO,OAAO,IAAI,YAAY,CAAC,GACnD;AACA,mBAAe,YAAY,cAAc;AAAA,MACvC,uBAAuB;AAAA,QACrB,YAAY;AAAA,UACV,cAAc,CAAC,UAAU,iBAAiB;AAAA,UAC1C,eAAe,CAAC,UAAU,SAAS,UAAU,KAAK;AAAA,QACpD;AAAA,MACF;AAAA,IAAA,CACD;AAAA,EACH;AAEA,SAAOC,gBAAO,QAAA,YAAY,EAAE,KAAK,IAAI;AACvC;;"}
@@ -58,7 +58,7 @@ const security = (config, { strapi }) => (ctx, next) => {
58
58
  }
59
59
  });
60
60
  }
61
- if (["development", "test"].includes(process.env.NODE_ENV ?? "") && ctx.method === "GET" && ["/admin"].some((str) => ctx.path.startsWith(str))) {
61
+ if (["development", "test"].includes(process.env.NODE_ENV ?? "") && ctx.method === "GET" && ctx.path.startsWith(strapi.config.get("admin.path"))) {
62
62
  helmetConfig = mergeConfig(helmetConfig, {
63
63
  contentSecurityPolicy: {
64
64
  directives: {
@@ -1 +1 @@
1
- {"version":3,"file":"security.mjs","sources":["../../src/middlewares/security.ts"],"sourcesContent":["import { defaultsDeep, mergeWith } from 'lodash/fp';\nimport helmet, { KoaHelmet } from 'koa-helmet';\n\nimport type { Core } from '@strapi/types';\n\nexport type Config = NonNullable<Parameters<KoaHelmet>[0]>;\n\nconst defaults: Config = {\n crossOriginEmbedderPolicy: false,\n crossOriginOpenerPolicy: false,\n crossOriginResourcePolicy: false,\n originAgentCluster: false,\n contentSecurityPolicy: {\n useDefaults: true,\n directives: {\n 'connect-src': [\"'self'\", 'https:'],\n 'img-src': [\"'self'\", 'data:', 'blob:', 'https://market-assets.strapi.io'],\n 'media-src': [\"'self'\", 'data:', 'blob:'],\n upgradeInsecureRequests: null,\n },\n },\n xssFilter: false,\n hsts: {\n maxAge: 31536000,\n includeSubDomains: true,\n },\n frameguard: {\n action: 'sameorigin',\n },\n};\n\nconst mergeConfig = (existingConfig: Config, newConfig: Config) => {\n return mergeWith(\n (obj, src) => (Array.isArray(obj) && Array.isArray(src) ? obj.concat(src) : undefined),\n existingConfig,\n newConfig\n );\n};\n\nexport const security: Core.MiddlewareFactory<Config> =\n (config, { strapi }) =>\n (ctx, next) => {\n let helmetConfig: Config = defaultsDeep(defaults, config);\n\n const specialPaths = ['/documentation'];\n\n const directives: {\n 'script-src': string[];\n 'img-src': string[];\n 'manifest-src': string[];\n 'frame-src': string[];\n } = {\n 'script-src': [\"'self'\", \"'unsafe-inline'\", 'cdn.jsdelivr.net'],\n 'img-src': [\"'self'\", 'data:', 'cdn.jsdelivr.net', 'strapi.io'],\n 'manifest-src': [],\n 'frame-src': [],\n };\n\n // if apollo graphql playground is enabled, add exceptions for it\n if (strapi.plugin('graphql')?.service('utils').playground.isEnabled()) {\n const { config: gqlConfig } = strapi.plugin('graphql');\n specialPaths.push(gqlConfig('endpoint'));\n\n directives['script-src'].push(`https: 'unsafe-inline'`);\n directives['img-src'].push(`'apollo-server-landing-page.cdn.apollographql.com'`);\n directives['manifest-src'].push(`'self'`);\n directives['manifest-src'].push('apollo-server-landing-page.cdn.apollographql.com');\n directives['frame-src'].push(`'self'`);\n directives['frame-src'].push('sandbox.embed.apollographql.com');\n }\n\n // TODO: we shouldn't combine playground exceptions with documentation for all routes, we should first check the path and then return exceptions specific to that\n if (ctx.method === 'GET' && specialPaths.some((str) => ctx.path.startsWith(str))) {\n helmetConfig = mergeConfig(helmetConfig, {\n crossOriginEmbedderPolicy: false, // TODO: only use this for graphql playground\n contentSecurityPolicy: {\n directives,\n },\n });\n }\n\n /**\n * These are for vite's watch mode so it can accurately\n * connect to the HMR websocket & reconnect on failure\n * or when the server restarts.\n *\n * It only applies in development, and only on GET requests\n * that are part of the admin route.\n */\n if (\n ['development', 'test'].includes(process.env.NODE_ENV ?? '') &&\n ctx.method === 'GET' &&\n ['/admin'].some((str) => ctx.path.startsWith(str))\n ) {\n helmetConfig = mergeConfig(helmetConfig, {\n contentSecurityPolicy: {\n directives: {\n 'script-src': [\"'self'\", \"'unsafe-inline'\"],\n 'connect-src': [\"'self'\", 'http:', 'https:', 'ws:'],\n },\n },\n });\n }\n\n return helmet(helmetConfig)(ctx, next);\n };\n"],"names":[],"mappings":";;AAOA,MAAM,WAAmB;AAAA,EACvB,2BAA2B;AAAA,EAC3B,yBAAyB;AAAA,EACzB,2BAA2B;AAAA,EAC3B,oBAAoB;AAAA,EACpB,uBAAuB;AAAA,IACrB,aAAa;AAAA,IACb,YAAY;AAAA,MACV,eAAe,CAAC,UAAU,QAAQ;AAAA,MAClC,WAAW,CAAC,UAAU,SAAS,SAAS,iCAAiC;AAAA,MACzE,aAAa,CAAC,UAAU,SAAS,OAAO;AAAA,MACxC,yBAAyB;AAAA,IAC3B;AAAA,EACF;AAAA,EACA,WAAW;AAAA,EACX,MAAM;AAAA,IACJ,QAAQ;AAAA,IACR,mBAAmB;AAAA,EACrB;AAAA,EACA,YAAY;AAAA,IACV,QAAQ;AAAA,EACV;AACF;AAEA,MAAM,cAAc,CAAC,gBAAwB,cAAsB;AAC1D,SAAA;AAAA,IACL,CAAC,KAAK,QAAS,MAAM,QAAQ,GAAG,KAAK,MAAM,QAAQ,GAAG,IAAI,IAAI,OAAO,GAAG,IAAI;AAAA,IAC5E;AAAA,IACA;AAAA,EAAA;AAEJ;AAEa,MAAA,WACX,CAAC,QAAQ,EAAE,aACX,CAAC,KAAK,SAAS;AACT,MAAA,eAAuB,aAAa,UAAU,MAAM;AAElD,QAAA,eAAe,CAAC,gBAAgB;AAEtC,QAAM,aAKF;AAAA,IACF,cAAc,CAAC,UAAU,mBAAmB,kBAAkB;AAAA,IAC9D,WAAW,CAAC,UAAU,SAAS,oBAAoB,WAAW;AAAA,IAC9D,gBAAgB,CAAC;AAAA,IACjB,aAAa,CAAC;AAAA,EAAA;AAIZ,MAAA,OAAO,OAAO,SAAS,GAAG,QAAQ,OAAO,EAAE,WAAW,aAAa;AACrE,UAAM,EAAE,QAAQ,UAAA,IAAc,OAAO,OAAO,SAAS;AACxC,iBAAA,KAAK,UAAU,UAAU,CAAC;AAE5B,eAAA,YAAY,EAAE,KAAK,wBAAwB;AAC3C,eAAA,SAAS,EAAE,KAAK,oDAAoD;AACpE,eAAA,cAAc,EAAE,KAAK,QAAQ;AAC7B,eAAA,cAAc,EAAE,KAAK,kDAAkD;AACvE,eAAA,WAAW,EAAE,KAAK,QAAQ;AAC1B,eAAA,WAAW,EAAE,KAAK,iCAAiC;AAAA,EAChE;AAGA,MAAI,IAAI,WAAW,SAAS,aAAa,KAAK,CAAC,QAAQ,IAAI,KAAK,WAAW,GAAG,CAAC,GAAG;AAChF,mBAAe,YAAY,cAAc;AAAA,MACvC,2BAA2B;AAAA;AAAA,MAC3B,uBAAuB;AAAA,QACrB;AAAA,MACF;AAAA,IAAA,CACD;AAAA,EACH;AAWE,MAAA,CAAC,eAAe,MAAM,EAAE,SAAS,QAAQ,IAAI,YAAY,EAAE,KAC3D,IAAI,WAAW,SACf,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,KAAK,WAAW,GAAG,CAAC,GACjD;AACA,mBAAe,YAAY,cAAc;AAAA,MACvC,uBAAuB;AAAA,QACrB,YAAY;AAAA,UACV,cAAc,CAAC,UAAU,iBAAiB;AAAA,UAC1C,eAAe,CAAC,UAAU,SAAS,UAAU,KAAK;AAAA,QACpD;AAAA,MACF;AAAA,IAAA,CACD;AAAA,EACH;AAEA,SAAO,OAAO,YAAY,EAAE,KAAK,IAAI;AACvC;"}
1
+ {"version":3,"file":"security.mjs","sources":["../../src/middlewares/security.ts"],"sourcesContent":["import { defaultsDeep, mergeWith } from 'lodash/fp';\nimport helmet, { KoaHelmet } from 'koa-helmet';\n\nimport type { Core } from '@strapi/types';\n\nexport type Config = NonNullable<Parameters<KoaHelmet>[0]>;\n\nconst defaults: Config = {\n crossOriginEmbedderPolicy: false,\n crossOriginOpenerPolicy: false,\n crossOriginResourcePolicy: false,\n originAgentCluster: false,\n contentSecurityPolicy: {\n useDefaults: true,\n directives: {\n 'connect-src': [\"'self'\", 'https:'],\n 'img-src': [\"'self'\", 'data:', 'blob:', 'https://market-assets.strapi.io'],\n 'media-src': [\"'self'\", 'data:', 'blob:'],\n upgradeInsecureRequests: null,\n },\n },\n xssFilter: false,\n hsts: {\n maxAge: 31536000,\n includeSubDomains: true,\n },\n frameguard: {\n action: 'sameorigin',\n },\n};\n\nconst mergeConfig = (existingConfig: Config, newConfig: Config) => {\n return mergeWith(\n (obj, src) => (Array.isArray(obj) && Array.isArray(src) ? obj.concat(src) : undefined),\n existingConfig,\n newConfig\n );\n};\n\nexport const security: Core.MiddlewareFactory<Config> =\n (config, { strapi }) =>\n (ctx, next) => {\n let helmetConfig: Config = defaultsDeep(defaults, config);\n\n const specialPaths = ['/documentation'];\n\n const directives: {\n 'script-src': string[];\n 'img-src': string[];\n 'manifest-src': string[];\n 'frame-src': string[];\n } = {\n 'script-src': [\"'self'\", \"'unsafe-inline'\", 'cdn.jsdelivr.net'],\n 'img-src': [\"'self'\", 'data:', 'cdn.jsdelivr.net', 'strapi.io'],\n 'manifest-src': [],\n 'frame-src': [],\n };\n\n // if apollo graphql playground is enabled, add exceptions for it\n if (strapi.plugin('graphql')?.service('utils').playground.isEnabled()) {\n const { config: gqlConfig } = strapi.plugin('graphql');\n specialPaths.push(gqlConfig('endpoint'));\n\n directives['script-src'].push(`https: 'unsafe-inline'`);\n directives['img-src'].push(`'apollo-server-landing-page.cdn.apollographql.com'`);\n directives['manifest-src'].push(`'self'`);\n directives['manifest-src'].push('apollo-server-landing-page.cdn.apollographql.com');\n directives['frame-src'].push(`'self'`);\n directives['frame-src'].push('sandbox.embed.apollographql.com');\n }\n\n // TODO: we shouldn't combine playground exceptions with documentation for all routes, we should first check the path and then return exceptions specific to that\n if (ctx.method === 'GET' && specialPaths.some((str) => ctx.path.startsWith(str))) {\n helmetConfig = mergeConfig(helmetConfig, {\n crossOriginEmbedderPolicy: false, // TODO: only use this for graphql playground\n contentSecurityPolicy: {\n directives,\n },\n });\n }\n\n /**\n * These are for vite's watch mode so it can accurately\n * connect to the HMR websocket & reconnect on failure\n * or when the server restarts.\n *\n * It only applies in development, and only on GET requests\n * that are part of the admin route.\n */\n\n if (\n ['development', 'test'].includes(process.env.NODE_ENV ?? '') &&\n ctx.method === 'GET' &&\n ctx.path.startsWith(strapi.config.get('admin.path'))\n ) {\n helmetConfig = mergeConfig(helmetConfig, {\n contentSecurityPolicy: {\n directives: {\n 'script-src': [\"'self'\", \"'unsafe-inline'\"],\n 'connect-src': [\"'self'\", 'http:', 'https:', 'ws:'],\n },\n },\n });\n }\n\n return helmet(helmetConfig)(ctx, next);\n };\n"],"names":[],"mappings":";;AAOA,MAAM,WAAmB;AAAA,EACvB,2BAA2B;AAAA,EAC3B,yBAAyB;AAAA,EACzB,2BAA2B;AAAA,EAC3B,oBAAoB;AAAA,EACpB,uBAAuB;AAAA,IACrB,aAAa;AAAA,IACb,YAAY;AAAA,MACV,eAAe,CAAC,UAAU,QAAQ;AAAA,MAClC,WAAW,CAAC,UAAU,SAAS,SAAS,iCAAiC;AAAA,MACzE,aAAa,CAAC,UAAU,SAAS,OAAO;AAAA,MACxC,yBAAyB;AAAA,IAC3B;AAAA,EACF;AAAA,EACA,WAAW;AAAA,EACX,MAAM;AAAA,IACJ,QAAQ;AAAA,IACR,mBAAmB;AAAA,EACrB;AAAA,EACA,YAAY;AAAA,IACV,QAAQ;AAAA,EACV;AACF;AAEA,MAAM,cAAc,CAAC,gBAAwB,cAAsB;AAC1D,SAAA;AAAA,IACL,CAAC,KAAK,QAAS,MAAM,QAAQ,GAAG,KAAK,MAAM,QAAQ,GAAG,IAAI,IAAI,OAAO,GAAG,IAAI;AAAA,IAC5E;AAAA,IACA;AAAA,EAAA;AAEJ;AAEa,MAAA,WACX,CAAC,QAAQ,EAAE,aACX,CAAC,KAAK,SAAS;AACT,MAAA,eAAuB,aAAa,UAAU,MAAM;AAElD,QAAA,eAAe,CAAC,gBAAgB;AAEtC,QAAM,aAKF;AAAA,IACF,cAAc,CAAC,UAAU,mBAAmB,kBAAkB;AAAA,IAC9D,WAAW,CAAC,UAAU,SAAS,oBAAoB,WAAW;AAAA,IAC9D,gBAAgB,CAAC;AAAA,IACjB,aAAa,CAAC;AAAA,EAAA;AAIZ,MAAA,OAAO,OAAO,SAAS,GAAG,QAAQ,OAAO,EAAE,WAAW,aAAa;AACrE,UAAM,EAAE,QAAQ,UAAA,IAAc,OAAO,OAAO,SAAS;AACxC,iBAAA,KAAK,UAAU,UAAU,CAAC;AAE5B,eAAA,YAAY,EAAE,KAAK,wBAAwB;AAC3C,eAAA,SAAS,EAAE,KAAK,oDAAoD;AACpE,eAAA,cAAc,EAAE,KAAK,QAAQ;AAC7B,eAAA,cAAc,EAAE,KAAK,kDAAkD;AACvE,eAAA,WAAW,EAAE,KAAK,QAAQ;AAC1B,eAAA,WAAW,EAAE,KAAK,iCAAiC;AAAA,EAChE;AAGA,MAAI,IAAI,WAAW,SAAS,aAAa,KAAK,CAAC,QAAQ,IAAI,KAAK,WAAW,GAAG,CAAC,GAAG;AAChF,mBAAe,YAAY,cAAc;AAAA,MACvC,2BAA2B;AAAA;AAAA,MAC3B,uBAAuB;AAAA,QACrB;AAAA,MACF;AAAA,IAAA,CACD;AAAA,EACH;AAYE,MAAA,CAAC,eAAe,MAAM,EAAE,SAAS,QAAQ,IAAI,YAAY,EAAE,KAC3D,IAAI,WAAW,SACf,IAAI,KAAK,WAAW,OAAO,OAAO,IAAI,YAAY,CAAC,GACnD;AACA,mBAAe,YAAY,cAAc;AAAA,MACvC,uBAAuB;AAAA,QACrB,YAAY;AAAA,UACV,cAAc,CAAC,UAAU,iBAAiB;AAAA,UAC1C,eAAe,CAAC,UAAU,SAAS,UAAU,KAAK;AAAA,QACpD;AAAA,MACF;AAAA,IAAA,CACD;AAAA,EACH;AAEA,SAAO,OAAO,YAAY,EAAE,KAAK,IAAI;AACvC;"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const _ = require("lodash/fp");
3
+ const fp = require("lodash/fp");
4
4
  const koaSession = require("koa-session");
5
5
  const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
6
6
  const koaSession__default = /* @__PURE__ */ _interopDefault(koaSession);
@@ -18,7 +18,7 @@ const defaultConfig = {
18
18
  };
19
19
  const session = (userConfig, { strapi }) => {
20
20
  const { keys } = strapi.server.app;
21
- if (!_.isArray(keys) || _.isEmpty(keys) || keys.some(_.isEmpty)) {
21
+ if (!fp.isArray(keys) || fp.isEmpty(keys) || keys.some(fp.isEmpty)) {
22
22
  throw new Error(
23
23
  `App keys are required. Please set app.keys in config/server.js (ex: keys: ['myKeyA', 'myKeyB'])`
24
24
  );
@@ -1 +1 @@
1
- {"version":3,"file":"session.js","sources":["../../src/middlewares/session.ts"],"sourcesContent":["import { isEmpty, isArray } from 'lodash/fp';\nimport koaSession from 'koa-session';\nimport type { Core } from '@strapi/types';\n\nconst defaultConfig = {\n key: 'koa.sess',\n maxAge: 86400000,\n autoCommit: true,\n overwrite: true,\n httpOnly: true,\n signed: true,\n rolling: false,\n renew: false,\n secure: process.env.NODE_ENV === 'production',\n sameSite: undefined,\n};\n\nexport const session: Core.MiddlewareFactory<Partial<koaSession.opts>> = (\n userConfig,\n { strapi }\n) => {\n const { keys } = strapi.server.app;\n if (!isArray(keys) || isEmpty(keys) || keys.some(isEmpty)) {\n throw new Error(\n `App keys are required. Please set app.keys in config/server.js (ex: keys: ['myKeyA', 'myKeyB'])`\n );\n }\n\n const config: Partial<koaSession.opts> = { ...defaultConfig, ...userConfig };\n\n strapi.server.use(koaSession(config, strapi.server.app));\n};\n"],"names":["isArray","isEmpty","koaSession"],"mappings":";;;;;;AAIA,MAAM,gBAAgB;AAAA,EACpB,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,OAAO;AAAA,EACP,QAAQ,QAAQ,IAAI,aAAa;AAAA,EACjC,UAAU;AACZ;AAEO,MAAM,UAA4D,CACvE,YACA,EAAE,aACC;AACH,QAAM,EAAE,KAAS,IAAA,OAAO,OAAO;AAC3B,MAAA,CAACA,EAAAA,QAAQ,IAAI,KAAKC,EAAA,QAAQ,IAAI,KAAK,KAAK,KAAKA,EAAAA,OAAO,GAAG;AACzD,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAAA,EAEJ;AAEA,QAAM,SAAmC,EAAE,GAAG,eAAe,GAAG,WAAW;AAE3E,SAAO,OAAO,IAAIC,oBAAA,QAAW,QAAQ,OAAO,OAAO,GAAG,CAAC;AACzD;;"}
1
+ {"version":3,"file":"session.js","sources":["../../src/middlewares/session.ts"],"sourcesContent":["import { isEmpty, isArray } from 'lodash/fp';\nimport koaSession from 'koa-session';\nimport type { Core } from '@strapi/types';\n\nconst defaultConfig = {\n key: 'koa.sess',\n maxAge: 86400000,\n autoCommit: true,\n overwrite: true,\n httpOnly: true,\n signed: true,\n rolling: false,\n renew: false,\n secure: process.env.NODE_ENV === 'production',\n sameSite: undefined,\n};\n\nexport const session: Core.MiddlewareFactory<Partial<koaSession.opts>> = (\n userConfig,\n { strapi }\n) => {\n const { keys } = strapi.server.app;\n if (!isArray(keys) || isEmpty(keys) || keys.some(isEmpty)) {\n throw new Error(\n `App keys are required. Please set app.keys in config/server.js (ex: keys: ['myKeyA', 'myKeyB'])`\n );\n }\n\n const config: Partial<koaSession.opts> = { ...defaultConfig, ...userConfig };\n\n strapi.server.use(koaSession(config, strapi.server.app));\n};\n"],"names":["isArray","isEmpty","koaSession"],"mappings":";;;;;;AAIA,MAAM,gBAAgB;AAAA,EACpB,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,OAAO;AAAA,EACP,QAAQ,QAAQ,IAAI,aAAa;AAAA,EACjC,UAAU;AACZ;AAEO,MAAM,UAA4D,CACvE,YACA,EAAE,aACC;AACH,QAAM,EAAE,KAAS,IAAA,OAAO,OAAO;AAC3B,MAAA,CAACA,GAAAA,QAAQ,IAAI,KAAKC,GAAA,QAAQ,IAAI,KAAK,KAAK,KAAKA,GAAAA,OAAO,GAAG;AACzD,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAAA,EAEJ;AAEA,QAAM,SAAmC,EAAE,GAAG,eAAe,GAAG,WAAW;AAE3E,SAAO,OAAO,IAAIC,oBAAA,QAAW,QAAQ,OAAO,OAAO,GAAG,CAAC;AACzD;;"}
@@ -1,3 +1,15 @@
1
+ /**
2
+ * This migration is responsible for creating the draft counterpart for all the entries that were in a published state.
3
+ *
4
+ * In v4, entries could either be in a draft or published state, but not both at the same time.
5
+ * In v5, we introduced the concept of document, and an entry can be in a draft or published state.
6
+ *
7
+ * This means the migration needs to create the draft counterpart if an entry was published.
8
+ *
9
+ * This migration performs the following steps:
10
+ * 1. Creates draft entries for all published entries, without it's components, dynamic zones or relations.
11
+ * 2. Using the document service, discard those same drafts to copy its relations.
12
+ */
1
13
  import type { Database, Migration } from '@strapi/database';
2
14
  type DocumentVersion = {
3
15
  documentId: string;
@@ -16,15 +28,6 @@ export declare function getBatchToDiscard({ db, trx, uid, batchSize, }: {
16
28
  uid: string;
17
29
  batchSize?: number;
18
30
  }): AsyncGenerator<DocumentVersion[], void, unknown>;
19
- /**
20
- * On V4 there was no concept of document, and an entry could be in a draft or published state.
21
- * But not both at the same time.
22
- *
23
- * On V5 we introduced the concept of document, and an entry can be in a draft or published state,
24
- * with the requirement that a document must always have a draft.
25
- *
26
- * This migration creates the document draft counterpart for all the entries that were in a published state.
27
- */
28
31
  export declare const discardDocumentDrafts: Migration;
29
32
  export {};
30
33
  //# sourceMappingURL=5.0.0-discard-drafts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"5.0.0-discard-drafts.d.ts","sourceRoot":"","sources":["../../../src/migrations/database/5.0.0-discard-drafts.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAG5D,KAAK,eAAe,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAC9D,KAAK,IAAI,GAAG,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAE3C;;;;;GAKG;AACH,wBAAuB,iBAAiB,CAAC,EACvC,EAAE,EACF,GAAG,EACH,GAAG,EACH,SAAgB,GACjB,EAAE;IACD,EAAE,EAAE,QAAQ,CAAC;IACb,GAAG,EAAE,IAAI,CAAC;IACV,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,oDAuBA;AAiCD;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,EAAE,SASnC,CAAC"}
1
+ {"version":3,"file":"5.0.0-discard-drafts.d.ts","sourceRoot":"","sources":["../../../src/migrations/database/5.0.0-discard-drafts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAG5D,KAAK,eAAe,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAC9D,KAAK,IAAI,GAAG,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAgF3C;;;;;GAKG;AACH,wBAAuB,iBAAiB,CAAC,EACvC,EAAE,EACF,GAAG,EACH,GAAG,EACH,SAAgB,GACjB,EAAE;IACD,EAAE,EAAE,QAAQ,CAAC;IACb,GAAG,EAAE,IAAI,CAAC;IACV,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,oDAuBA;AAwCD,eAAO,MAAM,qBAAqB,EAAE,SAQnC,CAAC"}
@@ -1,6 +1,45 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const strapiUtils = require("@strapi/utils");
4
+ const hasDraftAndPublish = async (trx, meta) => {
5
+ const hasTable = await trx.schema.hasTable(meta.tableName);
6
+ if (!hasTable) {
7
+ return false;
8
+ }
9
+ const uid = meta.uid;
10
+ const model = strapi.getModel(uid);
11
+ const hasDP = strapiUtils.contentTypes.hasDraftAndPublish(model);
12
+ if (!hasDP) {
13
+ return false;
14
+ }
15
+ return true;
16
+ };
17
+ async function copyPublishedEntriesToDraft({
18
+ db,
19
+ trx,
20
+ uid
21
+ }) {
22
+ const meta = db.metadata.get(uid);
23
+ const scalarAttributes = Object.values(meta.attributes).reduce((acc, attribute) => {
24
+ if (["id"].includes(attribute.columnName)) {
25
+ return acc;
26
+ }
27
+ if (strapiUtils.contentTypes.isScalarAttribute(attribute)) {
28
+ acc.push(attribute.columnName);
29
+ }
30
+ return acc;
31
+ }, []);
32
+ await trx.into(trx.raw(`${meta.tableName} (${scalarAttributes.join(", ")})`)).insert((subQb) => {
33
+ subQb.select(
34
+ ...scalarAttributes.map((att) => {
35
+ if (att === "published_at") {
36
+ return trx.raw("NULL as published_at");
37
+ }
38
+ return att;
39
+ })
40
+ ).from(meta.tableName).whereNotNull("published_at");
41
+ });
42
+ }
4
43
  async function* getBatchToDiscard({
5
44
  db,
6
45
  trx,
@@ -19,19 +58,19 @@ async function* getBatchToDiscard({
19
58
  }
20
59
  }
21
60
  const migrateUp = async (trx, db) => {
61
+ const dpModels = [];
22
62
  for (const meta of db.metadata.values()) {
23
- const hasTable = await trx.schema.hasTable(meta.tableName);
24
- if (!hasTable) {
25
- continue;
63
+ const hasDP = await hasDraftAndPublish(trx, meta);
64
+ if (hasDP) {
65
+ dpModels.push(meta);
26
66
  }
27
- const uid = meta.uid;
28
- const model = strapi.getModel(uid);
29
- const hasDP = strapiUtils.contentTypes.hasDraftAndPublish(model);
30
- if (!hasDP) {
31
- continue;
32
- }
33
- const discardDraft = async (entry) => strapi.documents(uid).discardDraft({ documentId: entry.documentId, locale: entry.locale });
34
- for await (const batch of getBatchToDiscard({ db, trx, uid: meta.uid })) {
67
+ }
68
+ for (const model of dpModels) {
69
+ await copyPublishedEntriesToDraft({ db, trx, uid: model.uid });
70
+ }
71
+ for (const model of dpModels) {
72
+ const discardDraft = async (entry) => strapi.documents(model.uid).discardDraft({ documentId: entry.documentId, locale: entry.locale });
73
+ for await (const batch of getBatchToDiscard({ db, trx, uid: model.uid })) {
35
74
  await strapiUtils.async.map(batch, discardDraft, { concurrency: 10 });
36
75
  }
37
76
  }
@@ -1 +1 @@
1
- {"version":3,"file":"5.0.0-discard-drafts.js","sources":["../../../src/migrations/database/5.0.0-discard-drafts.ts"],"sourcesContent":["/* eslint-disable no-continue */\nimport type { UID } from '@strapi/types';\nimport type { Database, Migration } from '@strapi/database';\nimport { async, contentTypes } from '@strapi/utils';\n\ntype DocumentVersion = { documentId: string; locale: string };\ntype Knex = Parameters<Migration['up']>[0];\n\n/**\n * Load a batch of versions to discard.\n *\n * Versions with only a draft version will be ignored.\n * Only versions with a published version (which always have a draft version) will be discarded.\n */\nexport async function* getBatchToDiscard({\n db,\n trx,\n uid,\n batchSize = 1000,\n}: {\n db: Database;\n trx: Knex;\n uid: string;\n batchSize?: number;\n}) {\n let offset = 0;\n let hasMore = true;\n\n while (hasMore) {\n // Look for the published entries to discard\n const batch: DocumentVersion[] = await db\n .queryBuilder(uid)\n .select(['id', 'documentId', 'locale'])\n .where({ publishedAt: { $ne: null } })\n .limit(batchSize)\n .offset(offset)\n .orderBy('id')\n .transacting(trx)\n .execute();\n\n if (batch.length < batchSize) {\n hasMore = false;\n }\n\n offset += batchSize;\n yield batch;\n }\n}\n\nconst migrateUp = async (trx: Knex, db: Database) => {\n for (const meta of db.metadata.values()) {\n const hasTable = await trx.schema.hasTable(meta.tableName);\n\n if (!hasTable) {\n continue;\n }\n\n const uid = meta.uid as UID.ContentType;\n const model = strapi.getModel(uid);\n const hasDP = contentTypes.hasDraftAndPublish(model);\n if (!hasDP) {\n continue;\n }\n\n const discardDraft = async (entry: DocumentVersion) =>\n strapi\n .documents(uid)\n // Discard draft by referencing the documentId and locale\n .discardDraft({ documentId: entry.documentId, locale: entry.locale });\n\n /**\n * Load a batch of entries (batched to prevent loading millions of rows at once ),\n * and discard them using the document service.\n */\n for await (const batch of getBatchToDiscard({ db, trx, uid: meta.uid })) {\n await async.map(batch, discardDraft, { concurrency: 10 });\n }\n }\n};\n\n/**\n * On V4 there was no concept of document, and an entry could be in a draft or published state.\n * But not both at the same time.\n *\n * On V5 we introduced the concept of document, and an entry can be in a draft or published state,\n * with the requirement that a document must always have a draft.\n *\n * This migration creates the document draft counterpart for all the entries that were in a published state.\n */\nexport const discardDocumentDrafts: Migration = {\n name: 'core::5.0.0-discard-drafts',\n async up(trx, db) {\n // TODO: Log to inform the user that the migration is running in the background\n await migrateUp(trx, db);\n },\n async down() {\n throw new Error('not implemented');\n },\n};\n"],"names":["contentTypes","async"],"mappings":";;;AAcA,gBAAuB,kBAAkB;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AACd,GAKG;AACD,MAAI,SAAS;AACb,MAAI,UAAU;AAEd,SAAO,SAAS;AAEd,UAAM,QAA2B,MAAM,GACpC,aAAa,GAAG,EAChB,OAAO,CAAC,MAAM,cAAc,QAAQ,CAAC,EACrC,MAAM,EAAE,aAAa,EAAE,KAAK,KAAO,EAAA,CAAC,EACpC,MAAM,SAAS,EACf,OAAO,MAAM,EACb,QAAQ,IAAI,EACZ,YAAY,GAAG,EACf,QAAQ;AAEP,QAAA,MAAM,SAAS,WAAW;AAClB,gBAAA;AAAA,IACZ;AAEU,cAAA;AACJ,UAAA;AAAA,EACR;AACF;AAEA,MAAM,YAAY,OAAO,KAAW,OAAiB;AACnD,aAAW,QAAQ,GAAG,SAAS,OAAA,GAAU;AACvC,UAAM,WAAW,MAAM,IAAI,OAAO,SAAS,KAAK,SAAS;AAEzD,QAAI,CAAC,UAAU;AACb;AAAA,IACF;AAEA,UAAM,MAAM,KAAK;AACX,UAAA,QAAQ,OAAO,SAAS,GAAG;AAC3B,UAAA,QAAQA,YAAAA,aAAa,mBAAmB,KAAK;AACnD,QAAI,CAAC,OAAO;AACV;AAAA,IACF;AAEA,UAAM,eAAe,OAAO,UAC1B,OACG,UAAU,GAAG,EAEb,aAAa,EAAE,YAAY,MAAM,YAAY,QAAQ,MAAM,QAAQ;AAMvD,qBAAA,SAAS,kBAAkB,EAAE,IAAI,KAAK,KAAK,KAAK,IAAI,CAAC,GAAG;AACvE,YAAMC,YAAAA,MAAM,IAAI,OAAO,cAAc,EAAE,aAAa,IAAI;AAAA,IAC1D;AAAA,EACF;AACF;AAWO,MAAM,wBAAmC;AAAA,EAC9C,MAAM;AAAA,EACN,MAAM,GAAG,KAAK,IAAI;AAEV,UAAA,UAAU,KAAK,EAAE;AAAA,EACzB;AAAA,EACA,MAAM,OAAO;AACL,UAAA,IAAI,MAAM,iBAAiB;AAAA,EACnC;AACF;;;"}
1
+ {"version":3,"file":"5.0.0-discard-drafts.js","sources":["../../../src/migrations/database/5.0.0-discard-drafts.ts"],"sourcesContent":["/**\n * This migration is responsible for creating the draft counterpart for all the entries that were in a published state.\n *\n * In v4, entries could either be in a draft or published state, but not both at the same time.\n * In v5, we introduced the concept of document, and an entry can be in a draft or published state.\n *\n * This means the migration needs to create the draft counterpart if an entry was published.\n *\n * This migration performs the following steps:\n * 1. Creates draft entries for all published entries, without it's components, dynamic zones or relations.\n * 2. Using the document service, discard those same drafts to copy its relations.\n */\n\n/* eslint-disable no-continue */\nimport type { UID } from '@strapi/types';\nimport type { Database, Migration } from '@strapi/database';\nimport { async, contentTypes } from '@strapi/utils';\n\ntype DocumentVersion = { documentId: string; locale: string };\ntype Knex = Parameters<Migration['up']>[0];\n\n/**\n * Check if the model has draft and publish enabled.\n */\nconst hasDraftAndPublish = async (trx: Knex, meta: any) => {\n const hasTable = await trx.schema.hasTable(meta.tableName);\n\n if (!hasTable) {\n return false;\n }\n\n const uid = meta.uid as UID.ContentType;\n const model = strapi.getModel(uid);\n const hasDP = contentTypes.hasDraftAndPublish(model);\n if (!hasDP) {\n return false;\n }\n\n return true;\n};\n\n/**\n * Copy all the published entries to draft entries, without it's components, dynamic zones or relations.\n * This ensures all necessary draft's exist before copying it's relations.\n */\nasync function copyPublishedEntriesToDraft({\n db,\n trx,\n uid,\n}: {\n db: Database;\n trx: Knex;\n uid: string;\n}) {\n // Extract all scalar attributes to use in the insert query\n const meta = db.metadata.get(uid);\n\n // Get scalar attributes that will be copied over the new draft\n const scalarAttributes = Object.values(meta.attributes).reduce((acc, attribute: any) => {\n if (['id'].includes(attribute.columnName)) {\n return acc;\n }\n\n if (contentTypes.isScalarAttribute(attribute)) {\n acc.push(attribute.columnName);\n }\n\n return acc;\n }, [] as string[]);\n\n /**\n * Query to copy the published entries into draft entries.\n *\n * INSERT INTO tableName (columnName1, columnName2, columnName3, ...)\n * SELECT columnName1, columnName2, columnName3, ...\n * FROM tableName\n */\n await trx\n // INSERT INTO tableName (columnName1, columnName2, columnName3, ...)\n .into(trx.raw(`${meta.tableName} (${scalarAttributes.join(', ')})`))\n .insert((subQb: typeof trx) => {\n // SELECT columnName1, columnName2, columnName3, ...\n subQb\n .select(\n ...scalarAttributes.map((att: string) => {\n // Override 'publishedAt' and 'updatedAt' attributes\n if (att === 'published_at') {\n return trx.raw('NULL as published_at');\n }\n\n return att;\n })\n )\n .from(meta.tableName)\n // Only select entries that were published\n .whereNotNull('published_at');\n });\n}\n\n/**\n * Load a batch of versions to discard.\n *\n * Versions with only a draft version will be ignored.\n * Only versions with a published version (which always have a draft version) will be discarded.\n */\nexport async function* getBatchToDiscard({\n db,\n trx,\n uid,\n batchSize = 1000,\n}: {\n db: Database;\n trx: Knex;\n uid: string;\n batchSize?: number;\n}) {\n let offset = 0;\n let hasMore = true;\n\n while (hasMore) {\n // Look for the published entries to discard\n const batch: DocumentVersion[] = await db\n .queryBuilder(uid)\n .select(['id', 'documentId', 'locale'])\n .where({ publishedAt: { $ne: null } })\n .limit(batchSize)\n .offset(offset)\n .orderBy('id')\n .transacting(trx)\n .execute();\n\n if (batch.length < batchSize) {\n hasMore = false;\n }\n\n offset += batchSize;\n yield batch;\n }\n}\n\n/**\n * 2 pass migration to create the draft entries for all the published entries.\n * And then discard the drafts to copy the relations.\n */\nconst migrateUp = async (trx: Knex, db: Database) => {\n const dpModels = [];\n for (const meta of db.metadata.values()) {\n const hasDP = await hasDraftAndPublish(trx, meta);\n if (hasDP) {\n dpModels.push(meta);\n }\n }\n\n /**\n * Create plain draft entries for all the entries that were published.\n */\n for (const model of dpModels) {\n await copyPublishedEntriesToDraft({ db, trx, uid: model.uid });\n }\n\n /**\n * Discard the drafts will copy the relations from the published entries to the newly created drafts.\n *\n * Load a batch of entries (batched to prevent loading millions of rows at once ),\n * and discard them using the document service.\n */\n for (const model of dpModels) {\n const discardDraft = async (entry: DocumentVersion) =>\n strapi\n .documents(model.uid as UID.ContentType)\n .discardDraft({ documentId: entry.documentId, locale: entry.locale });\n\n for await (const batch of getBatchToDiscard({ db, trx, uid: model.uid })) {\n await async.map(batch, discardDraft, { concurrency: 10 });\n }\n }\n};\n\nexport const discardDocumentDrafts: Migration = {\n name: 'core::5.0.0-discard-drafts',\n async up(trx, db) {\n await migrateUp(trx, db);\n },\n async down() {\n throw new Error('not implemented');\n },\n};\n"],"names":["contentTypes","async"],"mappings":";;;AAwBA,MAAM,qBAAqB,OAAO,KAAW,SAAc;AACzD,QAAM,WAAW,MAAM,IAAI,OAAO,SAAS,KAAK,SAAS;AAEzD,MAAI,CAAC,UAAU;AACN,WAAA;AAAA,EACT;AAEA,QAAM,MAAM,KAAK;AACX,QAAA,QAAQ,OAAO,SAAS,GAAG;AAC3B,QAAA,QAAQA,YAAAA,aAAa,mBAAmB,KAAK;AACnD,MAAI,CAAC,OAAO;AACH,WAAA;AAAA,EACT;AAEO,SAAA;AACT;AAMA,eAAe,4BAA4B;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AACF,GAIG;AAED,QAAM,OAAO,GAAG,SAAS,IAAI,GAAG;AAG1B,QAAA,mBAAmB,OAAO,OAAO,KAAK,UAAU,EAAE,OAAO,CAAC,KAAK,cAAmB;AACtF,QAAI,CAAC,IAAI,EAAE,SAAS,UAAU,UAAU,GAAG;AAClC,aAAA;AAAA,IACT;AAEI,QAAAA,YAAA,aAAa,kBAAkB,SAAS,GAAG;AACzC,UAAA,KAAK,UAAU,UAAU;AAAA,IAC/B;AAEO,WAAA;AAAA,EACT,GAAG,CAAc,CAAA;AASjB,QAAM,IAEH,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS,KAAK,iBAAiB,KAAK,IAAI,CAAC,GAAG,CAAC,EAClE,OAAO,CAAC,UAAsB;AAG1B,UAAA;AAAA,MACC,GAAG,iBAAiB,IAAI,CAAC,QAAgB;AAEvC,YAAI,QAAQ,gBAAgB;AACnB,iBAAA,IAAI,IAAI,sBAAsB;AAAA,QACvC;AAEO,eAAA;AAAA,MAAA,CACR;AAAA,IAAA,EAEF,KAAK,KAAK,SAAS,EAEnB,aAAa,cAAc;AAAA,EAAA,CAC/B;AACL;AAQA,gBAAuB,kBAAkB;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AACd,GAKG;AACD,MAAI,SAAS;AACb,MAAI,UAAU;AAEd,SAAO,SAAS;AAEd,UAAM,QAA2B,MAAM,GACpC,aAAa,GAAG,EAChB,OAAO,CAAC,MAAM,cAAc,QAAQ,CAAC,EACrC,MAAM,EAAE,aAAa,EAAE,KAAK,KAAO,EAAA,CAAC,EACpC,MAAM,SAAS,EACf,OAAO,MAAM,EACb,QAAQ,IAAI,EACZ,YAAY,GAAG,EACf,QAAQ;AAEP,QAAA,MAAM,SAAS,WAAW;AAClB,gBAAA;AAAA,IACZ;AAEU,cAAA;AACJ,UAAA;AAAA,EACR;AACF;AAMA,MAAM,YAAY,OAAO,KAAW,OAAiB;AACnD,QAAM,WAAW,CAAA;AACjB,aAAW,QAAQ,GAAG,SAAS,OAAA,GAAU;AACvC,UAAM,QAAQ,MAAM,mBAAmB,KAAK,IAAI;AAChD,QAAI,OAAO;AACT,eAAS,KAAK,IAAI;AAAA,IACpB;AAAA,EACF;AAKA,aAAW,SAAS,UAAU;AAC5B,UAAM,4BAA4B,EAAE,IAAI,KAAK,KAAK,MAAM,KAAK;AAAA,EAC/D;AAQA,aAAW,SAAS,UAAU;AAC5B,UAAM,eAAe,OAAO,UAC1B,OACG,UAAU,MAAM,GAAsB,EACtC,aAAa,EAAE,YAAY,MAAM,YAAY,QAAQ,MAAM,QAAQ;AAEvD,qBAAA,SAAS,kBAAkB,EAAE,IAAI,KAAK,KAAK,MAAM,IAAI,CAAC,GAAG;AACxE,YAAMC,YAAAA,MAAM,IAAI,OAAO,cAAc,EAAE,aAAa,IAAI;AAAA,IAC1D;AAAA,EACF;AACF;AAEO,MAAM,wBAAmC;AAAA,EAC9C,MAAM;AAAA,EACN,MAAM,GAAG,KAAK,IAAI;AACV,UAAA,UAAU,KAAK,EAAE;AAAA,EACzB;AAAA,EACA,MAAM,OAAO;AACL,UAAA,IAAI,MAAM,iBAAiB;AAAA,EACnC;AACF;;;"}
@@ -1,4 +1,43 @@
1
- import { contentTypes, async } from "@strapi/utils";
1
+ import { async, contentTypes } from "@strapi/utils";
2
+ const hasDraftAndPublish = async (trx, meta) => {
3
+ const hasTable = await trx.schema.hasTable(meta.tableName);
4
+ if (!hasTable) {
5
+ return false;
6
+ }
7
+ const uid = meta.uid;
8
+ const model = strapi.getModel(uid);
9
+ const hasDP = contentTypes.hasDraftAndPublish(model);
10
+ if (!hasDP) {
11
+ return false;
12
+ }
13
+ return true;
14
+ };
15
+ async function copyPublishedEntriesToDraft({
16
+ db,
17
+ trx,
18
+ uid
19
+ }) {
20
+ const meta = db.metadata.get(uid);
21
+ const scalarAttributes = Object.values(meta.attributes).reduce((acc, attribute) => {
22
+ if (["id"].includes(attribute.columnName)) {
23
+ return acc;
24
+ }
25
+ if (contentTypes.isScalarAttribute(attribute)) {
26
+ acc.push(attribute.columnName);
27
+ }
28
+ return acc;
29
+ }, []);
30
+ await trx.into(trx.raw(`${meta.tableName} (${scalarAttributes.join(", ")})`)).insert((subQb) => {
31
+ subQb.select(
32
+ ...scalarAttributes.map((att) => {
33
+ if (att === "published_at") {
34
+ return trx.raw("NULL as published_at");
35
+ }
36
+ return att;
37
+ })
38
+ ).from(meta.tableName).whereNotNull("published_at");
39
+ });
40
+ }
2
41
  async function* getBatchToDiscard({
3
42
  db,
4
43
  trx,
@@ -17,19 +56,19 @@ async function* getBatchToDiscard({
17
56
  }
18
57
  }
19
58
  const migrateUp = async (trx, db) => {
59
+ const dpModels = [];
20
60
  for (const meta of db.metadata.values()) {
21
- const hasTable = await trx.schema.hasTable(meta.tableName);
22
- if (!hasTable) {
23
- continue;
61
+ const hasDP = await hasDraftAndPublish(trx, meta);
62
+ if (hasDP) {
63
+ dpModels.push(meta);
24
64
  }
25
- const uid = meta.uid;
26
- const model = strapi.getModel(uid);
27
- const hasDP = contentTypes.hasDraftAndPublish(model);
28
- if (!hasDP) {
29
- continue;
30
- }
31
- const discardDraft = async (entry) => strapi.documents(uid).discardDraft({ documentId: entry.documentId, locale: entry.locale });
32
- for await (const batch of getBatchToDiscard({ db, trx, uid: meta.uid })) {
65
+ }
66
+ for (const model of dpModels) {
67
+ await copyPublishedEntriesToDraft({ db, trx, uid: model.uid });
68
+ }
69
+ for (const model of dpModels) {
70
+ const discardDraft = async (entry) => strapi.documents(model.uid).discardDraft({ documentId: entry.documentId, locale: entry.locale });
71
+ for await (const batch of getBatchToDiscard({ db, trx, uid: model.uid })) {
33
72
  await async.map(batch, discardDraft, { concurrency: 10 });
34
73
  }
35
74
  }
@@ -1 +1 @@
1
- {"version":3,"file":"5.0.0-discard-drafts.mjs","sources":["../../../src/migrations/database/5.0.0-discard-drafts.ts"],"sourcesContent":["/* eslint-disable no-continue */\nimport type { UID } from '@strapi/types';\nimport type { Database, Migration } from '@strapi/database';\nimport { async, contentTypes } from '@strapi/utils';\n\ntype DocumentVersion = { documentId: string; locale: string };\ntype Knex = Parameters<Migration['up']>[0];\n\n/**\n * Load a batch of versions to discard.\n *\n * Versions with only a draft version will be ignored.\n * Only versions with a published version (which always have a draft version) will be discarded.\n */\nexport async function* getBatchToDiscard({\n db,\n trx,\n uid,\n batchSize = 1000,\n}: {\n db: Database;\n trx: Knex;\n uid: string;\n batchSize?: number;\n}) {\n let offset = 0;\n let hasMore = true;\n\n while (hasMore) {\n // Look for the published entries to discard\n const batch: DocumentVersion[] = await db\n .queryBuilder(uid)\n .select(['id', 'documentId', 'locale'])\n .where({ publishedAt: { $ne: null } })\n .limit(batchSize)\n .offset(offset)\n .orderBy('id')\n .transacting(trx)\n .execute();\n\n if (batch.length < batchSize) {\n hasMore = false;\n }\n\n offset += batchSize;\n yield batch;\n }\n}\n\nconst migrateUp = async (trx: Knex, db: Database) => {\n for (const meta of db.metadata.values()) {\n const hasTable = await trx.schema.hasTable(meta.tableName);\n\n if (!hasTable) {\n continue;\n }\n\n const uid = meta.uid as UID.ContentType;\n const model = strapi.getModel(uid);\n const hasDP = contentTypes.hasDraftAndPublish(model);\n if (!hasDP) {\n continue;\n }\n\n const discardDraft = async (entry: DocumentVersion) =>\n strapi\n .documents(uid)\n // Discard draft by referencing the documentId and locale\n .discardDraft({ documentId: entry.documentId, locale: entry.locale });\n\n /**\n * Load a batch of entries (batched to prevent loading millions of rows at once ),\n * and discard them using the document service.\n */\n for await (const batch of getBatchToDiscard({ db, trx, uid: meta.uid })) {\n await async.map(batch, discardDraft, { concurrency: 10 });\n }\n }\n};\n\n/**\n * On V4 there was no concept of document, and an entry could be in a draft or published state.\n * But not both at the same time.\n *\n * On V5 we introduced the concept of document, and an entry can be in a draft or published state,\n * with the requirement that a document must always have a draft.\n *\n * This migration creates the document draft counterpart for all the entries that were in a published state.\n */\nexport const discardDocumentDrafts: Migration = {\n name: 'core::5.0.0-discard-drafts',\n async up(trx, db) {\n // TODO: Log to inform the user that the migration is running in the background\n await migrateUp(trx, db);\n },\n async down() {\n throw new Error('not implemented');\n },\n};\n"],"names":[],"mappings":";AAcA,gBAAuB,kBAAkB;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AACd,GAKG;AACD,MAAI,SAAS;AACb,MAAI,UAAU;AAEd,SAAO,SAAS;AAEd,UAAM,QAA2B,MAAM,GACpC,aAAa,GAAG,EAChB,OAAO,CAAC,MAAM,cAAc,QAAQ,CAAC,EACrC,MAAM,EAAE,aAAa,EAAE,KAAK,KAAO,EAAA,CAAC,EACpC,MAAM,SAAS,EACf,OAAO,MAAM,EACb,QAAQ,IAAI,EACZ,YAAY,GAAG,EACf,QAAQ;AAEP,QAAA,MAAM,SAAS,WAAW;AAClB,gBAAA;AAAA,IACZ;AAEU,cAAA;AACJ,UAAA;AAAA,EACR;AACF;AAEA,MAAM,YAAY,OAAO,KAAW,OAAiB;AACnD,aAAW,QAAQ,GAAG,SAAS,OAAA,GAAU;AACvC,UAAM,WAAW,MAAM,IAAI,OAAO,SAAS,KAAK,SAAS;AAEzD,QAAI,CAAC,UAAU;AACb;AAAA,IACF;AAEA,UAAM,MAAM,KAAK;AACX,UAAA,QAAQ,OAAO,SAAS,GAAG;AAC3B,UAAA,QAAQ,aAAa,mBAAmB,KAAK;AACnD,QAAI,CAAC,OAAO;AACV;AAAA,IACF;AAEA,UAAM,eAAe,OAAO,UAC1B,OACG,UAAU,GAAG,EAEb,aAAa,EAAE,YAAY,MAAM,YAAY,QAAQ,MAAM,QAAQ;AAMvD,qBAAA,SAAS,kBAAkB,EAAE,IAAI,KAAK,KAAK,KAAK,IAAI,CAAC,GAAG;AACvE,YAAM,MAAM,IAAI,OAAO,cAAc,EAAE,aAAa,IAAI;AAAA,IAC1D;AAAA,EACF;AACF;AAWO,MAAM,wBAAmC;AAAA,EAC9C,MAAM;AAAA,EACN,MAAM,GAAG,KAAK,IAAI;AAEV,UAAA,UAAU,KAAK,EAAE;AAAA,EACzB;AAAA,EACA,MAAM,OAAO;AACL,UAAA,IAAI,MAAM,iBAAiB;AAAA,EACnC;AACF;"}
1
+ {"version":3,"file":"5.0.0-discard-drafts.mjs","sources":["../../../src/migrations/database/5.0.0-discard-drafts.ts"],"sourcesContent":["/**\n * This migration is responsible for creating the draft counterpart for all the entries that were in a published state.\n *\n * In v4, entries could either be in a draft or published state, but not both at the same time.\n * In v5, we introduced the concept of document, and an entry can be in a draft or published state.\n *\n * This means the migration needs to create the draft counterpart if an entry was published.\n *\n * This migration performs the following steps:\n * 1. Creates draft entries for all published entries, without it's components, dynamic zones or relations.\n * 2. Using the document service, discard those same drafts to copy its relations.\n */\n\n/* eslint-disable no-continue */\nimport type { UID } from '@strapi/types';\nimport type { Database, Migration } from '@strapi/database';\nimport { async, contentTypes } from '@strapi/utils';\n\ntype DocumentVersion = { documentId: string; locale: string };\ntype Knex = Parameters<Migration['up']>[0];\n\n/**\n * Check if the model has draft and publish enabled.\n */\nconst hasDraftAndPublish = async (trx: Knex, meta: any) => {\n const hasTable = await trx.schema.hasTable(meta.tableName);\n\n if (!hasTable) {\n return false;\n }\n\n const uid = meta.uid as UID.ContentType;\n const model = strapi.getModel(uid);\n const hasDP = contentTypes.hasDraftAndPublish(model);\n if (!hasDP) {\n return false;\n }\n\n return true;\n};\n\n/**\n * Copy all the published entries to draft entries, without it's components, dynamic zones or relations.\n * This ensures all necessary draft's exist before copying it's relations.\n */\nasync function copyPublishedEntriesToDraft({\n db,\n trx,\n uid,\n}: {\n db: Database;\n trx: Knex;\n uid: string;\n}) {\n // Extract all scalar attributes to use in the insert query\n const meta = db.metadata.get(uid);\n\n // Get scalar attributes that will be copied over the new draft\n const scalarAttributes = Object.values(meta.attributes).reduce((acc, attribute: any) => {\n if (['id'].includes(attribute.columnName)) {\n return acc;\n }\n\n if (contentTypes.isScalarAttribute(attribute)) {\n acc.push(attribute.columnName);\n }\n\n return acc;\n }, [] as string[]);\n\n /**\n * Query to copy the published entries into draft entries.\n *\n * INSERT INTO tableName (columnName1, columnName2, columnName3, ...)\n * SELECT columnName1, columnName2, columnName3, ...\n * FROM tableName\n */\n await trx\n // INSERT INTO tableName (columnName1, columnName2, columnName3, ...)\n .into(trx.raw(`${meta.tableName} (${scalarAttributes.join(', ')})`))\n .insert((subQb: typeof trx) => {\n // SELECT columnName1, columnName2, columnName3, ...\n subQb\n .select(\n ...scalarAttributes.map((att: string) => {\n // Override 'publishedAt' and 'updatedAt' attributes\n if (att === 'published_at') {\n return trx.raw('NULL as published_at');\n }\n\n return att;\n })\n )\n .from(meta.tableName)\n // Only select entries that were published\n .whereNotNull('published_at');\n });\n}\n\n/**\n * Load a batch of versions to discard.\n *\n * Versions with only a draft version will be ignored.\n * Only versions with a published version (which always have a draft version) will be discarded.\n */\nexport async function* getBatchToDiscard({\n db,\n trx,\n uid,\n batchSize = 1000,\n}: {\n db: Database;\n trx: Knex;\n uid: string;\n batchSize?: number;\n}) {\n let offset = 0;\n let hasMore = true;\n\n while (hasMore) {\n // Look for the published entries to discard\n const batch: DocumentVersion[] = await db\n .queryBuilder(uid)\n .select(['id', 'documentId', 'locale'])\n .where({ publishedAt: { $ne: null } })\n .limit(batchSize)\n .offset(offset)\n .orderBy('id')\n .transacting(trx)\n .execute();\n\n if (batch.length < batchSize) {\n hasMore = false;\n }\n\n offset += batchSize;\n yield batch;\n }\n}\n\n/**\n * 2 pass migration to create the draft entries for all the published entries.\n * And then discard the drafts to copy the relations.\n */\nconst migrateUp = async (trx: Knex, db: Database) => {\n const dpModels = [];\n for (const meta of db.metadata.values()) {\n const hasDP = await hasDraftAndPublish(trx, meta);\n if (hasDP) {\n dpModels.push(meta);\n }\n }\n\n /**\n * Create plain draft entries for all the entries that were published.\n */\n for (const model of dpModels) {\n await copyPublishedEntriesToDraft({ db, trx, uid: model.uid });\n }\n\n /**\n * Discard the drafts will copy the relations from the published entries to the newly created drafts.\n *\n * Load a batch of entries (batched to prevent loading millions of rows at once ),\n * and discard them using the document service.\n */\n for (const model of dpModels) {\n const discardDraft = async (entry: DocumentVersion) =>\n strapi\n .documents(model.uid as UID.ContentType)\n .discardDraft({ documentId: entry.documentId, locale: entry.locale });\n\n for await (const batch of getBatchToDiscard({ db, trx, uid: model.uid })) {\n await async.map(batch, discardDraft, { concurrency: 10 });\n }\n }\n};\n\nexport const discardDocumentDrafts: Migration = {\n name: 'core::5.0.0-discard-drafts',\n async up(trx, db) {\n await migrateUp(trx, db);\n },\n async down() {\n throw new Error('not implemented');\n },\n};\n"],"names":[],"mappings":";AAwBA,MAAM,qBAAqB,OAAO,KAAW,SAAc;AACzD,QAAM,WAAW,MAAM,IAAI,OAAO,SAAS,KAAK,SAAS;AAEzD,MAAI,CAAC,UAAU;AACN,WAAA;AAAA,EACT;AAEA,QAAM,MAAM,KAAK;AACX,QAAA,QAAQ,OAAO,SAAS,GAAG;AAC3B,QAAA,QAAQ,aAAa,mBAAmB,KAAK;AACnD,MAAI,CAAC,OAAO;AACH,WAAA;AAAA,EACT;AAEO,SAAA;AACT;AAMA,eAAe,4BAA4B;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AACF,GAIG;AAED,QAAM,OAAO,GAAG,SAAS,IAAI,GAAG;AAG1B,QAAA,mBAAmB,OAAO,OAAO,KAAK,UAAU,EAAE,OAAO,CAAC,KAAK,cAAmB;AACtF,QAAI,CAAC,IAAI,EAAE,SAAS,UAAU,UAAU,GAAG;AAClC,aAAA;AAAA,IACT;AAEI,QAAA,aAAa,kBAAkB,SAAS,GAAG;AACzC,UAAA,KAAK,UAAU,UAAU;AAAA,IAC/B;AAEO,WAAA;AAAA,EACT,GAAG,CAAc,CAAA;AASjB,QAAM,IAEH,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS,KAAK,iBAAiB,KAAK,IAAI,CAAC,GAAG,CAAC,EAClE,OAAO,CAAC,UAAsB;AAG1B,UAAA;AAAA,MACC,GAAG,iBAAiB,IAAI,CAAC,QAAgB;AAEvC,YAAI,QAAQ,gBAAgB;AACnB,iBAAA,IAAI,IAAI,sBAAsB;AAAA,QACvC;AAEO,eAAA;AAAA,MAAA,CACR;AAAA,IAAA,EAEF,KAAK,KAAK,SAAS,EAEnB,aAAa,cAAc;AAAA,EAAA,CAC/B;AACL;AAQA,gBAAuB,kBAAkB;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AACd,GAKG;AACD,MAAI,SAAS;AACb,MAAI,UAAU;AAEd,SAAO,SAAS;AAEd,UAAM,QAA2B,MAAM,GACpC,aAAa,GAAG,EAChB,OAAO,CAAC,MAAM,cAAc,QAAQ,CAAC,EACrC,MAAM,EAAE,aAAa,EAAE,KAAK,KAAO,EAAA,CAAC,EACpC,MAAM,SAAS,EACf,OAAO,MAAM,EACb,QAAQ,IAAI,EACZ,YAAY,GAAG,EACf,QAAQ;AAEP,QAAA,MAAM,SAAS,WAAW;AAClB,gBAAA;AAAA,IACZ;AAEU,cAAA;AACJ,UAAA;AAAA,EACR;AACF;AAMA,MAAM,YAAY,OAAO,KAAW,OAAiB;AACnD,QAAM,WAAW,CAAA;AACjB,aAAW,QAAQ,GAAG,SAAS,OAAA,GAAU;AACvC,UAAM,QAAQ,MAAM,mBAAmB,KAAK,IAAI;AAChD,QAAI,OAAO;AACT,eAAS,KAAK,IAAI;AAAA,IACpB;AAAA,EACF;AAKA,aAAW,SAAS,UAAU;AAC5B,UAAM,4BAA4B,EAAE,IAAI,KAAK,KAAK,MAAM,KAAK;AAAA,EAC/D;AAQA,aAAW,SAAS,UAAU;AAC5B,UAAM,eAAe,OAAO,UAC1B,OACG,UAAU,MAAM,GAAsB,EACtC,aAAa,EAAE,YAAY,MAAM,YAAY,QAAQ,MAAM,QAAQ;AAEvD,qBAAA,SAAS,kBAAkB,EAAE,IAAI,KAAK,KAAK,MAAM,IAAI,CAAC,GAAG;AACxE,YAAM,MAAM,IAAI,OAAO,cAAc,EAAE,aAAa,IAAI;AAAA,IAC1D;AAAA,EACF;AACF;AAEO,MAAM,wBAAmC;AAAA,EAC9C,MAAM;AAAA,EACN,MAAM,GAAG,KAAK,IAAI;AACV,UAAA,UAAU,KAAK,EAAE;AAAA,EACzB;AAAA,EACA,MAAM,OAAO;AACL,UAAA,IAAI,MAAM,iBAAiB;AAAA,EACnC;AACF;"}
@@ -1 +1 @@
1
- {"version":3,"file":"admin.d.ts","sourceRoot":"","sources":["../../src/providers/admin.ts"],"names":[],"mappings":";AAGA,wBAkBG"}
1
+ {"version":3,"file":"admin.d.ts","sourceRoot":"","sources":["../../src/providers/admin.ts"],"names":[],"mappings":";AAGA,wBAmBG"}
@@ -1 +1 @@
1
- {"version":3,"file":"admin.js","sources":["../../src/providers/admin.ts"],"sourcesContent":["import { defineProvider } from './provider';\nimport loadAdmin from '../loaders/admin';\n\nexport default defineProvider({\n init(strapi) {\n strapi.add('admin', () => require('@strapi/admin/strapi-server'));\n },\n\n async register(strapi) {\n await loadAdmin(strapi);\n\n await strapi.get('admin')?.register({ strapi });\n },\n\n async bootstrap(strapi) {\n await strapi.get('admin')?.bootstrap({ strapi });\n },\n\n async destroy(strapi) {\n await strapi.get('admin')?.destroy({ strapi });\n },\n});\n"],"names":["defineProvider","loadAdmin"],"mappings":";;;AAGA,MAAA,QAAeA,wBAAe;AAAA,EAC5B,KAAK,QAAQ;AACX,WAAO,IAAI,SAAS,MAAM,QAAQ,6BAA6B,CAAC;AAAA,EAClE;AAAA,EAEA,MAAM,SAAS,QAAQ;AACrB,UAAMC,QAAU,MAAM;AAEtB,UAAM,OAAO,IAAI,OAAO,GAAG,SAAS,EAAE,QAAQ;AAAA,EAChD;AAAA,EAEA,MAAM,UAAU,QAAQ;AACtB,UAAM,OAAO,IAAI,OAAO,GAAG,UAAU,EAAE,QAAQ;AAAA,EACjD;AAAA,EAEA,MAAM,QAAQ,QAAQ;AACpB,UAAM,OAAO,IAAI,OAAO,GAAG,QAAQ,EAAE,QAAQ;AAAA,EAC/C;AACF,CAAC;;"}
1
+ {"version":3,"file":"admin.js","sources":["../../src/providers/admin.ts"],"sourcesContent":["import { defineProvider } from './provider';\nimport loadAdmin from '../loaders/admin';\n\nexport default defineProvider({\n init(strapi) {\n // eslint-disable-next-line node/no-missing-require\n strapi.add('admin', () => require('@strapi/admin/strapi-server'));\n },\n\n async register(strapi) {\n await loadAdmin(strapi);\n\n await strapi.get('admin')?.register({ strapi });\n },\n\n async bootstrap(strapi) {\n await strapi.get('admin')?.bootstrap({ strapi });\n },\n\n async destroy(strapi) {\n await strapi.get('admin')?.destroy({ strapi });\n },\n});\n"],"names":["defineProvider","loadAdmin"],"mappings":";;;AAGA,MAAA,QAAeA,wBAAe;AAAA,EAC5B,KAAK,QAAQ;AAEX,WAAO,IAAI,SAAS,MAAM,QAAQ,6BAA6B,CAAC;AAAA,EAClE;AAAA,EAEA,MAAM,SAAS,QAAQ;AACrB,UAAMC,QAAU,MAAM;AAEtB,UAAM,OAAO,IAAI,OAAO,GAAG,SAAS,EAAE,QAAQ;AAAA,EAChD;AAAA,EAEA,MAAM,UAAU,QAAQ;AACtB,UAAM,OAAO,IAAI,OAAO,GAAG,UAAU,EAAE,QAAQ;AAAA,EACjD;AAAA,EAEA,MAAM,QAAQ,QAAQ;AACpB,UAAM,OAAO,IAAI,OAAO,GAAG,QAAQ,EAAE,QAAQ;AAAA,EAC/C;AACF,CAAC;;"}