0.11.0 • Published 11 days ago

remix-data-kit v0.11.0

Weekly downloads
-
License
MIT
Repository
github
Last release
11 days ago

remix-data-kit

a kit to simplify remix actions / handling form data

Install

npm install remix-data-kit

Usage

We provide the default remix ActionFunctionArgs as argument, and extend it with a payload property, that contains the FormData as an expanded object using form-data-kit. No more manually handling formData.

import { createActionHandler } from 'remix-data-kit';

export const action = createActionHandler({
	CREATE_COMMENT: ({ request, context, payload }) => {
		assertUser(request);
		return context.api.createComment({ user, comment: payload });
	},
	UPDATE_COMMENT: ({ request, context, payload }) => {
		assertUser(request);
		return context.api.updateComment({ user, comment: payload });
	},
});

Without remix-data-kit it would look something like this:

export const action = async ({ request, context }: ActionFunctionArgs) => {
	const formData = await request.formData();
	const _intent = formData.get('_intent');

	switch (_intent) {
		case 'CREATE_COMMENT': {
			assertUser(request);
			const body = formData.get('body');
			const tags = formData.get('tags');
			return context.api.createComment({ user, comment: { body, tags } });
		}

		case 'UPDATE_COMMENT': {
			assertUser(request);
			const body = formData.get('body');
			return context.api.updateComment({ user, comment: { body } });
		}

		default: {
			throw json({
				ok: false,
				message: `No handler found for action: ${_intent}`,
			});
		}
	}
};

Validation

To ease validation, we've wrapped the assertType utility from typebox-assert, that asserts and narrows the type of the submitted data using typebox.

assertType throws a Response with errors when the type is invalid. It also mutates the object to:

  • remove additional properties that are not defined in the schema
  • add missing properties by using schema defaults
  • cast property types where possible
import { createActionHandler, assertType } from 'remix-data-kit';
import { Type } from '@sinclair/typebox';

const CreateComment = Type.Object(
	{
		body: Type.String(),
		tags: Type.String(),
	},
	{ $id: 'CreateComment' },
);

const UpdateComment = Type.Object(
	{
		body: Type.String(),
	},
	{ $id: 'UpdateComment' },
);

export const actions = createActionHandler({
	CREATE_COMMENT: ({ request, context, payload }) => {
		assertUser(request);
		assertType(CreateComment, payload); // throws Response when invalid
		// payload is narrowed to type CreateComment
		return context.api.createComment({ user, comment: payload });
	},
	UPDATE_COMMENT: ({ request, context, payload }) => {
		assertUser(request);
		assertType(UpdateComment, payload); // throws Response when invalid
		// payload is narrowed to type UpdateComment
		return context.api.updateComment({ user, comment: payload });
	},
});
0.10.0

11 days ago

0.11.0

11 days ago

0.9.0

11 days ago

0.8.0

13 days ago

0.7.0

16 days ago

0.6.0

16 days ago

0.5.0

17 days ago

0.4.0

17 days ago

0.3.1

17 days ago

0.3.0

18 days ago

0.2.0

20 days ago

0.1.0

20 days ago