@qlover/create-app 0.7.14 → 0.7.15

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 (31) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/index.cjs +1 -1
  3. package/dist/index.js +1 -1
  4. package/dist/templates/next-app/README.en.md +131 -0
  5. package/dist/templates/next-app/README.md +115 -20
  6. package/dist/templates/next-app/docs/en/api.md +387 -0
  7. package/dist/templates/next-app/docs/en/component.md +544 -0
  8. package/dist/templates/next-app/docs/en/database.md +496 -0
  9. package/dist/templates/next-app/docs/en/development-guide.md +727 -0
  10. package/dist/templates/next-app/docs/en/env.md +563 -0
  11. package/dist/templates/next-app/docs/en/i18n.md +287 -0
  12. package/dist/templates/next-app/docs/en/index.md +166 -0
  13. package/dist/templates/next-app/docs/en/page.md +457 -0
  14. package/dist/templates/next-app/docs/en/project-structure.md +177 -0
  15. package/dist/templates/next-app/docs/en/router.md +427 -0
  16. package/dist/templates/next-app/docs/en/theme.md +532 -0
  17. package/dist/templates/next-app/docs/en/validator.md +478 -0
  18. package/dist/templates/next-app/docs/zh/api.md +387 -0
  19. package/dist/templates/next-app/docs/zh/component.md +544 -0
  20. package/dist/templates/next-app/docs/zh/database.md +496 -0
  21. package/dist/templates/next-app/docs/zh/development-guide.md +727 -0
  22. package/dist/templates/next-app/docs/zh/env.md +563 -0
  23. package/dist/templates/next-app/docs/zh/i18n.md +287 -0
  24. package/dist/templates/next-app/docs/zh/index.md +166 -0
  25. package/dist/templates/next-app/docs/zh/page.md +457 -0
  26. package/dist/templates/next-app/docs/zh/project-structure.md +177 -0
  27. package/dist/templates/next-app/docs/zh/router.md +427 -0
  28. package/dist/templates/next-app/docs/zh/theme.md +532 -0
  29. package/dist/templates/next-app/docs/zh/validator.md +476 -0
  30. package/package.json +1 -1
  31. package/dist/templates/next-app/docs/env.md +0 -94
@@ -0,0 +1,427 @@
1
+ # Router System Development Guide
2
+
3
+ ## Table of Contents
4
+
5
+ 1. [Router System Overview](#router-system-overview)
6
+ 2. [Router Services and Interfaces](#router-services-and-interfaces)
7
+ 3. [Router Middleware and Permissions](#router-middleware-and-permissions)
8
+ 4. [Router Navigation and Hooks](#router-navigation-and-hooks)
9
+ 5. [Best Practices and Examples](#best-practices-and-examples)
10
+
11
+ ## Router System Overview
12
+
13
+ ### 1. Router Architecture
14
+
15
+ The project combines Next.js App Router with custom router services:
16
+
17
+ ```
18
+ Router Layer Service Layer
19
+ ┌──────────────┐ ┌──────────────┐
20
+ │ Page Routes │ │Router Service│
21
+ ├──────────────┤ ├──────────────┤
22
+ │ Middleware │ ◄─────┤ Navigation │
23
+ ├──────────────┤ ├──────────────┤
24
+ │ Auth Control│ │Auth Service │
25
+ └──────────────┘ └──────────────┘
26
+ ```
27
+
28
+ ### 2. Route Types
29
+
30
+ ```typescript
31
+ // 1. Basic route configuration
32
+ export const routes = {
33
+ // Public routes
34
+ home: '/',
35
+ login: '/login',
36
+ register: '/register',
37
+
38
+ // Admin routes
39
+ admin: {
40
+ root: '/admin',
41
+ users: '/admin/users',
42
+ settings: '/admin/settings'
43
+ }
44
+ };
45
+
46
+ // 2. Route metadata
47
+ interface RouteMetadata {
48
+ title: string;
49
+ auth?: boolean;
50
+ roles?: string[];
51
+ }
52
+
53
+ // 3. Route configuration
54
+ const routeMetadata: Record<keyof typeof routes, RouteMetadata> = {
55
+ home: {
56
+ title: 'page.home.title'
57
+ },
58
+ login: {
59
+ title: 'page.login.title'
60
+ },
61
+ admin: {
62
+ title: 'page.admin.title',
63
+ auth: true,
64
+ roles: ['admin']
65
+ }
66
+ };
67
+ ```
68
+
69
+ ## Router Services and Interfaces
70
+
71
+ ### 1. Router Service Interface
72
+
73
+ ```typescript
74
+ // 1. Router interface definition
75
+ export interface RouterInterface {
76
+ // Navigation methods
77
+ navigate(path: string, options?: NavigateOptions): void;
78
+ replace(path: string, options?: NavigateOptions): void;
79
+ back(): void;
80
+
81
+ // Route state
82
+ getCurrentRoute(): string;
83
+ getRouteParams(): Record<string, string>;
84
+
85
+ // Route guards
86
+ beforeEach(guard: NavigationGuard): void;
87
+ afterEach(hook: NavigationHook): void;
88
+ }
89
+
90
+ // 2. Navigation options
91
+ interface NavigateOptions {
92
+ query?: Record<string, string>;
93
+ state?: unknown;
94
+ locale?: string;
95
+ }
96
+
97
+ // 3. Navigation guards
98
+ type NavigationGuard = (to: string, from: string) => boolean | Promise<boolean>;
99
+ type NavigationHook = (to: string, from: string) => void;
100
+ ```
101
+
102
+ ### 2. Router Service Implementation
103
+
104
+ ```typescript
105
+ @injectable()
106
+ export class RouterService implements RouterInterface {
107
+ constructor(
108
+ @inject(I18nService) private i18n: I18nServiceInterface,
109
+ @inject(AuthService) private auth: AuthServiceInterface
110
+ ) {}
111
+
112
+ // Navigate to home
113
+ gotoHome(): void {
114
+ this.navigate(routes.home);
115
+ }
116
+
117
+ // Navigate to login
118
+ gotoLogin(): void {
119
+ this.navigate(routes.login);
120
+ }
121
+
122
+ // Basic navigation method
123
+ navigate(path: string, options?: NavigateOptions): void {
124
+ const locale = options?.locale || this.i18n.currentLocale;
125
+ const localePath = `/${locale}${path}`;
126
+
127
+ if (options?.query) {
128
+ const queryString = new URLSearchParams(options.query).toString();
129
+ window.location.href = `${localePath}?${queryString}`;
130
+ } else {
131
+ window.location.href = localePath;
132
+ }
133
+ }
134
+
135
+ // Get current route
136
+ getCurrentRoute(): string {
137
+ return window.location.pathname.replace(
138
+ new RegExp(`^/${this.i18n.currentLocale}`),
139
+ ''
140
+ );
141
+ }
142
+ }
143
+ ```
144
+
145
+ ## Router Middleware and Permissions
146
+
147
+ ### 1. Router Middleware
148
+
149
+ ```typescript
150
+ // middleware.ts
151
+ import { NextResponse } from 'next/server';
152
+ import type { NextRequest } from 'next/server';
153
+ import { i18nConfig } from '@config/i18n';
154
+
155
+ export async function middleware(request: NextRequest) {
156
+ const { pathname } = request.nextUrl;
157
+
158
+ // 1. Language middleware
159
+ if (!i18nConfig.supportedLngs.some((lng) => pathname.startsWith(`/${lng}`))) {
160
+ return NextResponse.redirect(
161
+ new URL(`/${i18nConfig.defaultLocale}${pathname}`, request.url)
162
+ );
163
+ }
164
+
165
+ // 2. Authentication middleware
166
+ const token = request.cookies.get('token');
167
+ if (pathname.startsWith('/admin') && !token) {
168
+ const locale = pathname.split('/')[1];
169
+ return NextResponse.redirect(new URL(`/${locale}/login`, request.url));
170
+ }
171
+ }
172
+
173
+ // Configure middleware matching paths
174
+ export const config = {
175
+ matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)']
176
+ };
177
+ ```
178
+
179
+ ### 2. Permission Control
180
+
181
+ ```typescript
182
+ // 1. Permission component
183
+ export function PrivateRoute({
184
+ children,
185
+ roles
186
+ }: PropsWithChildren<{ roles?: string[] }>) {
187
+ const auth = useAuth();
188
+ const locale = useLocale();
189
+
190
+ // Check authentication status
191
+ if (!auth.isAuthenticated) {
192
+ return redirect(`/${locale}/login`);
193
+ }
194
+
195
+ // Check role permissions
196
+ if (roles && !roles.some(role => auth.hasRole(role))) {
197
+ return redirect(`/${locale}/403`);
198
+ }
199
+
200
+ return children;
201
+ }
202
+
203
+ // 2. Use in page
204
+ export default function AdminPage() {
205
+ return (
206
+ <PrivateRoute roles={['admin']}>
207
+ <AdminDashboard />
208
+ </PrivateRoute>
209
+ );
210
+ }
211
+ ```
212
+
213
+ ## Router Navigation and Hooks
214
+
215
+ ### 1. Navigation Components
216
+
217
+ ```typescript
218
+ // 1. Localized link component
219
+ export function LocaleLink({
220
+ href,
221
+ locale,
222
+ children,
223
+ ...props
224
+ }: LocaleLinkProps) {
225
+ const currentLocale = useLocale();
226
+ const finalLocale = locale || currentLocale;
227
+
228
+ return (
229
+ <Link href={`/${finalLocale}${href}`} {...props}>
230
+ {children}
231
+ </Link>
232
+ );
233
+ }
234
+
235
+ // 2. Navigation menu
236
+ export function AdminNav() {
237
+ const { navItems } = useStore(adminPageManager);
238
+ const locale = useLocale();
239
+ const t = useTranslations();
240
+
241
+ return (
242
+ <Menu>
243
+ {navItems.map(item => (
244
+ <Menu.Item key={item.key}>
245
+ <LocaleLink href={item.pathname}>
246
+ {t(item.i18nKey)}
247
+ </LocaleLink>
248
+ </Menu.Item>
249
+ ))}
250
+ </Menu>
251
+ );
252
+ }
253
+ ```
254
+
255
+ ### 2. Router Hooks
256
+
257
+ ```typescript
258
+ // 1. Use router hook
259
+ export function useRouteGuard() {
260
+ const router = useRouter();
261
+ const auth = useAuth();
262
+
263
+ useEffect(() => {
264
+ // Check authentication status on route change
265
+ const handleRouteChange = (url: string) => {
266
+ if (url.startsWith('/admin') && !auth.isAuthenticated) {
267
+ router.push('/login');
268
+ }
269
+ };
270
+
271
+ router.events.on('routeChangeStart', handleRouteChange);
272
+ return () => {
273
+ router.events.off('routeChangeStart', handleRouteChange);
274
+ };
275
+ }, [router, auth]);
276
+ }
277
+
278
+ // 2. Use in application
279
+ export function App() {
280
+ useRouteGuard();
281
+
282
+ return (
283
+ <RouterProvider>
284
+ {/* Application content */}
285
+ </RouterProvider>
286
+ );
287
+ }
288
+ ```
289
+
290
+ ## Best Practices and Examples
291
+
292
+ ### 1. Route Organization
293
+
294
+ ```typescript
295
+ // 1. Organize routes by feature
296
+ app /
297
+ [locale] /
298
+ public / // Public route group
299
+ page.tsx; // Homepage
300
+ about /
301
+ page.tsx(
302
+ // About page
303
+ auth
304
+ ) / // Auth route group
305
+ login /
306
+ page.tsx;
307
+ register /
308
+ page.tsx(admin) / // Admin route group
309
+ admin /
310
+ layout.tsx; // Admin layout
311
+ page.tsx; // Admin homepage
312
+ users / page.tsx; // User management
313
+
314
+ // 2. Route constants
315
+ export const ROUTES = {
316
+ PUBLIC: {
317
+ HOME: '/',
318
+ ABOUT: '/about'
319
+ },
320
+ AUTH: {
321
+ LOGIN: '/login',
322
+ REGISTER: '/register'
323
+ },
324
+ ADMIN: {
325
+ ROOT: '/admin',
326
+ USERS: '/admin/users'
327
+ }
328
+ } as const;
329
+ ```
330
+
331
+ ### 2. Type-Safe Routes
332
+
333
+ ```typescript
334
+ // 1. Route type definitions
335
+ type Route = keyof typeof ROUTES;
336
+ type PublicRoute = keyof typeof ROUTES.PUBLIC;
337
+ type AdminRoute = keyof typeof ROUTES.ADMIN;
338
+
339
+ // 2. Type-safe navigation
340
+ function useTypedRouter() {
341
+ const router = useRouter();
342
+ const locale = useLocale();
343
+
344
+ return {
345
+ push: (route: Route) => {
346
+ router.push(`/${locale}${route}`);
347
+ },
348
+ replace: (route: Route) => {
349
+ router.replace(`/${locale}${route}`);
350
+ }
351
+ };
352
+ }
353
+
354
+ // 3. Use type-safe routes
355
+ function Navigation() {
356
+ const router = useTypedRouter();
357
+
358
+ const handleClick = () => {
359
+ router.push(ROUTES.ADMIN.USERS); // Type-safe
360
+ };
361
+ }
362
+ ```
363
+
364
+ ### 3. Route Metadata
365
+
366
+ ```typescript
367
+ // 1. Metadata type
368
+ interface PageMetadata {
369
+ title: string;
370
+ description?: string;
371
+ auth?: boolean;
372
+ roles?: string[];
373
+ }
374
+
375
+ // 2. Route metadata configuration
376
+ const pageMetadata: Record<Route, PageMetadata> = {
377
+ [ROUTES.PUBLIC.HOME]: {
378
+ title: 'page.home.title',
379
+ description: 'page.home.description'
380
+ },
381
+ [ROUTES.ADMIN.ROOT]: {
382
+ title: 'page.admin.title',
383
+ auth: true,
384
+ roles: ['admin']
385
+ }
386
+ };
387
+
388
+ // 3. Generate metadata
389
+ export async function generateMetadata({
390
+ params: { locale }
391
+ }: {
392
+ params: { locale: string };
393
+ }): Promise<Metadata> {
394
+ const t = await getTranslations(locale);
395
+ const route = getCurrentRoute();
396
+ const meta = pageMetadata[route];
397
+
398
+ return {
399
+ title: t(meta.title),
400
+ description: meta.description ? t(meta.description) : undefined
401
+ };
402
+ }
403
+ ```
404
+
405
+ ## Summary
406
+
407
+ The project's router system follows these principles:
408
+
409
+ 1. **Layered Architecture**:
410
+ - Page router layer
411
+ - Service layer
412
+ - Middleware layer
413
+
414
+ 2. **Type Safety**:
415
+ - Route constants
416
+ - Type definitions
417
+ - Compile-time checking
418
+
419
+ 3. **Permission Control**:
420
+ - Route guards
421
+ - Role permissions
422
+ - Middleware interception
423
+
424
+ 4. **Best Practices**:
425
+ - Route organization
426
+ - Type safety
427
+ - Metadata management