Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Schema.FormData literal to work with 3rd party libs that expose only it #3986

Open
MrOxMasTer opened this issue Nov 23, 2024 · 8 comments
Open
Assignees
Labels
enhancement New feature or request Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. schema

Comments

@MrOxMasTer
Copy link

What is the problem this feature would solve?

FormData validation

What is the feature you are proposing to solve the problem?

Use schemas to validate formData

What alternatives have you considered?

https://www.npmjs.com/package/zod-form-data

@MrOxMasTer MrOxMasTer added the enhancement New feature or request label Nov 23, 2024
@IMax153 IMax153 added schema Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. labels Nov 23, 2024
@MrOxMasTer
Copy link
Author

MrOxMasTer commented Nov 25, 2024

I'm not so versed in Effect yet that I can come up with anything, but I guess you could probably do something like this:

import { Schema as S } from “effect”;

const TodoSchema = S.Struct({
    id: S.String,
    content: S.String
});

const TodoFormDataSchema = S.formData(Todo);
const decoded = S.decodeUnknownPromise(TodoFormDataSchema)
const encoded = S.encodePromise(TodoFormDataSchema)

const serverAction = async (formData: FormData) => {
    const decode = await decoded(formData) // -> { id: “...”, content: “...” };
    const encode = await encoded(decode) // -> formData
}

await serverAction();

It's also worth considering other things that can be passed in formData:
image

@MrOxMasTer
Copy link
Author

You should add more types related to FormData, these are:
image

const SchemaFormData = S.FormData(S.Struct({
  text: S.Text(),
  numeric: S.Numeric(),
  checkbox: S.Checkbox(),
  file: S.File(),
  repeatable: S.Repeatable(),
  repeatableOfType: S.RepeatableOfType()
}))

@datner
Copy link
Member

datner commented Dec 1, 2024

These exist under the Multipart module, and formdata has supporting API in a server and in a client as can be seen in HttpBody, HttpClientRequest, HttpServerRequest, HttpServerResponse, and various modules of the HttpApi family. All from @effect/platform.

Also, text is just Schema.String, or if pushed can be Schema.NonEmptyTrimmedString or Schema.OptionFromNonEmptyTrimmedString.
numeric is Schema.NumberFromString,
checkbox:

Schema.transformLiterals(["on", true], ["", false]).pipe(
  Schema.optionalWith({ default: () => false }),
);

File exists, only thing that is missing is Repeatable or more exactly support for Schema.Array

@MrOxMasTer
Copy link
Author

MrOxMasTer commented Dec 1, 2024

These exist under the Multipart module, and formdata has supporting API in a server and in a client as can be seen in HttpBody, HttpClientRequest, HttpServerRequest, HttpServerResponse, and various modules of the HttpApi family. All from @effect/platform.

Yes, there is indeed an api, but as I understand it, there is no complete FormData check - only in pieces (file, json, ...)?

@MrOxMasTer
Copy link
Author

These exist under the Multipart module, and formdata has supporting API in a server and in a client as can be seen in HttpBody, HttpClientRequest, HttpServerRequest, HttpServerResponse, and various modules of the HttpApi family. All from @effect/platform.

I made a request for this function because there are api's - over which I have no power. For example next-safe-action. All I can do in the .schema method is only pass a function that controls the schema itself, not the data processing, which is why I need this api

@datner
Copy link
Member

datner commented Dec 2, 2024

It seems that the lib is taking a very heavy-handed approach to schema integration, taking inspiration from typeschema, with a very important difference being that the latter does universal validation so this approach is expected but the former has no reason to bake it in like that. Regardless, the adapters are pretty trivial to implement. But I now understand what you are asking for, not tools for working with FormData, but rather the nominal FormData schema. I think that request is valid

@gcanti Besides the Multipart module, would we be interested in shipping a builtin FormData literal schema? It is increasingly popular for web frameworks to expose API that directly interacts with it in non-file scenarios as part of progressive-enhancement support, in those specific cases, if the user does not use @effect/platform, then they are tasked with handling the raw FormData directly.
Examples include Remix, Tanstack Router, and NextJS

@datner datner changed the title Tools for working with FormData Schema.FormData literal to work with 3rd party libs that expose only it Dec 2, 2024
@MrOxMasTer
Copy link
Author

@gcanti Besides the Multipart module, would we be interested in shipping a builtin FormData literal schema? It is increasingly popular for web frameworks to expose API that directly interacts with it in non-file scenarios as part of progressive-enhancement support, in those specific cases, if the user does not use @effect/platform, then they are tasked with handling the raw FormData directly. Examples include Remix, Tanstack Router, and NextJS

You're talking about scenarios where the user might not @effect/platform. If you add just a nominal formData schema, it might be strange that schemas, for files in formData etc are not bundled with it.
My idea -> move the schemas, for fields in formData (files etc) to the main Schema library. And I think the schema for checkbox - although the implementation is trivial, but it's nice when it's there and you don't need to write it again from project to project, so I think it's worth adding it too.

@datner
Copy link
Member

datner commented Dec 2, 2024

Thats not good logic, taking to its natural conclusion there should be no ecosystem packages because users might not use them but would want to use something they have. It doesn't track. It might go into effect regardless, but not to spare users from \platform lol

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. schema
Projects
None yet
Development

No branches or pull requests

4 participants