{"version":3,"sources":["../../src/zod/store/form-configuration-store.ts","../../src/zod/hook/use-form-configuration.ts","../../src/zod/component/FormConfigurationZodProvider.tsx","../../src/zod/loader/fetch-form-configurations.ts","../../src/zod/converter/FormConfigurationValidationZodConverter.ts"],"sourcesContent":["/*\n *    Copyright 2022 CROZ d.o.o, the original author or authors.\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n */\n\nimport { create } from \"zustand\";\n\nimport { FormZodConfiguration } from \"../api\";\n\ninterface FormZodConfigurationState {\n\n  /**\n   * Array of current state form configurations.\n   */\n  zodFormConfigurations: FormZodConfiguration[];\n\n  /**\n   * Flag that indicates weather form configuration is fetched from API.\n   */\n  formConfigurationLoaded: boolean;\n\n  /**\n   * Sets form configurations to state.\n   * Use on initial call to find-all endpoint.\n   * @param formConfigurations formConfigurations to set\n   */\n  set: (zodFormConfigurations: FormZodConfiguration[]) => void;\n\n  /**\n   * Adds form configuration to state.\n   * @param formConfiguration formConfiguration to add\n   */\n  add: (zodFormConfiguration: FormZodConfiguration) => void;\n\n  /**\n   * Removes form configuration to state.\n   * @param formConfiguration formConfiguration to add\n   */\n  remove: (zodFormConfiguration: FormZodConfiguration) => void;\n\n  /**\n   * Sets form configuration loaded to state.\n   * @param isLoaded loaded flag to set\n   */\n  setFormConfigurationLoaded: (formConfigurationLoaded: boolean) => void;\n}\n\n/**\n * Creation of the API for managing internal form configuration state.\n * Used internally in the {@link useFormConfiguration} hook.\n *\n * @returns A hook for managing form configuration state usable in a React environment.\n */\nexport const useZodFormConfigurationStore = create<FormZodConfigurationState>((set) => ({\n  zodFormConfigurations: [],\n  formConfigurationLoaded: false,\n  set: ((zodFormConfigurations) => set((state) => ({\n    ...state, zodFormConfigurations,\n  }))),\n  add: (zodFormConfigurations) => set((state) => ({\n    zodFormConfigurations: [...state.zodFormConfigurations, zodFormConfigurations],\n  })),\n  remove: (zodFormConfigurations) => set((state) => ({\n    zodFormConfigurations: state.zodFormConfigurations.filter((c) => c !== zodFormConfigurations),\n  })),\n  setFormConfigurationLoaded: (formConfigurationLoaded) => set({ formConfigurationLoaded }),\n}));\n","/*\n *    Copyright 2022 CROZ d.o.o, the original author or authors.\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n */\n\nimport { z } from \"zod\";\n\nimport { FormZodConfiguration } from \"../api\";\nimport { useZodFormConfigurationStore } from \"../store\";\n\nexport type ZodFormConfigurationOptions = {\n  /**\n   * Array of current state form configurations.\n   */\n  formZodConfigurations: FormZodConfiguration[],\n  /**\n   * Flag that indicates whether form configuration is fetched from API.\n   */\n  formConfigurationLoaded: boolean;\n  /**\n   * Sets form configurations to state.\n   * Use on initial call to find-all endpoint.\n   * @param formConfigurations formConfigurations to set\n   */\n  set: (formConfigurations: FormZodConfiguration[]) => void,\n\n  /**\n   * Adds form configuration to state.\n   * @param formConfiguration formConfiguration to add\n   */\n  add: (formConfiguration: FormZodConfiguration) => void,\n  /**\n   * Removes form configuration to state.\n   * @param formConfiguration formConfiguration to add\n   */\n  remove: (formConfiguration: FormZodConfiguration) => void\n  /**\n   * Sets form configuration loaded to state.\n   * @param isLoaded loaded flag to set\n   */\n  setFormConfigurationLoaded: (formConfigurationLoaded: boolean) => void;\n};\n\nexport type UseZodFormConfiguration = () => ZodFormConfigurationOptions;\n\n/**\n * A hook which simplifies the usage of the form configuration state.\n * Uses the internal {@link useZodFormConfigurationStore} hook for managing the form configuration state.\n *\n * @returns An array of options to access and set the form configuration state and remove or add a single form configuration.\n */\nexport const useZodFormConfigurationState: UseZodFormConfiguration = () => {\n  const formZodConfigurations = useZodFormConfigurationStore((state) => state.zodFormConfigurations);\n  const formConfigurationLoaded = useZodFormConfigurationStore((state) => state.formConfigurationLoaded);\n  const set = useZodFormConfigurationStore((state) => state.set);\n  const add = useZodFormConfigurationStore((state) => state.add);\n  const remove = useZodFormConfigurationStore((state) => state.remove);\n  const setFormConfigurationLoaded = useZodFormConfigurationStore((state) => state.setFormConfigurationLoaded);\n\n  return {\n    formZodConfigurations, formConfigurationLoaded, set, add, remove, setFormConfigurationLoaded,\n  };\n};\n\n/**\n * A hook which extracts a specific Zod configuration from the form configuration identified by the form id.\n * Uses the internal {@link useZodFormConfigurationStore} hook for managing the form configuration state.\n *\n * @param formId Registered form id for a specific form configuration.\n *\n * @returns Mapped Zod configuration from the form configuration identified by the form id, or undefined if no matching form configuration is found.\n */\nexport const useZodFormConfiguration = (formId: string) => {\n  const { formZodConfigurations } = useZodFormConfigurationState();\n\n  const searchedFormConfiguration = formZodConfigurations.find((formZodConfiguration) => formZodConfiguration.formId === formId);\n\n  if (!searchedFormConfiguration) {\n    return undefined;\n  }\n\n  return searchedFormConfiguration.zodSchema as z.ZodObject<any>;\n};\n","/*\n *    Copyright 2022 CROZ d.o.o, the original author or authors.\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n */\n\nimport React, { useEffect } from \"react\";\n\nimport { FormConfigurationConfiguration } from \"../../shared/api\";\nimport { useZodFormConfigurationState } from \"../hook\";\nimport { fetchZodFormConfigurations } from \"../loader\";\n\nexport type ZodProps = {\n\n  /**\n   * Content to show conditionally\n   */\n  children?: React.ReactNode;\n\n  /**\n   * Custom loader to show until content loads\n   */\n  loader?: React.ReactNode;\n} & FormConfigurationConfiguration;\n\n/**\n * Should be used to wrap the whole app that includes forms, so it doesn't render them without loading form configuration from API first.\n * @param children content to show conditionally\n * @param loader custom loader to show until content loads\n */\nexport const FormConfigurationZodProvider = ({ children, loader, ...fetchProps }: ZodProps) => {\n  useEffect(() => {\n    fetchZodFormConfigurations(fetchProps);\n  }, []);\n\n  const { formConfigurationLoaded } = useZodFormConfigurationState();\n\n  return <div>{formConfigurationLoaded ? children : loader ?? null}</div>;\n};\n","/*\n *    Copyright 2022 CROZ d.o.o, the original author or authors.\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n */\n\nimport _uniqBy from \"lodash/uniqBy\";\n\nimport { FormConfiguration, FormConfigurationConfiguration } from \"../../shared/api\";\nimport { FormZodConfiguration } from \"../api\";\nimport { FormConfigurationValidationZodConverter } from \"../converter\";\nimport { useZodFormConfigurationStore } from \"../store\";\n\nconst mergeZodFormConfigurationsWithoutDuplicates = (oldFormConfiguration: FormZodConfiguration[], newFormConfiguration: FormZodConfiguration[]) => {\n  const mergedZodFormConfigurations = [...oldFormConfiguration, ...newFormConfiguration];\n\n  return _uniqBy(mergedZodFormConfigurations, \"formId\");\n};\n\nexport const fetchZodFormConfigurations = async ({ url, requestOptionsResolver, additionalValidatorConverters }: FormConfigurationConfiguration): Promise<FormConfiguration[]> => {\n  const formConfigurationValidationConverter = new FormConfigurationValidationZodConverter(additionalValidatorConverters);\n  const additionalOptions = requestOptionsResolver?.() || {};\n  const finalUrl = url || \"/nrich/form/configuration\";\n\n  const response = await fetch(`${finalUrl}/fetch-all`, {\n    method: \"POST\",\n    ...additionalOptions,\n  });\n  const body = await response.json() as FormConfiguration[];\n\n  const zodFormConfigurations: FormZodConfiguration[] = [];\n\n  // set the response to the form configuration store\n  if (response.ok) {\n    body.forEach((item) => {\n      zodFormConfigurations.push({\n        formId: item.formId,\n        zodSchema: formConfigurationValidationConverter.convertFormConfigurationToZodSchema(item),\n      });\n    });\n    useZodFormConfigurationStore.getState().set(mergeZodFormConfigurationsWithoutDuplicates(useZodFormConfigurationStore.getState().zodFormConfigurations, zodFormConfigurations));\n    useZodFormConfigurationStore.getState().setFormConfigurationLoaded(true);\n  }\n\n  return body;\n};\n","/*\n *    Copyright 2022 CROZ d.o.o, the original author or authors.\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n */\n\nimport { z } from \"zod\";\n\nimport {\n  ConstrainedPropertyClientValidatorConfiguration,\n  ConstrainedPropertyConfiguration,\n  FormConfiguration,\n  ValidatorConverter,\n} from \"../../shared/api\";\n\n/**\n * Converter responsible for conversion between ConstrainedPropertyConfiguration array (that contains validations specified and received from the backend)\n * and Zod's schema that can be applied on the frontend. The list of supported conversions is in given in {@link FormConfigurationValidationZodConverter.DEFAULT_CONVERTER_LIST} but\n * users can also provide their own by using {@link ValidatorConverter} interface and supplying them in the constructor.\n * The last validator converter will match any backend constraint and try to map it directly to Zod.\n */\nexport class FormConfigurationValidationZodConverter {\n  /**\n   * Additional converters that can be registered for unsupported conversion or to change one of the existing conversions (they take precedence to builtin converters).\n   * @private\n   */\n  private readonly additionalConverters: ValidatorConverter[];\n\n  constructor(additionalConverters: ValidatorConverter[] = []) {\n    this.additionalConverters = additionalConverters;\n  }\n\n  /**\n   * Converts {@link FormConfiguration} to Zod's schema using builtin and provided converters.\n   * @param formConfig Form configuration to convert\n   */\n  public convertFormConfigurationToZodSchema(formConfig: FormConfiguration): z.ZodObject<any> {\n    const shape: Record<string, z.ZodTypeAny> = {};\n\n    formConfig.constrainedPropertyConfigurationList.forEach(\n      (property: ConstrainedPropertyConfiguration) => {\n        let fieldSchema = FormConfigurationValidationZodConverter.getBaseSchema(property);\n\n        let isRequired = false;\n        let lastRequiredValidator: ConstrainedPropertyClientValidatorConfiguration | undefined;\n\n        property.validatorList.forEach(\n          (validator: ConstrainedPropertyClientValidatorConfiguration) => {\n            if ([\"NotNull\", \"NotBlank\", \"NotEmpty\"].includes(validator.name)) {\n              isRequired = true;\n              lastRequiredValidator = validator;\n            }\n            fieldSchema = this.applyConverter(validator, fieldSchema);\n          },\n        );\n\n        if (!isRequired) {\n          fieldSchema = fieldSchema.nullish();\n        }\n        else {\n          fieldSchema = fieldSchema\n            .nullable()\n            .or(z.undefined())\n            .refine(\n              (val: any) => val != null,\n              { message: lastRequiredValidator!.errorMessage },\n            );\n        }\n\n        FormConfigurationValidationZodConverter.setNestedField(shape, property.path.split(\".\"), fieldSchema);\n      },\n    );\n\n    return FormConfigurationValidationZodConverter.buildZodObject(shape);\n  }\n\n  /**\n   * Determines the base Zod schema for a constrained property based on\n   * its declared JavaScript type.\n   */\n  private static getBaseSchema(property: ConstrainedPropertyConfiguration): z.ZodTypeAny {\n    switch (property.javascriptType.toLowerCase()) {\n      case \"string\":\n        return z.string();\n      case \"number\":\n        return z.number();\n      case \"boolean\":\n        return z.boolean();\n      case \"object\":\n        return z.record(z.string(), z.any());\n      case \"array\":\n        return z.array(z.any());\n      case \"date\":\n        return z.date();\n      default:\n        return z.unknown();\n    }\n  }\n\n  /**\n   * Assigns a Zod schema to a nested path inside a JS object that represents the shape of the final Zod object.\n   */\n  private static setNestedField(\n    shape: Record<string, any>,\n    path: string[],\n    schema: z.ZodTypeAny,\n  ) {\n    let current = shape;\n\n    for (let i = 0; i < path.length - 1; i += 1) {\n      const key = path[i];\n\n      if (!(key in current)) {\n        current[key] = {};\n      }\n\n      current = current[key];\n    }\n\n    current[path[path.length - 1]] = schema;\n  }\n\n  /**\n   * Recursively converts a nested shape object into a real ZodObject.\n   */\n  private static buildZodObject(\n    shape: Record<string, any>,\n  ): z.ZodObject<any> {\n    const zodShape: Record<string, z.ZodTypeAny> = {};\n\n    Object.entries(shape).forEach(([key, value]) => {\n      if (value instanceof z.ZodType) {\n        zodShape[key] = value;\n      }\n      else {\n        zodShape[key] = FormConfigurationValidationZodConverter.buildZodObject(value);\n      }\n    });\n\n    return z.object(zodShape);\n  }\n\n  private applyConverter(\n    config: ConstrainedPropertyClientValidatorConfiguration,\n    schema: z.ZodTypeAny,\n  ): z.ZodTypeAny {\n    const converter = this.resolveConverter(config);\n    if (converter) {\n      try {\n        return converter.convert(config, schema) as z.ZodTypeAny;\n      }\n      catch {\n        // constraint is not registered so skip evaluation\n      }\n    }\n    return schema;\n  }\n\n  private resolveConverter(\n    config: ConstrainedPropertyClientValidatorConfiguration,\n  ): ValidatorConverter | undefined {\n    const allConverters = this.additionalConverters.concat(FormConfigurationValidationZodConverter.DEFAULT_CONVERTERS_LIST);\n    return allConverters.find((additionalConverter) => additionalConverter.supports(config));\n  }\n\n  private static readonly DEFAULT_CONVERTERS_LIST: ValidatorConverter[] = [\n    {\n      supports: (configuration) => [\"NotNull\", \"NotBlank\", \"NotEmpty\"].includes(configuration.name),\n      convert: (configuration, schema: any) => {\n        if (configuration.name === \"NotBlank\" && schema instanceof z.ZodString) {\n          return schema.refine(\n            (val: any) => val == null || (typeof val === \"string\" && val.trim().length > 0),\n            { message: configuration.errorMessage },\n          );\n        }\n        if (configuration.name === \"NotEmpty\") {\n          if (schema instanceof z.ZodString) {\n            return schema.refine(\n              (val: any) => val == null || (typeof val === \"string\" && val.length > 0),\n              { message: configuration.errorMessage },\n            );\n          }\n          if (schema instanceof z.ZodArray) {\n            return schema.refine(\n              (val: any) => val == null || val.length > 0,\n              { message: configuration.errorMessage },\n            );\n          }\n        }\n        // NotNull - no additional check needed, handled at the end\n        return schema;\n      },\n    },\n    {\n      supports: (configuration) => [\"Size\", \"Length\"].includes(configuration.name),\n      convert: (configuration, schema: any) => {\n        if (schema instanceof z.ZodString || schema instanceof z.ZodArray) {\n          let s = schema;\n          if (configuration.argumentMap.min != null) s = s.min(configuration.argumentMap.min as number, { message: configuration.errorMessage });\n          if (configuration.argumentMap.max != null) s = s.max(configuration.argumentMap.max as number, { message: configuration.errorMessage });\n          return s;\n        }\n        return schema;\n      },\n    },\n    {\n      supports: (configuration) => configuration.name === \"Pattern\",\n      convert: (configuration, schema: any) => {\n        if (!(schema instanceof z.ZodString)) {\n          return schema;\n        }\n\n        const patternStr = configuration.argumentMap.pattern;\n        if (typeof patternStr !== \"string\" || patternStr.trim() === \"\") {\n          return schema;\n        }\n\n        let regex: RegExp;\n        try {\n          regex = new RegExp(patternStr);\n        }\n        catch {\n          return schema;\n        }\n\n        return schema.regex(regex, { message: configuration.errorMessage });\n      },\n    },\n    {\n      supports: (configuration) => [\"Min\", \"Max\"].includes(configuration.name),\n      convert: (configuration, schema: any) => {\n        if (!(schema instanceof z.ZodNumber) || configuration.argumentMap.value == null) return schema;\n        const value = configuration.argumentMap.value as number;\n        return configuration.name === \"Min\"\n          ? schema.min(value, { message: configuration.errorMessage })\n          : schema.max(value, { message: configuration.errorMessage });\n      },\n    },\n    {\n      supports: (configuration) => configuration.name === \"InList\",\n      convert: (config, schema: any) => {\n        const values = config.argumentMap.value;\n        if (Array.isArray(values)) {\n          return schema.refine(\n            (val: any) => values.includes(val),\n            { message: config.errorMessage },\n          );\n        }\n        return schema;\n      },\n    },\n    {\n      supports: (configuration) => configuration.name === \"Email\",\n      convert: (configuration, schema: any) => {\n        if (!(schema instanceof z.ZodString)) {\n          return schema;\n        }\n        return z.email(configuration.errorMessage);\n      },\n    },\n    {\n      supports: () => true,\n      convert: (_, schema: any) => schema,\n    },\n  ];\n}\n"],"mappings":"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","names":["_uniqBy"]}