create-react-forge 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/README.md +88 -61
  2. package/dist/cli/index.js +1 -1
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/cli/parser.js +1 -1
  5. package/dist/cli/parser.js.map +1 -1
  6. package/dist/docs/architecture-generator.js +1 -1
  7. package/dist/generator/index.js +1 -1
  8. package/dist/generator/index.js.map +1 -1
  9. package/package.json +2 -1
  10. package/src/templates/overlays/base/manifest.json +16 -0
  11. package/src/templates/overlays/base/src/components/ui/Button.tsx +66 -0
  12. package/src/templates/overlays/base/src/components/ui/Input.tsx +51 -0
  13. package/src/templates/overlays/base/src/components/ui/index.ts +3 -0
  14. package/src/templates/overlays/base/src/hooks/use-disclosure.ts +21 -0
  15. package/src/templates/overlays/base/src/hooks/use-local-storage.ts +80 -0
  16. package/src/templates/overlays/base/src/lib/api-client.ts +101 -0
  17. package/src/templates/overlays/base/src/lib/utils.ts +34 -0
  18. package/src/templates/overlays/base/src/types/api.ts +47 -0
  19. package/src/templates/overlays/features/tanstack-query/manifest.json +17 -0
  20. package/src/templates/overlays/features/tanstack-query/src/features/users/api/create-user.ts +41 -0
  21. package/src/templates/overlays/features/tanstack-query/src/features/users/api/get-user.ts +27 -0
  22. package/src/templates/overlays/features/tanstack-query/src/features/users/api/get-users.ts +39 -0
  23. package/src/templates/overlays/features/tanstack-query/src/hooks/use-query-config.ts +42 -0
  24. package/src/templates/overlays/features/tanstack-query/src/lib/QueryProvider.tsx +28 -0
  25. package/src/templates/overlays/features/tanstack-query/src/lib/react-query.ts +46 -0
  26. package/src/templates/overlays/runtime/nextjs/manifest.json +27 -0
  27. package/src/templates/overlays/runtime/nextjs/next-env.d.ts +6 -0
  28. package/src/templates/overlays/runtime/nextjs/next.config.js +12 -0
  29. package/src/templates/overlays/runtime/nextjs/src/app/error.tsx +34 -0
  30. package/src/templates/overlays/runtime/nextjs/src/app/layout.tsx +23 -0
  31. package/src/templates/overlays/runtime/nextjs/src/app/loading.tsx +12 -0
  32. package/src/templates/overlays/runtime/nextjs/src/app/not-found.tsx +26 -0
  33. package/src/templates/overlays/runtime/nextjs/src/app/page.tsx +33 -0
  34. package/src/templates/overlays/runtime/nextjs/src/app/providers.tsx +14 -0
  35. package/src/templates/overlays/runtime/nextjs/src/styles/globals.css +50 -0
  36. package/src/templates/overlays/runtime/nextjs/tsconfig.json +29 -0
  37. package/src/templates/overlays/runtime/vite/index.html +14 -0
  38. package/src/templates/overlays/runtime/vite/manifest.json +28 -0
  39. package/src/templates/overlays/runtime/vite/public/vite.svg +2 -0
  40. package/src/templates/overlays/runtime/vite/src/app/App.tsx +11 -0
  41. package/src/templates/overlays/runtime/vite/src/app/provider.tsx +20 -0
  42. package/src/templates/overlays/runtime/vite/src/app/router.tsx +19 -0
  43. package/src/templates/overlays/runtime/vite/src/components/errors/ErrorFallback.tsx +21 -0
  44. package/src/templates/overlays/runtime/vite/src/components/ui/LoadingSpinner.tsx +23 -0
  45. package/src/templates/overlays/runtime/vite/src/features/misc/routes/Landing.tsx +33 -0
  46. package/src/templates/overlays/runtime/vite/src/features/misc/routes/NotFound.tsx +26 -0
  47. package/src/templates/overlays/runtime/vite/src/main.tsx +11 -0
  48. package/src/templates/overlays/runtime/vite/src/styles/globals.css +55 -0
  49. package/src/templates/overlays/runtime/vite/tsconfig.json +32 -0
  50. package/src/templates/overlays/runtime/vite/tsconfig.node.json +23 -0
  51. package/src/templates/overlays/runtime/vite/vite.config.ts +22 -0
  52. package/src/templates/overlays/state/redux/manifest.json +17 -0
  53. package/src/templates/overlays/state/redux/src/stores/Provider.tsx +17 -0
  54. package/src/templates/overlays/state/redux/src/stores/hooks.ts +11 -0
  55. package/src/templates/overlays/state/redux/src/stores/index.ts +17 -0
  56. package/src/templates/overlays/state/redux/src/stores/slices/auth.ts +54 -0
  57. package/src/templates/overlays/state/redux/src/stores/slices/notifications.ts +58 -0
  58. package/src/templates/overlays/state/redux/src/stores/store.ts +27 -0
  59. package/src/templates/overlays/state/zustand/manifest.json +16 -0
  60. package/src/templates/overlays/state/zustand/src/stores/auth.ts +48 -0
  61. package/src/templates/overlays/state/zustand/src/stores/index.ts +3 -0
  62. package/src/templates/overlays/state/zustand/src/stores/notifications.ts +54 -0
  63. package/src/templates/overlays/styling/css-modules/manifest.json +14 -0
  64. package/src/templates/overlays/styling/css-modules/src/components/ui/Button.module.css +87 -0
  65. package/src/templates/overlays/styling/css-modules/src/styles/globals.css +91 -0
  66. package/src/templates/overlays/styling/tailwind/manifest.json +18 -0
  67. package/src/templates/overlays/styling/tailwind/postcss.config.js +7 -0
  68. package/src/templates/overlays/styling/tailwind/src/styles/globals.css +54 -0
  69. package/src/templates/overlays/styling/tailwind/tailwind.config.js +62 -0
  70. package/src/templates/overlays/testing/jest/jest.config.js +24 -0
  71. package/src/templates/overlays/testing/jest/manifest.json +27 -0
  72. package/src/templates/overlays/testing/jest/src/components/ui/__tests__/Button.test.tsx +33 -0
  73. package/src/templates/overlays/testing/jest/src/testing/mocks/browser.ts +17 -0
  74. package/src/templates/overlays/testing/jest/src/testing/mocks/handlers.ts +42 -0
  75. package/src/templates/overlays/testing/jest/src/testing/mocks/server.ts +8 -0
  76. package/src/templates/overlays/testing/jest/src/testing/setup.ts +20 -0
  77. package/src/templates/overlays/testing/jest/src/testing/test-utils.tsx +39 -0
  78. package/src/templates/overlays/testing/playwright/manifest.json +21 -0
  79. package/src/templates/overlays/testing/playwright/playwright.config.ts +53 -0
  80. package/src/templates/overlays/testing/playwright/tests/e2e/accessibility.spec.ts +41 -0
  81. package/src/templates/overlays/testing/playwright/tests/e2e/home.spec.ts +41 -0
  82. package/src/templates/overlays/testing/vitest/manifest.json +28 -0
  83. package/src/templates/overlays/testing/vitest/src/components/ui/__tests__/Button.test.tsx +34 -0
  84. package/src/templates/overlays/testing/vitest/src/testing/mocks/browser.ts +17 -0
  85. package/src/templates/overlays/testing/vitest/src/testing/mocks/handlers.ts +42 -0
  86. package/src/templates/overlays/testing/vitest/src/testing/mocks/server.ts +8 -0
  87. package/src/templates/overlays/testing/vitest/src/testing/setup.ts +21 -0
  88. package/src/templates/overlays/testing/vitest/src/testing/test-utils.tsx +39 -0
  89. package/src/templates/overlays/testing/vitest/vitest.config.ts +31 -0
@@ -0,0 +1,41 @@
1
+ import { test, expect } from '@playwright/test';
2
+
3
+ test.describe('Home Page', () => {
4
+ test.beforeEach(async ({ page }) => {
5
+ await page.goto('/');
6
+ });
7
+
8
+ test('has correct title', async ({ page }) => {
9
+ await expect(page).toHaveTitle(/{{PROJECT_NAME}}/);
10
+ });
11
+
12
+ test('displays welcome message', async ({ page }) => {
13
+ await expect(
14
+ page.getByRole('heading', { name: /welcome/i })
15
+ ).toBeVisible();
16
+ });
17
+
18
+ test('has get started link', async ({ page }) => {
19
+ const getStartedLink = page.getByRole('link', { name: /get started/i });
20
+ await expect(getStartedLink).toBeVisible();
21
+ });
22
+
23
+ test('navigates to dashboard on get started click', async ({ page }) => {
24
+ await page.getByRole('link', { name: /get started/i }).click();
25
+ await expect(page).toHaveURL(/.*dashboard/);
26
+ });
27
+ });
28
+
29
+ test.describe('404 Page', () => {
30
+ test('shows not found for invalid routes', async ({ page }) => {
31
+ await page.goto('/invalid-route-that-does-not-exist');
32
+ await expect(page.getByText(/page not found/i)).toBeVisible();
33
+ });
34
+
35
+ test('has link back to home', async ({ page }) => {
36
+ await page.goto('/invalid-route');
37
+ await page.getByRole('link', { name: /go back home/i }).click();
38
+ await expect(page).toHaveURL('/');
39
+ });
40
+ });
41
+
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "testing-vitest",
3
+ "version": "1.0.0",
4
+ "description": "Vitest unit testing setup with React Testing Library",
5
+ "compatibleWith": ["runtime-vite", "runtime-nextjs"],
6
+ "dependencies": {},
7
+ "devDependencies": {
8
+ "vitest": "^2.0.0",
9
+ "@vitest/ui": "^2.0.0",
10
+ "@vitest/coverage-v8": "^2.0.0",
11
+ "@testing-library/react": "^16.0.0",
12
+ "@testing-library/jest-dom": "^6.4.0",
13
+ "@testing-library/user-event": "^14.5.0",
14
+ "jsdom": "^24.0.0",
15
+ "msw": "^2.4.0"
16
+ },
17
+ "scripts": {
18
+ "test": "vitest run",
19
+ "test:watch": "vitest",
20
+ "test:ui": "vitest --ui",
21
+ "test:coverage": "vitest run --coverage"
22
+ },
23
+ "filePatterns": {
24
+ "include": ["**/*"],
25
+ "exclude": ["manifest.json"]
26
+ }
27
+ }
28
+
@@ -0,0 +1,34 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import { render, screen } from '@/testing/test-utils';
3
+ import { Button } from '../Button';
4
+
5
+ describe('Button', () => {
6
+ it('renders children correctly', () => {
7
+ render(<Button>Click me</Button>);
8
+ expect(screen.getByRole('button', { name: /click me/i })).toBeInTheDocument();
9
+ });
10
+
11
+ it('handles click events', async () => {
12
+ const handleClick = vi.fn();
13
+ const { user } = render(<Button onClick={handleClick}>Click me</Button>);
14
+
15
+ await user.click(screen.getByRole('button'));
16
+ expect(handleClick).toHaveBeenCalledTimes(1);
17
+ });
18
+
19
+ it('shows loading state', () => {
20
+ render(<Button isLoading>Loading</Button>);
21
+ expect(screen.getByRole('button')).toBeDisabled();
22
+ });
23
+
24
+ it('can be disabled', () => {
25
+ render(<Button disabled>Disabled</Button>);
26
+ expect(screen.getByRole('button')).toBeDisabled();
27
+ });
28
+
29
+ it('applies variant styles', () => {
30
+ render(<Button variant="danger">Delete</Button>);
31
+ expect(screen.getByRole('button')).toHaveClass('bg-red-600');
32
+ });
33
+ });
34
+
@@ -0,0 +1,17 @@
1
+ import { setupWorker } from 'msw/browser';
2
+ import { handlers } from './handlers';
3
+
4
+ /**
5
+ * MSW worker for browser environment (development)
6
+ * Import and start in your app entry point for API mocking during development
7
+ *
8
+ * Example:
9
+ * ```ts
10
+ * if (import.meta.env.DEV) {
11
+ * const { worker } = await import('./testing/mocks/browser');
12
+ * await worker.start({ onUnhandledRequest: 'bypass' });
13
+ * }
14
+ * ```
15
+ */
16
+ export const worker = setupWorker(...handlers);
17
+
@@ -0,0 +1,42 @@
1
+ import { http, HttpResponse } from 'msw';
2
+
3
+ /**
4
+ * MSW request handlers for mocking API calls in tests
5
+ * Following bulletproof-react patterns
6
+ */
7
+
8
+ const API_URL = 'http://localhost:3001';
9
+
10
+ export const handlers = [
11
+ // Example: GET /api/users
12
+ http.get(`${API_URL}/api/users`, () => {
13
+ return HttpResponse.json([
14
+ { id: '1', name: 'John Doe', email: 'john@example.com' },
15
+ { id: '2', name: 'Jane Smith', email: 'jane@example.com' },
16
+ ]);
17
+ }),
18
+
19
+ // Example: POST /api/auth/login
20
+ http.post(`${API_URL}/api/auth/login`, async ({ request }) => {
21
+ const body = await request.json() as { email: string; password: string };
22
+
23
+ if (body.email === 'test@example.com' && body.password === 'password') {
24
+ return HttpResponse.json({
25
+ user: {
26
+ id: '1',
27
+ email: 'test@example.com',
28
+ name: 'Test User',
29
+ },
30
+ token: 'mock-jwt-token',
31
+ });
32
+ }
33
+
34
+ return HttpResponse.json(
35
+ { message: 'Invalid credentials' },
36
+ { status: 401 }
37
+ );
38
+ }),
39
+
40
+ // Add more handlers as needed
41
+ ];
42
+
@@ -0,0 +1,8 @@
1
+ import { setupServer } from 'msw/node';
2
+ import { handlers } from './handlers';
3
+
4
+ /**
5
+ * MSW server for Node.js environment (tests)
6
+ */
7
+ export const server = setupServer(...handlers);
8
+
@@ -0,0 +1,21 @@
1
+ import '@testing-library/jest-dom/vitest';
2
+ import { cleanup } from '@testing-library/react';
3
+ import { afterEach, beforeAll, afterAll } from 'vitest';
4
+ import { server } from './mocks/server';
5
+
6
+ // Establish API mocking before all tests
7
+ beforeAll(() => {
8
+ server.listen({ onUnhandledRequest: 'error' });
9
+ });
10
+
11
+ // Clean up after each test
12
+ afterEach(() => {
13
+ cleanup();
14
+ server.resetHandlers();
15
+ });
16
+
17
+ // Clean up after all tests are done
18
+ afterAll(() => {
19
+ server.close();
20
+ });
21
+
@@ -0,0 +1,39 @@
1
+ import { ReactElement, ReactNode } from 'react';
2
+ import { render, RenderOptions } from '@testing-library/react';
3
+ import userEvent from '@testing-library/user-event';
4
+ import { BrowserRouter } from 'react-router-dom';
5
+
6
+ /**
7
+ * Custom render function that includes providers
8
+ * Following bulletproof-react testing patterns
9
+ */
10
+
11
+ type WrapperProps = {
12
+ children: ReactNode;
13
+ };
14
+
15
+ function AllProviders({ children }: WrapperProps) {
16
+ return (
17
+ <BrowserRouter>
18
+ {/* Add other providers here (React Query, Theme, etc.) */}
19
+ {children}
20
+ </BrowserRouter>
21
+ );
22
+ }
23
+
24
+ function customRender(
25
+ ui: ReactElement,
26
+ options?: Omit<RenderOptions, 'wrapper'>
27
+ ) {
28
+ return {
29
+ user: userEvent.setup(),
30
+ ...render(ui, { wrapper: AllProviders, ...options }),
31
+ };
32
+ }
33
+
34
+ // Re-export everything from testing-library
35
+ export * from '@testing-library/react';
36
+
37
+ // Override render method
38
+ export { customRender as render };
39
+
@@ -0,0 +1,31 @@
1
+ import { defineConfig } from 'vitest/config';
2
+ import react from '@vitejs/plugin-react';
3
+ import path from 'path';
4
+
5
+ export default defineConfig({
6
+ plugins: [react()],
7
+ test: {
8
+ globals: true,
9
+ environment: 'jsdom',
10
+ setupFiles: ['./src/testing/setup.ts'],
11
+ include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
12
+ exclude: ['node_modules', 'dist', '.idea', '.git', '.cache'],
13
+ coverage: {
14
+ provider: 'v8',
15
+ reporter: ['text', 'json', 'html'],
16
+ exclude: [
17
+ 'node_modules/',
18
+ 'src/testing/',
19
+ '**/*.d.ts',
20
+ '**/*.config.*',
21
+ '**/index.ts',
22
+ ],
23
+ },
24
+ },
25
+ resolve: {
26
+ alias: {
27
+ '@': path.resolve(__dirname, './src'),
28
+ },
29
+ },
30
+ });
31
+