Skip to content

Commit

Permalink
Extract secret queries to SecretApi
Browse files Browse the repository at this point in the history
  • Loading branch information
kielbasa-elp committed Feb 26, 2024
1 parent fa1c5c2 commit 657db21
Show file tree
Hide file tree
Showing 10 changed files with 85 additions and 49 deletions.
48 changes: 48 additions & 0 deletions apps/web-remix/app/api/secrets/SecretsApi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { fetchTyped } from "~/utils/fetch.server";
import {
ICreateUpdateSecretSchema,
SecretKeyListResponse,
SecretKeyResponse,
} from "./secrets.contracts";
import { z } from "zod";

export class SecretsApi {
constructor(private client: typeof fetchTyped) {}

async getSecrets(organizationId: string | number) {
return this.client(
SecretKeyListResponse,
`/organizations/${organizationId}/secrets`
);
}

async deleteSecret(organizationId: string | number, name: string) {
return this.client(
z.any(),
`/organizations/${organizationId}/secrets/${name}`,
{ method: "DELETE" }
);
}

async updateSecret(
organizationId: string | number,
data: ICreateUpdateSecretSchema
) {
return this.client(
z.any(),
`/organizations/${organizationId}/secrets/${data.name}`,
{ method: "PUT", body: JSON.stringify({ value: data.value }) }
);
}

async createSecret(
organizationId: string | number,
data: ICreateUpdateSecretSchema
) {
return this.client(
SecretKeyResponse,
`/organizations/${organizationId}/secrets`,
{ method: "POST", body: JSON.stringify(data) }
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,12 @@ export const SecretKeyListResponse = z
data: SecretKeyList,
})
.transform((res) => res.data);

export const CreateUpdateSecretSchema = z.object({
name: z.string().min(2),
value: z.string().min(2),
});

export type ICreateUpdateSecretSchema = z.TypeOf<
typeof CreateUpdateSecretSchema
>;
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ import React, { useMemo } from "react";
import { ValidatedForm } from "remix-validated-form";
import { Modal } from "@elpassion/taco/Modal";
import { withZod } from "@remix-validated-form/with-zod";
import { Button } from "@elpassion/taco";

import { Field } from "~/components/form/fields/field.context";
import {
PasswordInputField,
TextInputField,
} from "~/components/form/fields/text.field";
import { ISecretKey } from "../variables.types";
import { schema } from "./schema";
import { CreateUpdateSecretSchema } from "~/api/secrets/secrets.contracts";
import { SubmitButton } from "~/components/form/submit";
interface EditSecretModalProps {
isOpen: boolean;
Expand All @@ -22,7 +22,7 @@ export const EditSecretKeyModal: React.FC<EditSecretModalProps> = ({
onClose,
initialData,
}) => {
const validator = useMemo(() => withZod(schema), []);
const validator = useMemo(() => withZod(CreateUpdateSecretSchema), []);

return (
<Modal
Expand Down
25 changes: 12 additions & 13 deletions apps/web-remix/app/components/pages/secrets/list/action.server.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ import { ActionFunctionArgs, json, redirect } from "@remix-run/node";
import { actionBuilder } from "~/utils.server";
import { requireLogin } from "~/session.server";
import invariant from "tiny-invariant";
import { z } from "zod";
import { validationError } from "remix-validated-form";
import { withZod } from "@remix-validated-form/with-zod";
import { schema } from "./schema";
import { CreateUpdateSecretSchema } from "~/api/secrets/secrets.contracts";
import { routes } from "~/utils/routes.utils";
import { setServerToast } from "~/utils/toast.server";
import { SecretsApi } from "~/api/secrets/SecretsApi";
import { assert } from "~/utils/assert";

export async function action(actionArgs: ActionFunctionArgs) {
return actionBuilder({
Expand All @@ -16,11 +17,11 @@ export async function action(actionArgs: ActionFunctionArgs) {
invariant(params.organizationId, "Missing organizationId");
const name = (await request.formData()).get("name");

await fetch(
z.any(),
`/organizations/${params.organizationId}/secrets/${name}`,
{ method: "DELETE" }
);
assert(name);

const secretsApi = new SecretsApi(fetch);

await secretsApi.deleteSecret(params.organizationId, name as string);

return json(
{},
Expand All @@ -40,17 +41,15 @@ export async function action(actionArgs: ActionFunctionArgs) {
await requireLogin(request);
invariant(params.organizationId, "Missing organizationId");

const validator = withZod(schema);
const validator = withZod(CreateUpdateSecretSchema);

const result = await validator.validate(await request.formData());

if (result.error) return validationError(result.error);

await fetch(
z.any(),
`/organizations/${params.organizationId}/secrets/${result.data.name}`,
{ method: "PUT", body: JSON.stringify({ value: result.data.value }) }
);
const secretsApi = new SecretsApi(fetch);

await secretsApi.updateSecret(params.organizationId, result.data);

return redirect(routes.secrets(params.organizationId), {
headers: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,15 @@ import { json, LoaderFunctionArgs } from "@remix-run/node";
import invariant from "tiny-invariant";
import { loaderBuilder } from "~/utils.server";
import { requireLogin } from "~/session.server";
import { SecretKeyListResponse } from "../contracts";
import { SecretsApi } from "~/api/secrets/SecretsApi";

export async function loader(args: LoaderFunctionArgs) {
return loaderBuilder(async ({ request, params }, { fetch }) => {
await requireLogin(request);
invariant(params.organizationId, "organizationId not found");

const secrets = await fetch(
SecretKeyListResponse,
`/organizations/${params.organizationId}/secrets`
);
const secretsApi = new SecretsApi(fetch);
const secrets = await secretsApi.getSecrets(params.organizationId);
return json({
organizationId: params.organizationId,
secrets: secrets.data,
Expand Down
6 changes: 0 additions & 6 deletions apps/web-remix/app/components/pages/secrets/list/schema.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,28 +1,26 @@
import { ActionFunctionArgs, redirect } from "@remix-run/node";
import invariant from "tiny-invariant";
import { actionBuilder } from "~/utils.server";
import { SecretKeyResponse } from "../contracts";
import { validationError } from "remix-validated-form";
import { withZod } from "@remix-validated-form/with-zod";
import { schema } from "./schema";
import { CreateUpdateSecretSchema } from "~/api/secrets/secrets.contracts";
import { routes } from "~/utils/routes.utils";
import { setServerToast } from "~/utils/toast.server";
import { SecretsApi } from "~/api/secrets/SecretsApi";

export async function action(actionArgs: ActionFunctionArgs) {
return actionBuilder({
post: async ({ params, request }, { fetch }) => {
const validator = withZod(schema);
const validator = withZod(CreateUpdateSecretSchema);
invariant(params.organizationId, "organizationId not found");

const result = await validator.validate(await request.formData());

if (result.error) return validationError(result.error);

await fetch(
SecretKeyResponse,
`/organizations/${params.organizationId}/secrets`,
{ method: "POST", body: JSON.stringify(result.data) }
);
const secretsApi = new SecretsApi(fetch);

await secretsApi.createSecret(params.organizationId, result.data);

return redirect(routes.secrets(params.organizationId), {
headers: {
Expand Down
10 changes: 3 additions & 7 deletions apps/web-remix/app/components/pages/secrets/newSecret/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ import {
TextInputField,
} from "~/components/form/fields/text.field";
import { SubmitButton } from "~/components/form/submit";
import { schema } from "./schema";

import { CreateUpdateSecretSchema } from "~/api/secrets/secrets.contracts";
export function NewSecret() {
const validator = useMemo(() => withZod(schema), []);
const validator = useMemo(() => withZod(CreateUpdateSecretSchema), []);

return (
<ValidatedForm
Expand Down Expand Up @@ -40,10 +39,7 @@ export function NewSecret() {
/>
</Field>
</div>
<SubmitButton
size="sm"
hierarchy="primary"
>
<SubmitButton size="sm" hierarchy="primary">
Save the Secret
</SubmitButton>
</ValidatedForm>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { z } from "zod";
import { SecretKey, SecretKeyList } from "./contracts";
import { SecretKey, SecretKeyList } from "~/api/secrets/secrets.contracts";

export type ISecretKey = z.TypeOf<typeof SecretKey>;

Expand Down

0 comments on commit 657db21

Please sign in to comment.