create-kuckit-app 0.1.1 → 0.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 (92) hide show
  1. package/dist/bin.js +1 -1
  2. package/dist/{create-project-DTm05G7D.js → create-project-CP-h4Ygi.js} +7 -5
  3. package/dist/index.js +1 -1
  4. package/package.json +3 -2
  5. package/templates/base/.claude/CLAUDE.md +44 -0
  6. package/templates/base/.claude/agents/daidalos.md +76 -0
  7. package/templates/base/.claude/agents/episteme.md +79 -0
  8. package/templates/base/.claude/agents/librarian.md +132 -0
  9. package/templates/base/.claude/agents/oracle.md +210 -0
  10. package/templates/base/.claude/commands/create-plan.md +159 -0
  11. package/templates/base/.claude/commands/file-beads.md +98 -0
  12. package/templates/base/.claude/commands/review-beads.md +161 -0
  13. package/templates/base/.claude/settings.json +11 -0
  14. package/templates/base/.claude/skills/kuckit/SKILL.md +436 -0
  15. package/templates/base/.claude/skills/kuckit/references/ARCHITECTURE.md +388 -0
  16. package/templates/base/.claude/skills/kuckit/references/CLI-COMMANDS.md +365 -0
  17. package/templates/base/.claude/skills/kuckit/references/MODULE-DEVELOPMENT.md +581 -0
  18. package/templates/base/.claude/skills/kuckit/references/PACKAGES.md +112 -0
  19. package/templates/base/.claude/skills/kuckit/references/PUBLISHING.md +231 -0
  20. package/templates/base/.env.example +13 -0
  21. package/templates/base/.github/workflows/ci.yml +28 -0
  22. package/templates/base/.husky/pre-commit +1 -0
  23. package/templates/base/.prettierignore +5 -0
  24. package/templates/base/.prettierrc +8 -0
  25. package/templates/base/AGENTS.md +148 -0
  26. package/templates/base/apps/server/.env.example +18 -0
  27. package/templates/base/apps/server/AGENTS.md +37 -0
  28. package/templates/base/apps/server/package.json +13 -2
  29. package/templates/base/apps/server/src/app.ts +20 -0
  30. package/templates/base/apps/server/src/auth.ts +10 -0
  31. package/templates/base/apps/server/src/config/modules.ts +22 -0
  32. package/templates/base/apps/server/src/container.ts +81 -0
  33. package/templates/base/apps/server/src/health.ts +27 -0
  34. package/templates/base/apps/server/src/middleware/container.ts +41 -0
  35. package/templates/base/apps/server/src/rpc-router-registry.ts +26 -0
  36. package/templates/base/apps/server/src/rpc.ts +31 -0
  37. package/templates/base/apps/server/src/server.ts +42 -14
  38. package/templates/base/apps/web/.env.example +4 -0
  39. package/templates/base/apps/web/AGENTS.md +53 -0
  40. package/templates/base/apps/web/index.html +1 -1
  41. package/templates/base/apps/web/package.json +15 -2
  42. package/templates/base/apps/web/src/lib/kuckit-router.ts +42 -0
  43. package/templates/base/apps/web/src/main.tsx +26 -14
  44. package/templates/base/apps/web/src/providers/KuckitProvider.tsx +147 -0
  45. package/templates/base/apps/web/src/providers/ServicesProvider.tsx +47 -0
  46. package/templates/base/apps/web/src/routeTree.gen.ts +91 -0
  47. package/templates/base/apps/web/src/routes/__root.tsx +31 -0
  48. package/templates/base/apps/web/src/routes/index.tsx +46 -0
  49. package/templates/base/apps/web/src/routes/login.tsx +108 -0
  50. package/templates/base/apps/web/src/services/auth-client.ts +12 -0
  51. package/templates/base/apps/web/src/services/index.ts +3 -0
  52. package/templates/base/apps/web/src/services/rpc.ts +29 -0
  53. package/templates/base/apps/web/src/services/types.ts +14 -0
  54. package/templates/base/apps/web/vite.config.ts +2 -1
  55. package/templates/base/docker-compose.yml +23 -0
  56. package/templates/base/eslint.config.js +18 -0
  57. package/templates/base/package.json +32 -2
  58. package/templates/base/packages/api/AGENTS.md +27 -0
  59. package/templates/base/packages/api/package.json +35 -0
  60. package/templates/base/packages/api/src/context.ts +48 -0
  61. package/templates/base/packages/api/src/index.ts +22 -0
  62. package/templates/base/packages/api/tsconfig.json +8 -0
  63. package/templates/base/packages/auth/AGENTS.md +45 -0
  64. package/templates/base/packages/auth/package.json +27 -0
  65. package/templates/base/packages/auth/src/index.ts +22 -0
  66. package/templates/base/packages/auth/tsconfig.json +8 -0
  67. package/templates/base/packages/db/AGENTS.md +59 -0
  68. package/templates/base/packages/db/drizzle.config.ts +19 -0
  69. package/templates/base/packages/db/package.json +36 -0
  70. package/templates/base/packages/db/src/connection.ts +40 -0
  71. package/templates/base/packages/db/src/index.ts +4 -0
  72. package/templates/base/packages/db/src/migrations/0000_init.sql +54 -0
  73. package/templates/base/packages/db/src/migrations/meta/_journal.json +13 -0
  74. package/templates/base/packages/db/src/schema/auth.ts +51 -0
  75. package/templates/base/packages/db/tsconfig.json +8 -0
  76. package/templates/base/packages/items-module/AGENTS.md +112 -0
  77. package/templates/base/packages/items-module/package.json +32 -0
  78. package/templates/base/packages/items-module/src/adapters/item.drizzle.ts +66 -0
  79. package/templates/base/packages/items-module/src/api/items.router.ts +47 -0
  80. package/templates/base/packages/items-module/src/client-module.ts +39 -0
  81. package/templates/base/packages/items-module/src/domain/item.entity.ts +36 -0
  82. package/templates/base/packages/items-module/src/index.ts +15 -0
  83. package/templates/base/packages/items-module/src/module.ts +53 -0
  84. package/templates/base/packages/items-module/src/ports/item.repository.ts +13 -0
  85. package/templates/base/packages/items-module/src/ui/ItemsPage.tsx +162 -0
  86. package/templates/base/packages/items-module/src/usecases/create-item.ts +25 -0
  87. package/templates/base/packages/items-module/src/usecases/delete-item.ts +18 -0
  88. package/templates/base/packages/items-module/src/usecases/get-item.ts +19 -0
  89. package/templates/base/packages/items-module/src/usecases/list-items.ts +21 -0
  90. package/templates/base/packages/items-module/tsconfig.json +9 -0
  91. package/templates/base/turbo.json +13 -1
  92. package/templates/base/apps/web/src/App.tsx +0 -16
@@ -0,0 +1,41 @@
1
+ import type { Express, Request, Response, NextFunction } from 'express'
2
+ import { asValue } from 'awilix'
3
+ import { buildRootContainer, type AppContainer } from '../container'
4
+
5
+ let rootContainer: AppContainer
6
+
7
+ /**
8
+ * Initialize and setup container middleware
9
+ * Must be awaited before using the container
10
+ */
11
+ export const setupContainerMiddleware = async (app: Express): Promise<void> => {
12
+ rootContainer = await buildRootContainer()
13
+
14
+ app.use((req: Request, res: Response, next: NextFunction) => {
15
+ req.scope = rootContainer.createScope()
16
+
17
+ req.scope.register({
18
+ requestId: asValue(crypto.randomUUID()),
19
+ })
20
+
21
+ res.on('finish', () => {
22
+ req.scope?.dispose()
23
+ })
24
+
25
+ res.on('close', () => {
26
+ req.scope?.dispose()
27
+ })
28
+
29
+ next()
30
+ })
31
+ }
32
+
33
+ /**
34
+ * Get root container (for graceful shutdown)
35
+ */
36
+ export const getRootContainer = (): AppContainer => {
37
+ if (!rootContainer) {
38
+ throw new Error('Container not initialized')
39
+ }
40
+ return rootContainer
41
+ }
@@ -0,0 +1,26 @@
1
+ import type { ApiRegistration } from '@kuckit/sdk'
2
+
3
+ /**
4
+ * Central mutable RPC router object used by RPCHandler.
5
+ *
6
+ * Module routers are wired into this object during the SDK loader's
7
+ * "wire" phase, before RPCHandler is instantiated.
8
+ */
9
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
10
+ export const rootRpcRouter: Record<string, any> = {}
11
+
12
+ /**
13
+ * Wire module RPC routers into the central router object.
14
+ * Called from the SDK loader's onApiRegistrations callback.
15
+ */
16
+ export const wireModuleRpcRouters = (registrations: ApiRegistration[]): void => {
17
+ for (const reg of registrations) {
18
+ if (reg.type !== 'rpc-router') continue
19
+
20
+ if (rootRpcRouter[reg.name]) {
21
+ throw new Error(`Duplicate RPC router name: "${reg.name}"`)
22
+ }
23
+
24
+ rootRpcRouter[reg.name] = reg.router
25
+ }
26
+ }
@@ -0,0 +1,31 @@
1
+ import { RPCHandler } from '@orpc/server/node'
2
+ import { onError } from '@orpc/server'
3
+ import { createContext } from '@__APP_NAME_KEBAB__/api'
4
+ import type { Express } from 'express'
5
+ import { rootRpcRouter } from './rpc-router-registry'
6
+
7
+ /**
8
+ * Setup oRPC handler
9
+ *
10
+ * IMPORTANT: This must be called AFTER setupContainerMiddleware() has completed,
11
+ * which ensures all module routers have been wired into rootRpcRouter.
12
+ */
13
+ export const setupRPC = (app: Express) => {
14
+ const rpcHandler = new RPCHandler(rootRpcRouter, {
15
+ interceptors: [
16
+ onError((error) => {
17
+ console.error('[RPC Error]', error)
18
+ }),
19
+ ],
20
+ })
21
+
22
+ app.use(async (req, res, next) => {
23
+ const result = await rpcHandler.handle(req, res, {
24
+ prefix: '/rpc',
25
+ context: await createContext({ req }),
26
+ })
27
+
28
+ if (result.matched) return
29
+ next()
30
+ })
31
+ }
@@ -1,21 +1,49 @@
1
1
  import 'dotenv/config'
2
- import express from 'express'
3
- import cors from 'cors'
2
+ import { createApp } from './app'
3
+ import { setupContainerMiddleware, getRootContainer } from './middleware/container'
4
+ import { setupAuth } from './auth'
5
+ import { setupRPC } from './rpc'
6
+ import { setupHealth } from './health'
7
+ import { disposeContainer } from './container'
4
8
 
5
- const app = express()
6
- const port = process.env.PORT ?? 3000
9
+ /**
10
+ * Bootstrap and start server
11
+ */
12
+ const bootstrap = async () => {
13
+ const app = createApp()
7
14
 
8
- app.use(cors())
9
- app.use(express.json())
15
+ await setupContainerMiddleware(app)
16
+ const rootContainer = getRootContainer()
10
17
 
11
- // Health check
12
- app.get('/health', (_req, res) => {
13
- res.json({ status: 'ok' })
14
- })
18
+ setupAuth(app)
19
+ setupRPC(app)
20
+ setupHealth(app, rootContainer)
21
+
22
+ const port = process.env.PORT || 3000
23
+ const server = app.listen(port, () => {
24
+ console.log(`Server is running on port ${port}`)
25
+ })
26
+
27
+ const shutdown = async () => {
28
+ console.log('Shutting down gracefully...')
29
+
30
+ server.close(async () => {
31
+ await disposeContainer(rootContainer)
32
+ console.log('Server closed')
33
+ process.exit(0)
34
+ })
35
+
36
+ setTimeout(() => {
37
+ console.error('Forced shutdown')
38
+ process.exit(1)
39
+ }, 10000)
40
+ }
15
41
 
16
- // TODO: Kuckit SDK integration will be added in future version
17
- // See: https://kuckit.dev/docs/getting-started
42
+ process.on('SIGTERM', shutdown)
43
+ process.on('SIGINT', shutdown)
44
+ }
18
45
 
19
- app.listen(port, () => {
20
- console.log(`Server running at http://localhost:${port}`)
46
+ bootstrap().catch((error) => {
47
+ console.error('Failed to start server:', error)
48
+ process.exit(1)
21
49
  })
@@ -0,0 +1,4 @@
1
+ # Web Environment Variables
2
+
3
+ # API URL for the backend server
4
+ VITE_API_URL=http://localhost:3000
@@ -0,0 +1,53 @@
1
+ # AGENTS.md - Web App
2
+
3
+ > See root [AGENTS.md](../../AGENTS.md) for project overview
4
+
5
+ ## Purpose
6
+
7
+ React frontend using TanStack Router, TanStack Query, and Kuckit client modules.
8
+
9
+ ## Key Files
10
+
11
+ | File | Purpose |
12
+ | -------------------------------- | --------------------------------- |
13
+ | `main.tsx` | App entry point |
14
+ | `modules.client.ts` | Client module registration |
15
+ | `providers/KuckitProvider.tsx` | Kuckit context setup |
16
+ | `providers/ServicesProvider.tsx` | Services context (RPC, auth) |
17
+ | `routes/` | TanStack Router file-based routes |
18
+
19
+ ## Adding Routes
20
+
21
+ Create files in `src/routes/`:
22
+
23
+ - `src/routes/about.tsx` → `/about`
24
+ - `src/routes/users/$id.tsx` → `/users/:id`
25
+ - `src/routes/settings/index.tsx` → `/settings`
26
+
27
+ ## Using Module UI Components
28
+
29
+ ```tsx
30
+ import { ItemsPage } from '@__APP_NAME_KEBAB__/items-module/ui'
31
+
32
+ // In your route component
33
+ export function Route() {
34
+ return <ItemsPage />
35
+ }
36
+ ```
37
+
38
+ ## Adding Client Modules
39
+
40
+ 1. Import in `modules.client.ts`:
41
+
42
+ ```typescript
43
+ import { kuckitClientModule as myClientModule } from '@__APP_NAME_KEBAB__/my-module/client'
44
+
45
+ export const clientModules = [
46
+ itemsClientModule,
47
+ myClientModule, // Add here
48
+ ]
49
+ ```
50
+
51
+ ## Environment Variables
52
+
53
+ See `.env.example` in this directory.
@@ -6,7 +6,7 @@
6
6
  <title>__APP_NAME__</title>
7
7
  </head>
8
8
  <body>
9
- <div id="root"></div>
9
+ <div id="app"></div>
10
10
  <script type="module" src="/src/main.tsx"></script>
11
11
  </body>
12
12
  </html>
@@ -1,5 +1,7 @@
1
1
  {
2
- "name": "__APP_NAME_KEBAB__-web",
2
+ "name": "@__APP_NAME_KEBAB__/web",
3
+ "version": "0.0.1",
4
+ "private": true,
3
5
  "type": "module",
4
6
  "scripts": {
5
7
  "dev": "vite --port=3001",
@@ -7,11 +9,22 @@
7
9
  "check-types": "tsc --noEmit"
8
10
  },
9
11
  "dependencies": {
12
+ "@kuckit/sdk-react": "^1.0.0",
13
+ "@orpc/client": "^1.10.0",
14
+ "@orpc/tanstack-query": "^1.10.0",
10
15
  "@tanstack/react-query": "^5.85.5",
16
+ "@tanstack/react-router": "^1.114.25",
17
+ "better-auth": "^1.3.28",
11
18
  "react": "^19.1.0",
12
- "react-dom": "^19.1.0"
19
+ "react-dom": "^19.1.0",
20
+ "zod": "^4.1.11",
21
+ "@__APP_NAME_KEBAB__/auth": "workspace:*"
13
22
  },
14
23
  "devDependencies": {
24
+ "@tanstack/react-router-devtools": "^1.114.27",
25
+ "@tanstack/router-plugin": "^1.114.27",
26
+ "@tanstack/react-query-devtools": "^5.85.5",
27
+ "@types/node": "^22.13.13",
15
28
  "@types/react": "~19.1.10",
16
29
  "@types/react-dom": "^19.0.4",
17
30
  "@vitejs/plugin-react": "^4.3.4",
@@ -0,0 +1,42 @@
1
+ import { createRoute, type AnyRoute, type RouteComponent } from '@tanstack/react-router'
2
+ import type { QueryClient } from '@tanstack/react-query'
3
+ import type { RouteRegistry, RouteDefinition } from '@kuckit/sdk-react'
4
+ import type { ORPCUtils } from '../services/types'
5
+
6
+ export interface KuckitRouterContext {
7
+ orpc: ORPCUtils
8
+ queryClient: QueryClient
9
+ }
10
+
11
+ /**
12
+ * Build TanStack Router routes from a RouteRegistry
13
+ */
14
+ export function buildModuleRoutes(routeRegistry: RouteRegistry, rootRoute: AnyRoute): AnyRoute[] {
15
+ const routes = routeRegistry.getAll()
16
+ const routeMap = new Map<string, AnyRoute>()
17
+
18
+ for (const routeDef of routes) {
19
+ const route = createModuleRoute(routeDef, rootRoute)
20
+ routeMap.set(routeDef.id, route)
21
+ }
22
+
23
+ const topLevelRoutes = routes
24
+ .filter((r) => !r.parentRouteId || r.parentRouteId === '__root__')
25
+ .map((r) => routeMap.get(r.id)!)
26
+ .filter(Boolean)
27
+
28
+ return topLevelRoutes
29
+ }
30
+
31
+ function createModuleRoute(routeDef: RouteDefinition, parentRoute: AnyRoute): AnyRoute {
32
+ return createRoute({
33
+ getParentRoute: () => parentRoute,
34
+ path: routeDef.path,
35
+ component: routeDef.component as RouteComponent,
36
+ ...(routeDef.meta?.title && {
37
+ head: () => ({
38
+ meta: [{ title: routeDef.meta!.title }],
39
+ }),
40
+ }),
41
+ })
42
+ }
@@ -1,14 +1,26 @@
1
- import { StrictMode } from 'react'
2
- import { createRoot } from 'react-dom/client'
3
- import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
4
- import { App } from './App.js'
5
-
6
- const queryClient = new QueryClient()
7
-
8
- createRoot(document.getElementById('root')!).render(
9
- <StrictMode>
10
- <QueryClientProvider client={queryClient}>
11
- <App />
12
- </QueryClientProvider>
13
- </StrictMode>
14
- )
1
+ import { createRouter } from '@tanstack/react-router'
2
+ import ReactDOM from 'react-dom/client'
3
+ import { routeTree } from './routeTree.gen'
4
+ import { ServicesProvider } from './providers/ServicesProvider'
5
+ import { KuckitProvider } from './providers/KuckitProvider'
6
+
7
+ declare module '@tanstack/react-router' {
8
+ interface Register {
9
+ router: ReturnType<typeof createRouter<typeof routeTree>>
10
+ }
11
+ }
12
+
13
+ const rootElement = document.getElementById('app')
14
+
15
+ if (!rootElement) {
16
+ throw new Error('Root element not found')
17
+ }
18
+
19
+ if (!rootElement.innerHTML) {
20
+ const root = ReactDOM.createRoot(rootElement)
21
+ root.render(
22
+ <ServicesProvider>
23
+ <KuckitProvider />
24
+ </ServicesProvider>
25
+ )
26
+ }
@@ -0,0 +1,147 @@
1
+ import { createContext, useContext, useEffect, useState, useMemo, type ReactNode } from 'react'
2
+ import {
3
+ RouterProvider,
4
+ createRouter,
5
+ createRoute,
6
+ type RouteComponent,
7
+ } from '@tanstack/react-router'
8
+ import {
9
+ loadKuckitClientModules,
10
+ KuckitNavProvider,
11
+ KuckitSlotProvider,
12
+ KuckitRpcProvider,
13
+ type LoadClientModulesResult,
14
+ type RouteRegistry,
15
+ type NavRegistry,
16
+ type SlotRegistry,
17
+ } from '@kuckit/sdk-react'
18
+ import { routeTree } from '../routeTree.gen'
19
+ import { Route as rootRoute } from '../routes/__root'
20
+ import { useServices } from './ServicesProvider'
21
+ import { getClientModuleSpecs } from '../modules.client'
22
+
23
+ interface KuckitContextValue {
24
+ routeRegistry: RouteRegistry
25
+ navRegistry: NavRegistry
26
+ slotRegistry: SlotRegistry
27
+ isLoaded: boolean
28
+ }
29
+
30
+ const KuckitContext = createContext<KuckitContextValue | null>(null)
31
+
32
+ /**
33
+ * Hook to access Kuckit registries
34
+ */
35
+ export function useKuckit(): KuckitContextValue {
36
+ const ctx = useContext(KuckitContext)
37
+ if (!ctx) {
38
+ throw new Error('useKuckit must be used within a KuckitProvider')
39
+ }
40
+ return ctx
41
+ }
42
+
43
+ interface KuckitProviderProps {
44
+ children?: ReactNode
45
+ }
46
+
47
+ /**
48
+ * KuckitProvider handles module loading and router creation
49
+ */
50
+ export function KuckitProvider({ children }: KuckitProviderProps) {
51
+ const { orpc, queryClient, rpcClient } = useServices()
52
+ const [loadResult, setLoadResult] = useState<LoadClientModulesResult | null>(null)
53
+ const [error, setError] = useState<Error | null>(null)
54
+
55
+ useEffect(() => {
56
+ let cancelled = false
57
+
58
+ const loadModules = async () => {
59
+ try {
60
+ const result = await loadKuckitClientModules({
61
+ orpc,
62
+ queryClient,
63
+ env: import.meta.env.MODE,
64
+ modules: getClientModuleSpecs(),
65
+ })
66
+
67
+ if (!cancelled) {
68
+ setLoadResult(result)
69
+ }
70
+ } catch (err) {
71
+ if (!cancelled) {
72
+ setError(err instanceof Error ? err : new Error(String(err)))
73
+ }
74
+ }
75
+ }
76
+
77
+ loadModules()
78
+
79
+ return () => {
80
+ cancelled = true
81
+ }
82
+ }, [orpc, queryClient])
83
+
84
+ // Build router with module routes
85
+ const router = useMemo(() => {
86
+ if (!loadResult) return null
87
+
88
+ const moduleRouteDefs = loadResult.routeRegistry.getAll()
89
+ const moduleRoutes = moduleRouteDefs.map((routeDef) =>
90
+ createRoute({
91
+ getParentRoute: () => rootRoute,
92
+ path: routeDef.path,
93
+ component: routeDef.component as RouteComponent,
94
+ })
95
+ )
96
+
97
+ if (moduleRoutes.length > 0) {
98
+ console.log(
99
+ `Loaded ${moduleRoutes.length} module routes:`,
100
+ moduleRouteDefs.map((r) => r.path)
101
+ )
102
+ }
103
+
104
+ return createRouter({
105
+ routeTree,
106
+ defaultPreload: 'intent',
107
+ context: { orpc, queryClient },
108
+ })
109
+ }, [loadResult, orpc, queryClient])
110
+
111
+ if (error) {
112
+ return (
113
+ <div style={{ padding: '2rem', color: 'red' }}>
114
+ <h2>Failed to load modules</h2>
115
+ <p>{error.message}</p>
116
+ </div>
117
+ )
118
+ }
119
+
120
+ if (!loadResult || !router) {
121
+ return (
122
+ <div style={{ padding: '2rem' }}>
123
+ <p>Loading...</p>
124
+ </div>
125
+ )
126
+ }
127
+
128
+ const contextValue: KuckitContextValue = {
129
+ routeRegistry: loadResult.routeRegistry,
130
+ navRegistry: loadResult.navRegistry,
131
+ slotRegistry: loadResult.slotRegistry,
132
+ isLoaded: true,
133
+ }
134
+
135
+ return (
136
+ <KuckitContext.Provider value={contextValue}>
137
+ <KuckitRpcProvider client={rpcClient}>
138
+ <KuckitNavProvider registry={loadResult.navRegistry}>
139
+ <KuckitSlotProvider registry={loadResult.slotRegistry}>
140
+ <RouterProvider router={router} />
141
+ {children}
142
+ </KuckitSlotProvider>
143
+ </KuckitNavProvider>
144
+ </KuckitRpcProvider>
145
+ </KuckitContext.Provider>
146
+ )
147
+ }
@@ -0,0 +1,47 @@
1
+ import { createContext, useContext, useMemo, type ReactNode } from 'react'
2
+ import { QueryClientProvider } from '@tanstack/react-query'
3
+ import {
4
+ createQueryClient,
5
+ createRPCLink,
6
+ createRPCClient,
7
+ createORPCUtils,
8
+ createAuthClientService,
9
+ type Services,
10
+ } from '../services'
11
+
12
+ const ServicesContext = createContext<Services | null>(null)
13
+
14
+ interface ServicesProviderProps {
15
+ children: ReactNode
16
+ }
17
+
18
+ export function ServicesProvider({ children }: ServicesProviderProps) {
19
+ const services = useMemo<Services>(() => {
20
+ const queryClient = createQueryClient()
21
+ const link = createRPCLink()
22
+ const rpcClient = createRPCClient(link)
23
+ const orpc = createORPCUtils(rpcClient)
24
+ const authClient = createAuthClientService()
25
+
26
+ return {
27
+ queryClient,
28
+ rpcClient,
29
+ orpc,
30
+ authClient,
31
+ }
32
+ }, [])
33
+
34
+ return (
35
+ <ServicesContext.Provider value={services}>
36
+ <QueryClientProvider client={services.queryClient}>{children}</QueryClientProvider>
37
+ </ServicesContext.Provider>
38
+ )
39
+ }
40
+
41
+ export function useServices(): Services {
42
+ const context = useContext(ServicesContext)
43
+ if (!context) {
44
+ throw new Error('useServices must be used within a ServicesProvider')
45
+ }
46
+ return context
47
+ }
@@ -0,0 +1,91 @@
1
+ /* eslint-disable */
2
+
3
+ // @ts-nocheck
4
+
5
+ // noinspection JSUnusedGlobalSymbols
6
+
7
+ // This file was automatically generated by TanStack Router.
8
+ // You should NOT make any changes in this file as it will be overwritten.
9
+ // Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
10
+
11
+ // Import Routes
12
+
13
+ import { Route as rootRoute } from './routes/__root'
14
+ import { Route as LoginImport } from './routes/login'
15
+ import { Route as IndexImport } from './routes/index'
16
+
17
+ // Create/Update Routes
18
+
19
+ const LoginRoute = LoginImport.update({
20
+ id: '/login',
21
+ path: '/login',
22
+ getParentRoute: () => rootRoute,
23
+ } as any)
24
+
25
+ const IndexRoute = IndexImport.update({
26
+ id: '/',
27
+ path: '/',
28
+ getParentRoute: () => rootRoute,
29
+ } as any)
30
+
31
+ // Populate the FileRoutesByPath interface
32
+
33
+ declare module '@tanstack/react-router' {
34
+ interface FileRoutesByPath {
35
+ '/': {
36
+ id: '/'
37
+ path: '/'
38
+ fullPath: '/'
39
+ preLoaderRoute: typeof IndexImport
40
+ parentRoute: typeof rootRoute
41
+ }
42
+ '/login': {
43
+ id: '/login'
44
+ path: '/login'
45
+ fullPath: '/login'
46
+ preLoaderRoute: typeof LoginImport
47
+ parentRoute: typeof rootRoute
48
+ }
49
+ }
50
+ }
51
+
52
+ // Create and export the route tree
53
+
54
+ export interface FileRoutesByFullPath {
55
+ '/': typeof IndexRoute
56
+ '/login': typeof LoginRoute
57
+ }
58
+
59
+ export interface FileRoutesByTo {
60
+ '/': typeof IndexRoute
61
+ '/login': typeof LoginRoute
62
+ }
63
+
64
+ export interface FileRoutesById {
65
+ __root__: typeof rootRoute
66
+ '/': typeof IndexRoute
67
+ '/login': typeof LoginRoute
68
+ }
69
+
70
+ export interface FileRouteTypes {
71
+ fileRoutesByFullPath: FileRoutesByFullPath
72
+ fullPaths: '/' | '/login'
73
+ fileRoutesByTo: FileRoutesByTo
74
+ to: '/' | '/login'
75
+ id: '__root__' | '/' | '/login'
76
+ fileRoutesById: FileRoutesById
77
+ }
78
+
79
+ export interface RootRouteChildren {
80
+ IndexRoute: typeof IndexRoute
81
+ LoginRoute: typeof LoginRoute
82
+ }
83
+
84
+ const rootRouteChildren: RootRouteChildren = {
85
+ IndexRoute: IndexRoute,
86
+ LoginRoute: LoginRoute,
87
+ }
88
+
89
+ export const routeTree = rootRoute
90
+ ._addFileChildren(rootRouteChildren)
91
+ ._addFileTypes<FileRouteTypes>()
@@ -0,0 +1,31 @@
1
+ import type { QueryClient } from '@tanstack/react-query'
2
+ import { Outlet, createRootRouteWithContext } from '@tanstack/react-router'
3
+ import type { ORPCUtils } from '../services/types'
4
+
5
+ export interface RouterAppContext {
6
+ orpc: ORPCUtils
7
+ queryClient: QueryClient
8
+ }
9
+
10
+ export const Route = createRootRouteWithContext<RouterAppContext>()({
11
+ component: RootComponent,
12
+ head: () => ({
13
+ meta: [
14
+ {
15
+ title: '__APP_NAME__',
16
+ },
17
+ {
18
+ name: 'description',
19
+ content: '__APP_NAME__ - A Kuckit application',
20
+ },
21
+ ],
22
+ }),
23
+ })
24
+
25
+ function RootComponent() {
26
+ return (
27
+ <div style={{ minHeight: '100vh' }}>
28
+ <Outlet />
29
+ </div>
30
+ )
31
+ }