create-template-project 1.1.2 → 1.2.0

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 (29) hide show
  1. package/README.md +11 -0
  2. package/dist/config/dependencies.json +15 -15
  3. package/dist/index.js +677 -483
  4. package/dist/templates/base/files/.release-it.json +1 -1
  5. package/dist/templates/base/files/_oxc.config.ts +212 -87
  6. package/dist/templates/cli/files/src/index.ts +1 -2
  7. package/dist/templates/cli/files/src/lib.ts +1 -3
  8. package/dist/templates/web-app/files/playwright.config.ts +7 -4
  9. package/dist/templates/web-app/files/src/App.tsx +11 -12
  10. package/dist/templates/web-app/files/src/index.tsx +1 -1
  11. package/dist/templates/web-app/files/tests/e2e/basic.e2e-test.ts +2 -2
  12. package/dist/templates/web-fullstack/files/client/src/App.tsx +8 -5
  13. package/dist/templates/web-fullstack/files/client/src/components/ProtectedRoute.tsx +5 -3
  14. package/dist/templates/web-fullstack/files/client/src/contexts/AuthContext.tsx +22 -18
  15. package/dist/templates/web-fullstack/files/client/src/main.tsx +8 -5
  16. package/dist/templates/web-fullstack/files/client/src/pages/Dashboard.tsx +12 -7
  17. package/dist/templates/web-fullstack/files/client/src/pages/Login.tsx +11 -7
  18. package/dist/templates/web-fullstack/files/client/src/trpc.ts +2 -1
  19. package/dist/templates/web-fullstack/files/playwright.config.ts +8 -5
  20. package/dist/templates/web-fullstack/files/server/src/context.ts +7 -5
  21. package/dist/templates/web-fullstack/files/server/src/index.ts +2 -3
  22. package/dist/templates/web-fullstack/files/server/src/routers/_app.ts +1 -0
  23. package/dist/templates/web-fullstack/files/server/src/routers/auth.ts +4 -4
  24. package/dist/templates/web-fullstack/files/server/src/trpc.ts +3 -4
  25. package/dist/templates/web-vanilla/files/playwright.config.ts +7 -4
  26. package/dist/templates/web-vanilla/files/src/index.test.ts +1 -1
  27. package/dist/templates/web-vanilla/files/src/index.ts +1 -1
  28. package/dist/templates/web-vanilla/files/src/lib.ts +1 -3
  29. package/package.json +13 -7
@@ -1,10 +1,14 @@
1
- import {useState, FormEvent} from 'react';
1
+ /* eslint-disable react/jsx-max-depth */
2
+ /* eslint-disable import/no-relative-parent-imports */
3
+ /* eslint-disable eslint/no-void */
4
+ /* eslint-disable typescript/no-deprecated */
5
+ import {useState, type ReactNode, type FormEvent} from 'react';
2
6
  import {Button, TextField, Dialog, DialogActions, DialogContent, DialogTitle, Typography, Alert, Box} from '@mui/material';
3
7
  import {useAuth} from '../contexts/AuthContext.js';
4
8
  import {trpc} from '../trpc.js';
5
9
  import {useNavigate} from 'react-router-dom';
6
10
 
7
- export const Login = () => {
11
+ export const Login = (): ReactNode => {
8
12
  const [email, setEmail] = useState('demo@example.com');
9
13
  const [password, setPassword] = useState('password');
10
14
  const [error, setError] = useState<string | null>(null);
@@ -21,7 +25,7 @@ export const Login = () => {
21
25
  },
22
26
  });
23
27
 
24
- const handleSubmit = (e: FormEvent) => {
28
+ const handleSubmit = (e: FormEvent<HTMLFormElement>): void => {
25
29
  e.preventDefault();
26
30
  setError(null);
27
31
  loginMutation.mutate({email, password});
@@ -32,13 +36,13 @@ export const Login = () => {
32
36
  <form onSubmit={handleSubmit}>
33
37
  <DialogTitle>Login</DialogTitle>
34
38
  <DialogContent>
35
- <Box display="flex" flexDirection="column" gap={2} pt={1}>
36
- {error && <Alert severity="error">{error}</Alert>}
39
+ <Box sx={{display: 'flex', flexDirection: 'column', gap: 2, pt: 1}}>
40
+ {error !== null && <Alert severity="error">{error}</Alert>}
37
41
  <Typography variant="body2" color="textSecondary">
38
42
  Use <b>demo@example.com</b> / <b>password</b> to login.
39
43
  </Typography>
40
- <TextField label="Email" type="email" fullWidth required value={email} onChange={(e) => setEmail(e.currentTarget.value)} />
41
- <TextField label="Password" type="password" fullWidth required value={password} onChange={(e) => setPassword(e.currentTarget.value)} />
44
+ <TextField label="Email" type="email" fullWidth required value={email} onChange={(e) => { setEmail(e.currentTarget.value); }} />
45
+ <TextField label="Password" type="password" fullWidth required value={password} onChange={(e) => { setPassword(e.currentTarget.value); }} />
42
46
  </Box>
43
47
  </DialogContent>
44
48
  <DialogActions>
@@ -1,4 +1,5 @@
1
+ /* eslint-disable import/no-relative-parent-imports */
1
2
  import {createTRPCReact} from '@trpc/react-query';
2
- import type {AppRouter} from '../../server/src/routers/_app.js';
3
+ import {type AppRouter} from '../../server/src/routers/_app.js';
3
4
 
4
5
  export const trpc = createTRPCReact<AppRouter>();
@@ -1,12 +1,15 @@
1
1
  import {defineConfig, devices} from '@playwright/test';
2
+ import {env} from 'node:process';
3
+
4
+ const isCi = env.CI !== undefined;
2
5
 
3
6
  export default defineConfig({
4
7
  testDir: './tests/e2e',
5
8
  testMatch: '**/*.e2e-test.ts',
6
9
  fullyParallel: true,
7
- forbidOnly: !!process.env.CI,
8
- retries: process.env.CI ? 2 : 0,
9
- workers: process.env.CI ? 1 : undefined,
10
+ forbidOnly: isCi,
11
+ retries: isCi ? 2 : 0,
12
+ workers: isCi ? 1 : undefined,
10
13
  reporter: 'html',
11
14
  use: {
12
15
  baseURL: 'http://localhost:5173',
@@ -22,12 +25,12 @@ export default defineConfig({
22
25
  {
23
26
  command: 'npm run dev --workspace=server',
24
27
  port: 3000,
25
- reuseExistingServer: !process.env.CI,
28
+ reuseExistingServer: !isCi,
26
29
  },
27
30
  {
28
31
  command: 'npm run dev --workspace=client',
29
32
  port: 5173,
30
- reuseExistingServer: !process.env.CI,
33
+ reuseExistingServer: !isCi,
31
34
  },
32
35
  ],
33
36
  });
@@ -1,17 +1,19 @@
1
- import {CreateExpressContextOptions} from '@trpc/server/adapters/express';
1
+ /* eslint-disable oxc/no-optional-chaining */
2
+ /* eslint-disable typescript/strict-boolean-expressions */
3
+ import {type CreateExpressContextOptions} from '@trpc/server/adapters/express';
2
4
 
3
- interface User {
5
+ type User = {
4
6
  id: string;
5
7
  name: string;
6
8
  email: string;
7
- }
9
+ };
8
10
 
9
- export const createContext = ({req}: CreateExpressContextOptions) => {
11
+ export const createContext = ({req}: CreateExpressContextOptions): {user: User | null} => {
10
12
  const authHeader = req.headers.authorization;
11
13
  let user: User | null = null;
12
14
 
13
15
  if (authHeader?.startsWith('Bearer ')) {
14
- const token = authHeader.split(' ')[1];
16
+ const [, token] = authHeader.split(' ');
15
17
  // Mock token verification
16
18
  if (token === 'mock-token') {
17
19
  user = {id: '1', name: 'Demo User', email: 'demo@example.com'};
@@ -4,11 +4,10 @@ import * as trpcExpress from '@trpc/server/adapters/express';
4
4
  import {appRouter} from './routers/_app.js';
5
5
  import {createContext} from './context.js';
6
6
  import path from 'node:path';
7
- import {fileURLToPath} from 'node:url';
8
7
 
9
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
8
+ const __dirname = import.meta.dirname;
10
9
  const app = express();
11
- const port = process.env['PORT'] || 3001;
10
+ const port = Number(process.env['PORT'] ?? 3001);
12
11
 
13
12
  app.use(cors());
14
13
  app.use(express.json());
@@ -1,3 +1,4 @@
1
+ /* eslint-disable import/no-relative-parent-imports */
1
2
  import {router} from '../trpc.js';
2
3
  import {authRouter} from './auth.js';
3
4
 
@@ -1,3 +1,5 @@
1
+ /* eslint-disable import/no-relative-parent-imports */
2
+ /* eslint-disable typescript/no-deprecated */
1
3
  import {z} from 'zod';
2
4
  import {publicProcedure, protectedProcedure, router} from '../trpc.js';
3
5
  import {TRPCError} from '@trpc/server';
@@ -10,7 +12,7 @@ export const authRouter = router({
10
12
  password: z.string().min(6),
11
13
  }),
12
14
  )
13
- .mutation(async ({input}) => {
15
+ .mutation(({input}) => {
14
16
  // Mock authentication logic
15
17
  if (input.email === 'demo@example.com' && input.password === 'password') {
16
18
  return {
@@ -23,7 +25,5 @@ export const authRouter = router({
23
25
  message: 'Invalid email or password',
24
26
  });
25
27
  }),
26
- me: protectedProcedure.query(({ctx}) => {
27
- return ctx.user;
28
- }),
28
+ me: protectedProcedure.query(({ctx}) => ctx.user),
29
29
  });
@@ -1,11 +1,10 @@
1
+ /* eslint-disable typescript/promise-function-async */
1
2
  import {initTRPC, TRPCError} from '@trpc/server';
2
- import {Context} from './context.js';
3
+ import {type Context} from './context.js';
3
4
 
4
5
  const t = initTRPC.context<Context>().create();
5
6
 
6
- export const router = t.router;
7
- export const createCallerFactory = t.createCallerFactory;
8
- export const publicProcedure = t.procedure;
7
+ export const {router, createCallerFactory, procedure: publicProcedure} = t;
9
8
  export const protectedProcedure = t.procedure.use(({ctx, next}) => {
10
9
  if (!ctx.user) {
11
10
  throw new TRPCError({code: 'UNAUTHORIZED'});
@@ -1,12 +1,15 @@
1
1
  import {defineConfig, devices} from '@playwright/test';
2
+ import {env} from 'node:process';
3
+
4
+ const isCi = env.CI !== undefined;
2
5
 
3
6
  export default defineConfig({
4
7
  testDir: './tests/e2e',
5
8
  testMatch: '**/*.e2e-test.ts',
6
9
  fullyParallel: true,
7
- forbidOnly: !!process.env.CI,
8
- retries: process.env.CI ? 2 : 0,
9
- workers: process.env.CI ? 1 : undefined,
10
+ forbidOnly: isCi,
11
+ retries: isCi ? 2 : 0,
12
+ workers: isCi ? 1 : undefined,
10
13
  reporter: 'html',
11
14
  use: {
12
15
  baseURL: 'http://localhost:5173',
@@ -21,6 +24,6 @@ export default defineConfig({
21
24
  webServer: {
22
25
  command: 'npm run dev',
23
26
  url: 'http://localhost:5173',
24
- reuseExistingServer: !process.env.CI,
27
+ reuseExistingServer: !isCi,
25
28
  },
26
29
  });
@@ -7,6 +7,6 @@ test('formatMessage returns correct string', () => {
7
7
  });
8
8
 
9
9
  test('createHeading renders in the browser', async () => {
10
- document.body.appendChild(createHeading('Browser Test'));
10
+ document.body.append(createHeading('Browser Test'));
11
11
  await expect.element(page.getByRole('heading', {name: 'Browser Test'})).toBeVisible();
12
12
  });
@@ -1,3 +1,3 @@
1
1
  import {createHeading} from './lib.js';
2
2
 
3
- document.body.appendChild(createHeading('Hello from Web-Vanilla!'));
3
+ document.body.append(createHeading('Hello from Web-Vanilla!'));
@@ -4,6 +4,4 @@ export const createHeading = (text: string): HTMLHeadingElement => {
4
4
  return h1;
5
5
  };
6
6
 
7
- export const formatMessage = (name: string): string => {
8
- return `Hello, ${name}!`;
9
- };
7
+ export const formatMessage = (name: string): string => `Hello, ${name}!`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-template-project",
3
- "version": "1.1.2",
3
+ "version": "1.2.0",
4
4
  "private": false,
5
5
  "description": "An ultra-modular, type-safe Node.js CLI tool used to scaffold new project templates (CLI, Webpage, Webapp, Fullstack) with best-practice configurations pre-installed.",
6
6
  "keywords": [
@@ -46,6 +46,11 @@
46
46
  ".": "./dist/index.js",
47
47
  "./package.json": "./package.json"
48
48
  },
49
+ "imports": {
50
+ "#shared/*.js": "./src/shared/*.ts",
51
+ "#templates/*.js": "./src/templates/*.ts",
52
+ "#templating/*.js": "./src/utils/templating/*.ts"
53
+ },
49
54
  "scripts": {
50
55
  "run-interactive": "node ./dist/index.js interactive",
51
56
  "build": "vite build && node scripts/copy-templates.ts",
@@ -77,20 +82,21 @@
77
82
  "@commitlint/config-conventional": "20.5.0",
78
83
  "@types/cli-progress": "3.11.6",
79
84
  "@types/debug": "4.1.13",
80
- "@vitest/coverage-v8": "4.1.2",
85
+ "@types/node": "25.6.0",
86
+ "@vitest/coverage-v8": "4.1.4",
81
87
  "conventional-changelog": "7.2.0",
82
88
  "conventional-changelog-angular": "8.3.1",
83
89
  "eslint-plugin-regexp": "3.1.0",
84
90
  "husky": "9.1.7",
85
- "oxfmt": "0.43.0",
86
- "oxlint": "1.58.0",
87
- "oxlint-tsgolint": "0.19.0",
91
+ "oxfmt": "0.45.0",
92
+ "oxlint": "1.60.0",
93
+ "oxlint-tsgolint": "0.20.0",
88
94
  "pnpm": "10.33.0",
89
95
  "release-it": "19.2.4",
90
96
  "rimraf": "6.1.3",
91
97
  "typescript": "6.0.2",
92
- "vite": "8.0.3",
93
- "vitest": "4.1.2"
98
+ "vite": "8.0.8",
99
+ "vitest": "4.1.4"
94
100
  },
95
101
  "engines": {
96
102
  "node": ">=22"