Skip to content

Commit

Permalink
Update dependencies and fix eslint configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
Tiscs committed May 3, 2024
1 parent a9f3919 commit 7a7887d
Show file tree
Hide file tree
Showing 17 changed files with 811 additions and 924 deletions.
9 changes: 8 additions & 1 deletion .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ module.exports = {
ecmaFeatures: {
jsx: true,
},
project: ["./tsconfig.json"],
tsconfigRootDir: __dirname,
},
env: {
browser: true,
Expand Down Expand Up @@ -66,7 +68,12 @@ module.exports = {
},
},
},
extends: ["plugin:@typescript-eslint/recommended", "plugin:import/recommended", "plugin:import/typescript"],
extends: [
"plugin:@typescript-eslint/strict-type-checked",
"plugin:@typescript-eslint/stylistic-type-checked",
"plugin:import/recommended",
"plugin:import/typescript",
],
},

// Node
Expand Down
2 changes: 1 addition & 1 deletion app/clients/grpc.client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { ChatsService } from "@proto/chats/v1beta/chats_connect";
import { createRegistry } from "@bufbuild/protobuf";
import { createGrpcGatewayTransport, createPromiseClient, googleRpcTypes } from "~/connect";

invariant(import.meta.env.VITE_GRPC_ENDPOINT, "environment variable VITE_GRPC_ENDPOINT is required.");
invariant(typeof import.meta.env.VITE_GRPC_ENDPOINT === "string", "environment variable VITE_GRPC_ENDPOINT is required.");

const endpoint = import.meta.env.VITE_GRPC_ENDPOINT;

Expand Down
2 changes: 1 addition & 1 deletion app/clients/grpc.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { createGrpcTransport } from "@connectrpc/connect-node";
import { createPromiseClient } from "@connectrpc/connect";
import { singleton } from "~/singleton.server";

invariant(process.env.GOMMERCE_GRPC_ENDPOINT, "environment variable GOMMERCE_GRPC_ENDPOINT is required.");
invariant(typeof process.env.GOMMERCE_GRPC_ENDPOINT === "string", "environment variable GOMMERCE_GRPC_ENDPOINT is required.");

const endpoint = process.env.GOMMERCE_GRPC_ENDPOINT;

Expand Down
30 changes: 15 additions & 15 deletions app/clients/state.server.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import type { SessionData, SessionStorage, SessionIdStorageStrategy } from "@remix-run/node";
import type { FlashSessionData } from "@remix-run/server-runtime";
import { createSessionStorage } from "@remix-run/node";
import { stateStoreServiceClient as stateStore } from "~/clients/grpc.server";
import { v4 as uuidv4 } from "uuid";
import invariant from "tiny-invariant";

invariant(typeof process.env.GOMMERCE_CLIENT_TOKEN === "string", "environment variable GOMMERCE_CLIENT_TOKEN is required.");

const clientToken = process.env.GOMMERCE_CLIENT_TOKEN;

interface CookieSessionStorageOptions {
bucket?: string;
Expand All @@ -11,14 +17,14 @@ interface CookieSessionStorageOptions {
export function createStateSessionStorage<Data = SessionData, FlashData = Data>(
options?: CookieSessionStorageOptions,
): SessionStorage<Data, FlashData> {
const bucket = options?.bucket || "sessions";
const bucket = options?.bucket ?? "sessions";
const encoder = new TextEncoder();
const decoder = new TextDecoder();
const upsert = async (id: string, data: string, expires?: Date): Promise<void> => {
const key = `${bucket}:${id}`;
const metadata: { [key: string]: string } = {};
const metadata: Record<string, string> = {};
if (expires) {
metadata["ttlInSeconds"] = Math.floor((expires.getTime() - Date.now()) / 1000).toString(10);
metadata.ttlInSeconds = Math.floor((expires.getTime() - Date.now()) / 1000).toString(10);
}
await stateStore.setState(
{
Expand All @@ -27,33 +33,27 @@ export function createStateSessionStorage<Data = SessionData, FlashData = Data>(
metadata,
contentType: "application/json",
},
{ headers: { Authorization: `Basic ${process.env.GOMMERCE_CLIENT_TOKEN}` } },
{ headers: { Authorization: `Basic ${clientToken}` } },
);
};
return createSessionStorage<Data, FlashData>({
cookie: options?.cookie,
async createData(data, expires) {
const id = uuidv4();
await upsert(id, JSON.stringify(data || null), expires);
await upsert(id, JSON.stringify(data), expires);
return id;
},
async readData(id) {
const key = `${bucket}:${id}`;
const { data } = await stateStore.getState(
{ key },
{ headers: { Authorization: `Basic ${process.env.GOMMERCE_CLIENT_TOKEN}` } },
);
return data && data.length > 0 ? JSON.parse(decoder.decode(data)) : null;
const { data } = await stateStore.getState({ key }, { headers: { Authorization: `Basic ${clientToken}` } });
return data.length > 0 ? (JSON.parse(decoder.decode(data)) as FlashSessionData<Data, FlashData>) : null;
},
async updateData(id, data, expires) {
await upsert(id, JSON.stringify(data || null), expires);
await upsert(id, JSON.stringify(data), expires);
},
async deleteData(id) {
const key = `${bucket}:${id}`;
await stateStore.delState(
{ key },
{ headers: { Authorization: `Basic ${process.env.GOMMERCE_CLIENT_TOKEN}` } },
);
await stateStore.delState({ key }, { headers: { Authorization: `Basic ${clientToken}` } });
},
});
}
4 changes: 2 additions & 2 deletions app/connect/grpc-gateway-transport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export function createGrpcGatewayTransport(options: GrpcGatewayTransportOptions)
if (!response.body) {
throw new Error("missing response body");
}
await validateResponse(response);
await validateResponse(response, options.jsonOptions);
return {
stream: false,
service,
Expand Down Expand Up @@ -138,7 +138,7 @@ export function createGrpcGatewayTransport(options: GrpcGatewayTransportOptions)
if (!response.body) {
throw new Error("missing response body");
}
await validateResponse(response);
await validateResponse(response, options.jsonOptions);
return {
stream: true,
service,
Expand Down
4 changes: 2 additions & 2 deletions app/connect/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export { createPromiseClient, createCallbackClient } from "@connectrpc/connect";
export * from "./grpc-gateway-transport";
export { createCallbackClient, createPromiseClient } from "@connectrpc/connect";
export * from "./google-rpc-types";
export * from "./grpc-gateway-transport";
18 changes: 0 additions & 18 deletions app/entry.client.tsx

This file was deleted.

122 changes: 0 additions & 122 deletions app/entry.server.tsx

This file was deleted.

4 changes: 2 additions & 2 deletions app/partials/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ import {
} from "@tabler/icons-react";
import { useHandleData } from "~/utils/hooks";

export type LayoutOptions = {
export interface LayoutOptions {
useSidebar?: boolean;
};
}

export default function Frame(props: { context?: unknown }) {
const { user } = useAuthorize();
Expand Down
2 changes: 1 addition & 1 deletion app/routes/login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export default function Index() {
<Form method="post">
<p className="my-6 select-none text-center text-2xl font-semibold uppercase">Gommerce</p>
<ul className="list-inside list-disc text-error">
{actionData?.formErrors?.map((m: string, k: number) => (
{actionData?.formErrors.map((m: string, k: number) => (
<li key={k} title={m}>
{m}
</li>
Expand Down
21 changes: 13 additions & 8 deletions app/secure.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,24 @@ import { ConnectError, Code } from "@connectrpc/connect";
import { usersServiceClient as users, tokensServiceClient as tokens } from "~/clients/grpc.server";
import { getSession, commitSession } from "~/session.server";

invariant(process.env.GOMMERCE_AUTH_REALM, "environment variable GOMMERCE_AUTH_REALM is required.");
invariant(process.env.REMIX_COOKIE_SECRET, "environment variable REMIX_COOKIE_SECRET is required.");
invariant(typeof process.env.GOMMERCE_AUTH_REALM === "string", "environment variable GOMMERCE_AUTH_REALM is required.");
invariant(typeof process.env.REMIX_COOKIE_SECRET === "string", "environment variable REMIX_COOKIE_SECRET is required.");
invariant(typeof process.env.GOMMERCE_CLIENT_TOKEN === "string", "environment variable GOMMERCE_CLIENT_TOKEN is required.");

const authRealm = process.env.GOMMERCE_AUTH_REALM;
const cookieSecret = process.env.REMIX_COOKIE_SECRET;
const clientToken = process.env.GOMMERCE_CLIENT_TOKEN;

const __token__ = createCookie("__token__", {
httpOnly: true,
path: "/",
sameSite: "lax",
secrets: [process.env.REMIX_COOKIE_SECRET],
secrets: [cookieSecret],
secure: process.env.NODE_ENV === "production",
});

export async function getToken(request: Request) {
const cookie = await __token__.parse(request.headers.get("Cookie"));
const cookie = (await __token__.parse(request.headers.get("Cookie"))) as string | null;
return typeof cookie === "string" ? cookie : null;
}

Expand All @@ -26,7 +31,7 @@ export async function getIdentity(request: Request) {
if (token) {
const { user, scope } = await users.getIdentity({}, { headers: { Authorization: `Bearer ${token}` } });
if (user) {
return { user: user.toJson(), scope: scope || [] };
return { user: user.toJson(), scope: scope };
}
console.error("unexpected error: user is not present in the response", {
user,
Expand All @@ -43,7 +48,7 @@ export async function authorize(request: Request) {
try {
const { user, scope } = await users.getIdentity({}, { headers: { Authorization: `Bearer ${token}` } });
if (user) {
return { user: user.toJson(), token, scope: scope || [] };
return { user: user.toJson(), token, scope: scope };
}
console.error("unexpected error: user is not present in the response", {
user,
Expand Down Expand Up @@ -71,14 +76,14 @@ export async function login(request: Request, redirectTo = "/") {
const { username, password } = LoginForm.parse(Object.fromEntries(formData));
const { accessToken, refreshToken, expiresIn } = await tokens.createToken(
{
realm: process.env.GOMMERCE_AUTH_REALM,
realm: authRealm,
provider: "FORM_PASSWORD",
username,
password,
},
{
headers: {
Authorization: `Basic ${process.env.GOMMERCE_CLIENT_TOKEN}`,
Authorization: `Basic ${clientToken}`,
},
},
);
Expand Down
4 changes: 2 additions & 2 deletions app/secure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import { User } from "@proto/iam/v1beta/users_pb";
import type { loader } from "~/root";
import { useMatchData } from "~/utils/hooks";

export type Identity = {
export interface Identity {
user: User | null;
token: string | null;
scope: string[];
};
}

export function useAuthorize(): Identity {
const routeData = useMatchData<typeof loader>("root");
Expand Down
4 changes: 1 addition & 3 deletions app/singleton.server.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
declare global {
// eslint-disable-next-line no-var
var __singletons__: {
[name: string]: unknown;
};
var __singletons__: Record<string, unknown> | undefined;
}

export function singleton<V>(name: string, factory: () => V): V {
Expand Down
Loading

0 comments on commit 7a7887d

Please sign in to comment.