extendSchemaDefinition.ts 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. // Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. import { cloneDeep } from 'lodash-es'
  3. import type {
  4. FormKitExtendableSchemaRoot,
  5. FormKitNode,
  6. FormKitSchemaCondition,
  7. FormKitSchemaNode,
  8. } from '@formkit/core'
  9. import { FormSchemaExtendType } from '#shared/types/form.ts'
  10. import { extend } from '@formkit/utils'
  11. // Can later be switched to in built-in feature from FormKit (when it's available).
  12. const extendSchemaDefinition = (
  13. node: FormKitNode,
  14. sectionKey: string,
  15. schemaExtension: FormKitSchemaCondition | Partial<FormKitSchemaNode>,
  16. extendType: FormSchemaExtendType = FormSchemaExtendType.Merge,
  17. cloneDefinition = false,
  18. // eslint-disable-next-line sonarjs/cognitive-complexity
  19. ) => {
  20. const { props } = node
  21. if (!props.definition) return
  22. const definition = cloneDefinition
  23. ? cloneDeep(props.definition)
  24. : props.definition
  25. const originalSchema = definition.schema as FormKitExtendableSchemaRoot
  26. definition.schema = (extensions) => {
  27. let sectionSchemaExtension:
  28. | FormKitSchemaCondition
  29. | Partial<FormKitSchemaNode>
  30. const currentExtension = extensions[sectionKey] || {}
  31. if (extendType === FormSchemaExtendType.Merge) {
  32. // When current extenstions is a string, replace it.
  33. if (typeof currentExtension === 'string') {
  34. sectionSchemaExtension = schemaExtension
  35. } else {
  36. sectionSchemaExtension = extend(currentExtension, schemaExtension) as
  37. | FormKitSchemaCondition
  38. | Partial<FormKitSchemaNode>
  39. }
  40. } else if (extendType === FormSchemaExtendType.Replace) {
  41. sectionSchemaExtension = schemaExtension
  42. } else {
  43. let currentChildren: Maybe<
  44. (FormKitSchemaCondition | Partial<FormKitSchemaNode>)[]
  45. > = null
  46. if (
  47. currentExtension &&
  48. typeof currentExtension === 'object' &&
  49. 'children' in currentExtension &&
  50. Array.isArray(currentExtension.children)
  51. ) {
  52. currentChildren = currentExtension.children
  53. }
  54. if (currentChildren) {
  55. sectionSchemaExtension = {
  56. children:
  57. extendType === FormSchemaExtendType.Append
  58. ? [...currentChildren, schemaExtension]
  59. : [schemaExtension, ...currentChildren],
  60. } as Partial<FormKitSchemaNode>
  61. } else {
  62. sectionSchemaExtension = {
  63. children: [schemaExtension],
  64. } as Partial<FormKitSchemaNode>
  65. }
  66. }
  67. const localExtensions = {
  68. ...extensions,
  69. [sectionKey]: sectionSchemaExtension,
  70. }
  71. return originalSchema(localExtensions)
  72. }
  73. props.definition = definition
  74. }
  75. export default extendSchemaDefinition