Compare commits
10 Commits
8916fd759e
...
a98a9c2c79
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a98a9c2c79 | ||
|
|
5acb326c03 | ||
|
|
3214fe716d | ||
|
|
31f9bac50b | ||
|
|
6bfcc4db24 | ||
|
|
fa3f461add | ||
|
|
7ab2d3b812 | ||
|
|
d28ecef77c | ||
|
|
85d296942b | ||
|
|
5267c35d15 |
18
package.json
18
package.json
@@ -7,26 +7,38 @@
|
|||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "tsc -b && vite build",
|
"build": "tsc -b && vite build",
|
||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
"preview": "vite preview"
|
"preview": "vite preview",
|
||||||
|
"test:unit": "vitest",
|
||||||
|
"test:run": "vitest run",
|
||||||
|
"test:coverage": "vitest run --coverage"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"ky": "^1.14.3",
|
||||||
"react": "^19.2.0",
|
"react": "^19.2.0",
|
||||||
"react-dom": "^19.2.0"
|
"react-dom": "^19.2.0",
|
||||||
|
"zustand": "^5.0.12"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^9.39.1",
|
"@eslint/js": "^9.39.1",
|
||||||
"@module-federation/vite": "^1.12.3",
|
"@module-federation/vite": "^1.12.3",
|
||||||
|
"@testing-library/dom": "^10.4.1",
|
||||||
|
"@testing-library/jest-dom": "^6.9.1",
|
||||||
|
"@testing-library/react": "^16.3.2",
|
||||||
|
"@testing-library/user-event": "^14.6.1",
|
||||||
"@types/node": "^24.10.1",
|
"@types/node": "^24.10.1",
|
||||||
"@types/react": "^19.2.7",
|
"@types/react": "^19.2.7",
|
||||||
"@types/react-dom": "^19.2.3",
|
"@types/react-dom": "^19.2.3",
|
||||||
"@vitejs/plugin-react": "^5.1.4",
|
"@vitejs/plugin-react": "^5.1.4",
|
||||||
|
"@vitest/coverage-v8": "^4.1.0",
|
||||||
"babel-plugin-react-compiler": "^1.0.0",
|
"babel-plugin-react-compiler": "^1.0.0",
|
||||||
"eslint": "^9.39.1",
|
"eslint": "^9.39.1",
|
||||||
"eslint-plugin-react-hooks": "^7.0.1",
|
"eslint-plugin-react-hooks": "^7.0.1",
|
||||||
"eslint-plugin-react-refresh": "^0.4.24",
|
"eslint-plugin-react-refresh": "^0.4.24",
|
||||||
"globals": "^16.5.0",
|
"globals": "^16.5.0",
|
||||||
|
"jsdom": "^29.0.0",
|
||||||
"typescript": "~5.9.3",
|
"typescript": "~5.9.3",
|
||||||
"typescript-eslint": "^8.48.0",
|
"typescript-eslint": "^8.48.0",
|
||||||
"vite": "^7.3.1"
|
"vite": "^7.3.1",
|
||||||
|
"vitest": "^4.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1
src/entities/User/index.ts
Normal file
1
src/entities/User/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export * from "./model";
|
||||||
1
src/entities/User/model/index.ts
Normal file
1
src/entities/User/model/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export * from "./types/types";
|
||||||
10
src/entities/User/model/types/types.ts
Normal file
10
src/entities/User/model/types/types.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
export interface User {
|
||||||
|
/**
|
||||||
|
* User's unique identifier.
|
||||||
|
*/
|
||||||
|
id: string;
|
||||||
|
/**
|
||||||
|
* User's email address.
|
||||||
|
*/
|
||||||
|
email: string;
|
||||||
|
}
|
||||||
@@ -1,2 +1,3 @@
|
|||||||
export * from "./lib";
|
export * from "./lib";
|
||||||
export * from "./ui";
|
export * from "./ui";
|
||||||
|
export * from "./model";
|
||||||
|
|||||||
2
src/features/auth/model/index.ts
Normal file
2
src/features/auth/model/index.ts
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
export * from "./types/service";
|
||||||
|
export * from "./types/store";
|
||||||
9
src/features/auth/model/stores/authStore/authStore.ts
Normal file
9
src/features/auth/model/stores/authStore/authStore.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import { create } from "zustand";
|
||||||
|
import type { AuthStore } from "../../types/store";
|
||||||
|
|
||||||
|
export const useAuthStore = create<AuthStore>()((set) => ({
|
||||||
|
user: undefined,
|
||||||
|
status: "idle",
|
||||||
|
setUser: (user) => set({ user }),
|
||||||
|
setStatus: (status) => set({ status }),
|
||||||
|
}));
|
||||||
18
src/features/auth/model/types/service.ts
Normal file
18
src/features/auth/model/types/service.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import type { User } from "entities/User";
|
||||||
|
|
||||||
|
export interface AuthResponse {
|
||||||
|
/**
|
||||||
|
* Access token for the authenticated user.
|
||||||
|
*/
|
||||||
|
accessToken: string;
|
||||||
|
/**
|
||||||
|
* User object associated with the access token.
|
||||||
|
*/
|
||||||
|
user: User;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type AuthStatus =
|
||||||
|
| "idle"
|
||||||
|
| "loading"
|
||||||
|
| "authenticated"
|
||||||
|
| "unauthenticated";
|
||||||
20
src/features/auth/model/types/store.ts
Normal file
20
src/features/auth/model/types/store.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import type { User } from "entities/User";
|
||||||
|
import type { AuthStatus } from "./service";
|
||||||
|
|
||||||
|
export interface AuthStoreState {
|
||||||
|
/**
|
||||||
|
* User's credentials
|
||||||
|
*/
|
||||||
|
user?: User;
|
||||||
|
/**
|
||||||
|
* Authentication status
|
||||||
|
*/
|
||||||
|
status: AuthStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AuthStoreActions {
|
||||||
|
setUser: (user: AuthStoreState["user"] | undefined) => void;
|
||||||
|
setStatus: (status: AuthStoreState["status"]) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type AuthStore = AuthStoreState & AuthStoreActions;
|
||||||
2
src/shared/config/api/endpoint.ts
Normal file
2
src/shared/config/api/endpoint.ts
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
export const BASE_URL =
|
||||||
|
import.meta.env.VITE_API_BASE_URL || "https://localhost:3001";
|
||||||
6
src/shared/config/api/httpClient.ts
Normal file
6
src/shared/config/api/httpClient.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import ky from "ky";
|
||||||
|
import { BASE_URL } from "./endpoint";
|
||||||
|
|
||||||
|
export const api = ky.create({
|
||||||
|
prefixUrl: BASE_URL,
|
||||||
|
});
|
||||||
2
src/shared/config/index.ts
Normal file
2
src/shared/config/index.ts
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
export * from "./api/endpoint";
|
||||||
|
export * from "./api/httpClient";
|
||||||
1
src/shared/config/test/setup.ts
Normal file
1
src/shared/config/test/setup.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import "@testing-library/jest-dom";
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
"useDefineForClassFields": true,
|
"useDefineForClassFields": true,
|
||||||
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
||||||
"module": "ESNext",
|
"module": "ESNext",
|
||||||
"types": ["vite/client"],
|
"types": ["vite/client", "vitest/globals"],
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
|
|
||||||
/* Bundler mode */
|
/* Bundler mode */
|
||||||
@@ -22,7 +22,17 @@
|
|||||||
"noUnusedParameters": true,
|
"noUnusedParameters": true,
|
||||||
"erasableSyntaxOnly": true,
|
"erasableSyntaxOnly": true,
|
||||||
"noFallthroughCasesInSwitch": true,
|
"noFallthroughCasesInSwitch": true,
|
||||||
"noUncheckedSideEffectImports": true
|
"noUncheckedSideEffectImports": true,
|
||||||
|
|
||||||
|
/* FSD path aliases */
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"shared/*": ["src/shared/*"],
|
||||||
|
"entities/*": ["src/entities/*"],
|
||||||
|
"features/*": ["src/features/*"],
|
||||||
|
"widgets/*": ["src/widgets/*"],
|
||||||
|
"app/*": ["src/app/*"]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"include": ["src"]
|
"include": ["src"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,18 @@
|
|||||||
import { defineConfig } from "vite";
|
import { defineConfig } from "vite";
|
||||||
import react from "@vitejs/plugin-react";
|
import react from "@vitejs/plugin-react";
|
||||||
import { federation } from "@module-federation/vite";
|
import { federation } from "@module-federation/vite";
|
||||||
|
import path from "path";
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
shared: path.resolve(__dirname, "src/shared"),
|
||||||
|
entities: path.resolve(__dirname, "src/entities"),
|
||||||
|
features: path.resolve(__dirname, "src/features"),
|
||||||
|
widgets: path.resolve(__dirname, "src/widgets"),
|
||||||
|
app: path.resolve(__dirname, "src/app"),
|
||||||
|
},
|
||||||
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
react({
|
react({
|
||||||
babel: {
|
babel: {
|
||||||
@@ -13,7 +23,12 @@ export default defineConfig({
|
|||||||
name: "auth-react-remote",
|
name: "auth-react-remote",
|
||||||
manifest: true,
|
manifest: true,
|
||||||
filename: "remoteEntry.js",
|
filename: "remoteEntry.js",
|
||||||
exposes: {},
|
exposes: {
|
||||||
|
"./AuthGuard": "./src/features/auth",
|
||||||
|
"./useAuth": "./src/features/auth",
|
||||||
|
"./RegisterForm": "./src/features/auth",
|
||||||
|
"./LoginForm": "./src/features/auth",
|
||||||
|
},
|
||||||
shared: ["react", "react-dom", "zustand"],
|
shared: ["react", "react-dom", "zustand"],
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
|||||||
32
vitest.config.ts
Normal file
32
vitest.config.ts
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import { defineConfig } from "vitest/config";
|
||||||
|
import react from "@vitejs/plugin-react";
|
||||||
|
import path from "path";
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [
|
||||||
|
react({
|
||||||
|
babel: {
|
||||||
|
plugins: [["babel-plugin-react-compiler", {}]],
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
shared: path.resolve(__dirname, "src/shared"),
|
||||||
|
entities: path.resolve(__dirname, "src/entities"),
|
||||||
|
features: path.resolve(__dirname, "src/features"),
|
||||||
|
widgets: path.resolve(__dirname, "src/widgets"),
|
||||||
|
app: path.resolve(__dirname, "src/app"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
test: {
|
||||||
|
globals: true,
|
||||||
|
environment: "jsdom",
|
||||||
|
setupFiles: ["./src/shared/config/test/setup.ts"],
|
||||||
|
coverage: {
|
||||||
|
provider: "v8",
|
||||||
|
reporter: ["text", "json", "html"],
|
||||||
|
exclude: ["node_modules/", "src/test/"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user