m6io / react-formgen

Headless, unopinionated, and flexible form generation.
https://react-formgen.vercel.app
MIT License
24 stars 1 forks source link

throw error on json shcema `anyOf` #2

Closed himself65 closed 1 day ago

himself65 commented 2 weeks ago
{"description": "Microsoft OneDrive reader.\n\nInitializes a new instance of the OneDriveReader.\n\n:param client_id: The Application (client) ID for the app registered in the Azure Entra (formerly Azure Active directory) portal with MS Graph permission \"Files.Read.All\".\n:param tenant_id: The Directory (tenant) ID of the Azure Active Directory (AAD) tenant the app is registered with.\n                  Defaults to \"consumers\" for multi-tenant applications and OneDrive personal.\n:param client_secret: The Application Secret for the app registered in the Azure portal.\n                      If provided, the MSAL client credential flow will be used for authentication (ConfidentialClientApplication).\n                      If not provided, interactive authentication will be used (Not recommended for CI/CD or scenarios where manual interaction for authentication is not feasible).\n                      Required for App authentication.\n:param userprinciplename: The user principal name (normally organization provided email) whose OneDrive will be accessed. Required for App authentication. Will be used if the\n                          parameter is not provided when calling load_data().\n:param folder_id: The folder ID of the folder to fetch from OneDrive. Will be used if the parameter is not provided when calling load_data().\n:param file_ids: A list of file IDs of files to fetch from OneDrive. Will be used if the parameter is not provided when calling load_data().\n:param folder_path (str, optional): The relative path of the OneDrive folder to download. If provided, files within the folder are downloaded.  Will be used if the parameter is\n                                    not provided when calling load_data().\n:param file_paths (List[str], optional): List of specific file paths to download. Will be used if the parameter is not provided when calling load_data().\n:param file_extractor (Optional[Dict[str, BaseReader]]): A mapping of file extension to a BaseReader class that specifies how to convert that file to text.\n                                                         See `SimpleDirectoryReader` for more details.\n\n\nFor interactive authentication to work, a browser is used to authenticate, hence the registered application should have a redirect URI set to 'https://localhost'\nfor mobile and native applications.", "properties": {"is_remote": {"default": false, "description": "Whether the data is loaded from a remote API or a local file.", "title": "Is Remote", "type": "boolean"}, "client_id": {"title": "Client Id", "type": "string"}, "client_secret": {"anyOf": [{"type": "string"}, {"type": "null"}], "default": null, "title": "Client Secret"}, "tenant_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "default": null, "title": "Tenant Id"}, "userprincipalname": {"anyOf": [{"type": "string"}, {"type": "null"}], "default": null, "title": "Userprincipalname"}, "folder_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "default": null, "title": "Folder Id"}, "file_ids": {"anyOf": [{"items": {"type": "string"}, "type": "array"}, {"type": "null"}], "default": null, "title": "File Ids"}, "folder_path": {"anyOf": [{"type": "string"}, {"type": "null"}], "default": null, "title": "Folder Path"}, "file_paths": {"anyOf": [{"items": {"type": "string"}, "type": "array"}, {"type": "null"}], "default": null, "title": "File Paths"}, "file_extractor": {"anyOf": [{"additionalProperties": {"type": "string"}, "type": "object"}, {"type": "null"}], "default": null, "title": "File Extractor"}, "class_name": {"default": "base_component", "title": "Class Name", "type": "string"}}, "required": ["client_id"], "title": "OneDriveReader", "type": "object"}
m6io commented 2 weeks ago

Can you provide more information?

himself65 commented 2 weeks ago

Yeah, I copy the schema to playground and most of inputs get error

m6io commented 2 weeks ago

Can you share the schema?

himself65 commented 2 weeks ago

It's already in the description!

m6io commented 1 day ago

Okay so regarding the anyOf issue: since my focus with this package is to make an extensible and un-opinionated form generator, the built-in template renderer really only looks at types and let's the type-specific template components handle all additional schema metatada.

Since JSON Schema is pretty open-ended, I decided against having the built-in renderer do any type inferences, so every level of your schema will need to be typed appropriately, which from what I can see is not the case.

Regarding anyOf: schema composition in general has way too many potential use cases, so to keep in line with the un-opinionated philosophy, I decided against implementing any specific approach within the package itself, so you're free to implement them how you see fit.

You can provide the <Form> with your own RenderTemplate if you have your own ideas of how you'd like to handle schemas in general (meaning, if you don't want to use my "type"-based approach and have your own implementation in mind) or you can add the types to your schema and handle the anyOfs how you see fit in the type-based templates.

Take a look at the example: https://github.com/m6io/react-formgen/blob/main/website/src/examples/JsonSchema.tsx#L119. It's not comprehensive, but it should give you an idea.

Alternatively, you can tyr this modified version of your schema

{
  "description": "Microsoft OneDrive reader.\n\nInitializes a new instance of the OneDriveReader.\n\n:param client_id: The Application (client) ID for the app registered in the Azure Entra (formerly Azure Active directory) portal with MS Graph permission \"Files.Read.All\".\n:param tenant_id: The Directory (tenant) ID of the Azure Active Directory (AAD) tenant the app is registered with.\n                  Defaults to \"consumers\" for multi-tenant applications and OneDrive personal.\n:param client_secret: The Application Secret for the app registered in the Azure portal.\n                      If provided, the MSAL client credential flow will be used for authentication (ConfidentialClientApplication).\n                      If not provided, interactive authentication will be used (Not recommended for CI/CD or scenarios where manual interaction for authentication is not feasible).\n                      Required for App authentication.\n:param userprinciplename: The user principal name (normally organization provided email) whose OneDrive will be accessed. Required for App authentication. Will be used if the\n                          parameter is not provided when calling load_data().\n:param folder_id: The folder ID of the folder to fetch from OneDrive. Will be used if the parameter is not provided when calling load_data().\n:param file_ids: A list of file IDs of files to fetch from OneDrive. Will be used if the parameter is not provided when calling load_data().\n:param folder_path (str, optional): The relative path of the OneDrive folder to download. If provided, files within the folder are downloaded.  Will be used if the parameter is\n                                    not provided when calling load_data().\n:param file_paths (List[str], optional): List of specific file paths to download. Will be used if the parameter is not provided when calling load_data().\n:param file_extractor (Optional[Dict[str, BaseReader]]): A mapping of file extension to a BaseReader class that specifies how to convert that file to text.\n                                                         See `SimpleDirectoryReader` for more details.\n\n\nFor interactive authentication to work, a browser is used to authenticate, hence the registered application should have a redirect URI set to 'https://localhost'\nfor mobile and native applications.",
  "properties": {
    "is_remote": {
      "default": false,
      "description": "Whether the data is loaded from a remote API or a local file.",
      "title": "Is Remote",
      "type": "boolean"
    },
    "client_id": {"title": "Client Id", "type": "string"},
    "client_secret": {
      "type": "string",
      "default": "",
      "description": "The Application Secret for the app. Empty string if not provided."
    },
    "tenant_id": {
      "type": "string",
      "default": "",
      "description": "The Directory (tenant) ID. Defaults to empty string if not provided."
    },
    "userprincipalname": {
      "type": "string",
      "default": "",
      "description": "The user principal name whose OneDrive will be accessed. Defaults to empty string if not provided."
    },
    "folder_id": {
      "type": "string",
      "default": "",
      "description": "The folder ID of the folder to fetch from OneDrive. Defaults to empty string if not provided."
    },
    "file_ids": {
      "type": "array",
      "items": {"type": "string"},
      "default": [],
      "description": "A list of file IDs to fetch from OneDrive. Defaults to an empty list if not provided."
    },
    "folder_path": {
      "type": "string",
      "default": "",
      "description": "The relative path of the OneDrive folder to download. Defaults to empty string if not provided."
    },
    "file_paths": {
      "type": "array",
      "items": {"type": "string"},
      "default": [],
      "description": "List of specific file paths to download. Defaults to an empty list if not provided."
    },
    "file_extractor": {
      "type": "object",
      "additionalProperties": {"type": "string"},
      "default": {},
      "description": "A mapping of file extension to a BaseReader class. Defaults to an empty object if not provided."
    },
    "class_name": {
      "default": "base_component",
      "title"  : "Class Name"    ,
      "type"   : "string"
    }
  },
  "required": ["client_id"],
  "title": "OneDriveReader",
  "type": "object"
}

Here's a little playpen if you want to test it out. Just dump the schema in the "JSON Schema" editor and hit the refresh icon to see how it renders https://formgen-testing.vercel.app/