create-lumen 1.1.3 → 1.2.0-beta.1
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.
- package/README.md +43 -35
- package/package.json +8 -2
- package/src/configure.js +29 -15
- package/src/css.js +73 -14
- package/src/dependencies.js +8 -3
- package/src/format.js +28 -0
- package/src/injector.js +131 -28
- package/src/main.js +17 -1
- package/src/readme.js +65 -22
- package/templates/architectures/component-based/main.tsx +1 -1
- package/templates/architectures/component-based/src/App.jsx +6 -4
- package/templates/architectures/component-based/src/App.tsx +6 -4
- package/templates/architectures/component-based/src/components/common/Button.jsx +5 -4
- package/templates/architectures/component-based/src/components/common/Button.tsx +5 -4
- package/templates/architectures/component-based/src/hooks/useApp.js +10 -0
- package/templates/architectures/component-based/src/hooks/useApp.ts +10 -0
- package/templates/architectures/component-based/src/hooks/useLocalStorage.ts +5 -5
- package/templates/architectures/component-based/src/layouts/MainLayout.jsx +12 -6
- package/templates/architectures/component-based/src/layouts/MainLayout.tsx +12 -6
- package/templates/architectures/component-based/src/pages/Home/Home.jsx +6 -2
- package/templates/architectures/component-based/src/pages/Home/Home.tsx +6 -2
- package/templates/architectures/component-based/src/providers/AppProvider.jsx +20 -0
- package/templates/architectures/component-based/src/providers/AppProvider.tsx +24 -0
- package/templates/architectures/component-based/src/providers/appcontext.js +3 -0
- package/templates/architectures/component-based/src/providers/appcontext.ts +8 -0
- package/templates/architectures/{feature-based → component-based}/src/types/index.js +7 -0
- package/templates/architectures/{feature-based → component-based}/src/types/index.ts +5 -0
- package/templates/architectures/component-based/src/utils/cn.ts +3 -1
- package/templates/architectures/feature-based/main.jsx +1 -1
- package/templates/architectures/feature-based/main.tsx +2 -2
- package/templates/architectures/feature-based/scripts/create-feature.mjs +2 -2
- package/templates/architectures/feature-based/src/app/App.jsx +15 -5
- package/templates/architectures/feature-based/src/app/App.tsx +15 -5
- package/templates/architectures/feature-based/src/app/contexts/themecontext.js +3 -0
- package/templates/architectures/feature-based/src/app/contexts/themecontext.ts +8 -0
- package/templates/architectures/feature-based/src/app/hooks/useTheme.js +10 -0
- package/templates/architectures/feature-based/src/app/hooks/useTheme.ts +10 -0
- package/templates/architectures/feature-based/src/app/providers/ThemeProvider.jsx +17 -2
- package/templates/architectures/feature-based/src/app/providers/ThemeProvider.tsx +20 -3
- package/templates/architectures/feature-based/src/features/home/pages/HomePage.jsx +18 -5
- package/templates/architectures/feature-based/src/features/home/pages/HomePage.tsx +18 -5
- package/templates/architectures/feature-based/src/shared/components/ui/Button.jsx +31 -0
- package/templates/architectures/feature-based/src/shared/components/ui/Button.tsx +36 -0
- package/templates/architectures/feature-based/src/{hooks → shared/hooks}/useLocalStorage.ts +5 -5
- package/templates/architectures/feature-based/src/shared/layouts/.gitkeep +0 -0
- package/templates/architectures/feature-based/src/shared/stores/.gitkeep +0 -0
- package/templates/architectures/feature-based/src/shared/styles/.gitkeep +0 -0
- package/templates/architectures/feature-based/src/shared/types/index.js +20 -0
- package/templates/architectures/feature-based/src/shared/types/index.ts +16 -0
- package/templates/architectures/feature-based/src/shared/utils/cn.ts +5 -0
- package/templates/conditional/axios/component-based/src/config/axios.config.js +7 -0
- package/templates/conditional/axios/component-based/src/config/axios.config.ts +7 -0
- package/templates/conditional/axios/component-based/src/services/axios.client.js +24 -0
- package/templates/conditional/axios/component-based/src/services/axios.client.ts +24 -0
- package/templates/conditional/axios/component-based/src/services/user.service.js +33 -0
- package/templates/conditional/axios/component-based/src/services/user.service.ts +29 -0
- package/templates/conditional/axios/feature-based/src/features/home/services/user.service.js +33 -0
- package/templates/conditional/axios/feature-based/src/features/home/services/user.service.ts +29 -0
- package/templates/conditional/axios/feature-based/src/shared/lib/axios/api.client.js +24 -0
- package/templates/conditional/axios/feature-based/src/shared/lib/axios/api.client.ts +24 -0
- package/templates/conditional/axios/feature-based/src/shared/lib/axios/api.config.js +7 -0
- package/templates/conditional/axios/feature-based/src/shared/lib/axios/api.config.ts +7 -0
- package/templates/conditional/axios/feature-based/src/shared/lib/axios/index.js +1 -0
- package/templates/conditional/axios/feature-based/src/shared/lib/axios/index.ts +1 -0
- package/templates/conditional/fetch/component-based/src/config/api.config.js +7 -0
- package/templates/conditional/fetch/component-based/src/config/api.config.ts +7 -0
- package/templates/conditional/fetch/component-based/src/services/api.client.js +51 -0
- package/templates/conditional/fetch/component-based/src/services/api.client.ts +55 -0
- package/templates/conditional/fetch/component-based/src/services/user.service.js +33 -0
- package/templates/conditional/fetch/component-based/src/services/user.service.ts +29 -0
- package/templates/conditional/fetch/feature-based/src/features/home/services/user.service.js +33 -0
- package/templates/conditional/fetch/feature-based/src/features/home/services/user.service.ts +29 -0
- package/templates/conditional/fetch/feature-based/src/shared/api/api.client.js +51 -0
- package/templates/conditional/fetch/feature-based/src/shared/api/api.client.ts +55 -0
- package/templates/conditional/fetch/feature-based/src/shared/api/api.config.js +7 -0
- package/templates/conditional/fetch/feature-based/src/shared/api/api.config.ts +7 -0
- package/templates/conditional/fetch/feature-based/src/shared/api/index.js +1 -0
- package/templates/conditional/fetch/feature-based/src/shared/api/index.ts +1 -0
- package/templates/conditional/formatter/oxfmt/.oxfmtrc.json +1 -1
- package/templates/conditional/formatter/prettier/.prettierrc +2 -2
- package/templates/conditional/icons/huge/component-based/bootstrap/src/pages/Home/Home.jsx +20 -0
- package/templates/conditional/icons/huge/component-based/bootstrap/src/pages/Home/Home.tsx +20 -0
- package/templates/conditional/icons/huge/component-based/src/pages/Home/Home.jsx +26 -10
- package/templates/conditional/icons/huge/component-based/src/pages/Home/Home.tsx +26 -10
- package/templates/conditional/icons/huge/component-based/tailwind/src/pages/Home/Home.jsx +20 -0
- package/templates/conditional/icons/huge/component-based/tailwind/src/pages/Home/Home.tsx +20 -0
- package/templates/conditional/icons/huge/feature-based/bootstrap/src/features/home/pages/HomePage.jsx +20 -0
- package/templates/conditional/icons/huge/feature-based/bootstrap/src/features/home/pages/HomePage.tsx +20 -0
- package/templates/conditional/icons/huge/feature-based/src/features/home/pages/HomePage.jsx +27 -11
- package/templates/conditional/icons/huge/feature-based/src/features/home/pages/HomePage.tsx +27 -11
- package/templates/conditional/icons/huge/feature-based/tailwind/src/features/home/pages/HomePage.jsx +20 -0
- package/templates/conditional/icons/huge/feature-based/tailwind/src/features/home/pages/HomePage.tsx +20 -0
- package/templates/conditional/icons/lucide/component-based/bootstrap/src/pages/Home/Home.jsx +19 -0
- package/templates/conditional/icons/lucide/component-based/bootstrap/src/pages/Home/Home.tsx +19 -0
- package/templates/conditional/icons/lucide/component-based/src/pages/Home/Home.jsx +25 -10
- package/templates/conditional/icons/lucide/component-based/src/pages/Home/Home.tsx +25 -10
- package/templates/conditional/icons/lucide/component-based/tailwind/src/pages/Home/Home.jsx +19 -0
- package/templates/conditional/icons/lucide/component-based/tailwind/src/pages/Home/Home.tsx +19 -0
- package/templates/conditional/icons/lucide/feature-based/bootstrap/src/features/home/pages/HomePage.jsx +19 -0
- package/templates/conditional/icons/lucide/feature-based/bootstrap/src/features/home/pages/HomePage.tsx +19 -0
- package/templates/conditional/icons/lucide/feature-based/src/features/home/pages/HomePage.jsx +26 -11
- package/templates/conditional/icons/lucide/feature-based/src/features/home/pages/HomePage.tsx +26 -11
- package/templates/conditional/icons/lucide/feature-based/tailwind/src/features/home/pages/HomePage.jsx +19 -0
- package/templates/conditional/icons/lucide/feature-based/tailwind/src/features/home/pages/HomePage.tsx +19 -0
- package/templates/conditional/linting/eslint/eslint.config.js +24 -2
- package/templates/conditional/linting/eslint/eslint.config.ts +25 -2
- package/templates/conditional/router/component-based/bootstrap/src/layouts/MainLayout.jsx +17 -0
- package/templates/conditional/router/component-based/bootstrap/src/layouts/MainLayout.tsx +17 -0
- package/templates/conditional/router/component-based/src/App.jsx +4 -5
- package/templates/conditional/router/component-based/src/App.tsx +4 -5
- package/templates/conditional/router/component-based/src/layouts/MainLayout.jsx +39 -0
- package/templates/conditional/router/component-based/src/layouts/MainLayout.tsx +39 -0
- package/templates/conditional/router/component-based/src/router/guards/AuthGuard.jsx +8 -0
- package/templates/conditional/router/component-based/src/router/guards/AuthGuard.tsx +14 -0
- package/templates/conditional/router/component-based/src/router/guards/GuestGuard.jsx +8 -0
- package/templates/conditional/router/component-based/src/router/guards/GuestGuard.tsx +14 -0
- package/templates/conditional/router/component-based/src/router/index.jsx +44 -0
- package/templates/conditional/router/component-based/src/router/index.tsx +44 -0
- package/templates/conditional/router/component-based/tailwind/src/layouts/MainLayout.jsx +17 -0
- package/templates/conditional/router/component-based/tailwind/src/layouts/MainLayout.tsx +17 -0
- package/templates/conditional/router/feature-based/bootstrap/src/shared/layouts/RootLayout.jsx +9 -0
- package/templates/conditional/router/feature-based/bootstrap/src/shared/layouts/RootLayout.tsx +9 -0
- package/templates/conditional/router/feature-based/src/app/App.jsx +6 -2
- package/templates/conditional/router/feature-based/src/app/App.tsx +6 -2
- package/templates/conditional/router/feature-based/src/app/router/guards/AuthGuard.jsx +8 -0
- package/templates/conditional/router/feature-based/src/app/router/guards/AuthGuard.tsx +14 -0
- package/templates/conditional/router/feature-based/src/app/router/guards/RoleGuard.jsx +8 -0
- package/templates/conditional/router/feature-based/src/app/router/guards/RoleGuard.tsx +15 -0
- package/templates/conditional/router/feature-based/src/app/router/index.jsx +16 -0
- package/templates/conditional/router/feature-based/src/app/router/index.tsx +16 -0
- package/templates/conditional/router/feature-based/src/app/router/routes/auth.routes.jsx +18 -0
- package/templates/conditional/router/feature-based/src/app/router/routes/auth.routes.tsx +18 -0
- package/templates/conditional/router/feature-based/src/app/router/routes/home.routes.jsx +8 -0
- package/templates/conditional/router/feature-based/src/app/router/routes/home.routes.tsx +8 -0
- package/templates/conditional/router/feature-based/src/shared/layouts/RootLayout.jsx +17 -0
- package/templates/conditional/router/feature-based/src/shared/layouts/RootLayout.tsx +17 -0
- package/templates/conditional/router/feature-based/tailwind/src/shared/layouts/RootLayout.jsx +9 -0
- package/templates/conditional/router/feature-based/tailwind/src/shared/layouts/RootLayout.tsx +9 -0
- package/templates/conditional/state/redux/component-based/src/pages/Home/counterSlice.ts +9 -3
- package/templates/conditional/state/redux/component-based/src/{context → providers}/StoreProvider.jsx +0 -1
- package/templates/conditional/state/redux/component-based/src/{context → providers}/StoreProvider.tsx +2 -2
- package/templates/conditional/state/redux/component-based/src/store/hooks.ts +4 -2
- package/templates/conditional/state/redux/component-based/src/store/index.ts +2 -2
- package/templates/conditional/state/redux/feature-based/src/app/providers/StoreProvider.jsx +1 -2
- package/templates/conditional/state/redux/feature-based/src/app/providers/StoreProvider.tsx +3 -3
- package/templates/conditional/state/redux/feature-based/src/features/home/store/counterSlice.ts +9 -3
- package/templates/conditional/state/redux/feature-based/src/shared/stores/hooks.ts +6 -0
- package/templates/conditional/state/redux/feature-based/src/{stores → shared/stores}/index.ts +2 -2
- package/templates/conditional/state/zustand/component-based/src/store/useCounterStore.ts +8 -1
- package/templates/conditional/state/zustand/feature-based/src/stores/useCounterStore.ts +8 -1
- package/templates/conditional/testing/jest/babel.config.cjs +7 -0
- package/templates/conditional/testing/jest/component-based/src/__tests__/App.test.jsx +10 -0
- package/templates/conditional/testing/jest/component-based/src/__tests__/App.test.tsx +11 -0
- package/templates/conditional/testing/jest/{src → feature-based/src}/__tests__/App.test.jsx +2 -1
- package/templates/conditional/testing/jest/feature-based/src/__tests__/App.test.tsx +11 -0
- package/templates/conditional/testing/jest/jest.config.js +2 -3
- package/templates/conditional/testing/jest/jest.config.ts +6 -4
- package/templates/conditional/testing/jest/jest.setup.js +6 -0
- package/templates/conditional/testing/jest/jest.setup.ts +6 -0
- package/templates/conditional/testing/vitest/component-based/src/__tests__/App.test.jsx +10 -0
- package/templates/conditional/testing/{jest → vitest/component-based}/src/__tests__/App.test.tsx +2 -1
- package/templates/css/bootstrap/src/themes.css +14 -0
- package/templates/css/component-styles/bootstrap/component-based/src/components/common/Button.jsx +17 -0
- package/templates/css/component-styles/bootstrap/component-based/src/components/common/Button.tsx +22 -0
- package/templates/css/component-styles/bootstrap/component-based/src/layouts/MainLayout.jsx +15 -0
- package/templates/css/component-styles/bootstrap/component-based/src/layouts/MainLayout.tsx +19 -0
- package/templates/css/component-styles/bootstrap/component-based/src/pages/Home/Home.jsx +13 -0
- package/templates/css/component-styles/bootstrap/component-based/src/pages/Home/Home.tsx +13 -0
- package/templates/css/component-styles/bootstrap/feature-based/src/app/App.jsx +9 -0
- package/templates/css/component-styles/bootstrap/feature-based/src/app/App.tsx +9 -0
- package/templates/css/component-styles/bootstrap/feature-based/src/features/home/pages/HomePage.jsx +13 -0
- package/templates/css/component-styles/bootstrap/feature-based/src/features/home/pages/HomePage.tsx +13 -0
- package/templates/css/component-styles/bootstrap/feature-based/src/shared/components/ui/Button.jsx +17 -0
- package/templates/css/component-styles/bootstrap/feature-based/src/shared/components/ui/Button.tsx +22 -0
- package/templates/{architectures/feature-based/src/components/ui → css/component-styles/tailwind/component-based/src/components/common}/Button.jsx +1 -3
- package/templates/{architectures/feature-based/src/components/ui → css/component-styles/tailwind/component-based/src/components/common}/Button.tsx +1 -3
- package/templates/css/component-styles/tailwind/component-based/src/layouts/MainLayout.jsx +15 -0
- package/templates/css/component-styles/tailwind/component-based/src/layouts/MainLayout.tsx +19 -0
- package/templates/css/component-styles/tailwind/component-based/src/pages/Home/Home.jsx +13 -0
- package/templates/css/component-styles/tailwind/component-based/src/pages/Home/Home.tsx +13 -0
- package/templates/css/component-styles/tailwind/feature-based/src/app/App.jsx +9 -0
- package/templates/css/component-styles/tailwind/feature-based/src/app/App.tsx +9 -0
- package/templates/css/component-styles/tailwind/feature-based/src/features/home/pages/HomePage.jsx +13 -0
- package/templates/css/component-styles/tailwind/feature-based/src/features/home/pages/HomePage.tsx +13 -0
- package/templates/css/component-styles/tailwind/feature-based/src/shared/components/ui/Button.jsx +21 -0
- package/templates/css/component-styles/tailwind/feature-based/src/shared/components/ui/Button.tsx +26 -0
- package/templates/css/none/src/{index.css → main.css} +2 -0
- package/templates/css/none/src/themes.css +19 -0
- package/templates/css/tailwind/src/themes.css +9 -0
- package/templates/architectures/component-based/src/config/constants.js +0 -2
- package/templates/architectures/component-based/src/config/constants.ts +0 -2
- package/templates/architectures/component-based/src/config/routes.js +0 -7
- package/templates/architectures/component-based/src/config/routes.ts +0 -7
- package/templates/architectures/component-based/src/context/AppContext.jsx +0 -13
- package/templates/architectures/component-based/src/context/AppContext.tsx +0 -13
- package/templates/architectures/component-based/src/hooks/index.js +0 -1
- package/templates/architectures/component-based/src/hooks/index.ts +0 -1
- package/templates/architectures/component-based/src/layouts/index.js +0 -1
- package/templates/architectures/component-based/src/layouts/index.ts +0 -1
- package/templates/architectures/component-based/src/routes/index.jsx +0 -11
- package/templates/architectures/component-based/src/routes/index.tsx +0 -11
- package/templates/architectures/component-based/src/styles/globals.css +0 -7
- package/templates/architectures/component-based/src/utils/index.js +0 -1
- package/templates/architectures/component-based/src/utils/index.ts +0 -1
- package/templates/architectures/feature-based/src/config/constants.js +0 -2
- package/templates/architectures/feature-based/src/config/constants.ts +0 -2
- package/templates/architectures/feature-based/src/hooks/index.js +0 -1
- package/templates/architectures/feature-based/src/hooks/index.ts +0 -1
- package/templates/architectures/feature-based/src/utils/cn.ts +0 -6
- package/templates/architectures/feature-based/src/utils/index.js +0 -1
- package/templates/architectures/feature-based/src/utils/index.ts +0 -1
- package/templates/conditional/axios/component-based/src/services/axios.jsx +0 -19
- package/templates/conditional/axios/component-based/src/services/axios.ts +0 -19
- package/templates/conditional/axios/component-based/src/services/index.js +0 -1
- package/templates/conditional/axios/component-based/src/services/index.ts +0 -1
- package/templates/conditional/axios/feature-based/src/lib/axios.jsx +0 -19
- package/templates/conditional/axios/feature-based/src/lib/axios.ts +0 -19
- package/templates/conditional/axios/feature-based/src/lib/index.js +0 -1
- package/templates/conditional/axios/feature-based/src/lib/index.ts +0 -1
- package/templates/conditional/fetch/component-based/src/services/api.jsx +0 -27
- package/templates/conditional/fetch/component-based/src/services/api.ts +0 -27
- package/templates/conditional/fetch/component-based/src/services/index.js +0 -1
- package/templates/conditional/fetch/component-based/src/services/index.ts +0 -1
- package/templates/conditional/fetch/feature-based/src/lib/api.jsx +0 -27
- package/templates/conditional/fetch/feature-based/src/lib/api.ts +0 -27
- package/templates/conditional/fetch/feature-based/src/lib/index.js +0 -1
- package/templates/conditional/fetch/feature-based/src/lib/index.ts +0 -1
- package/templates/conditional/router/component-based/src/routes/index.jsx +0 -13
- package/templates/conditional/router/component-based/src/routes/index.tsx +0 -13
- package/templates/conditional/router/feature-based/src/app/router.jsx +0 -13
- package/templates/conditional/router/feature-based/src/app/router.tsx +0 -13
- package/templates/conditional/state/redux/feature-based/src/stores/hooks.ts +0 -4
- package/templates/css/tailwind/src/index.css +0 -1
- /package/templates/architectures/component-based/src/{components/layout → config}/.gitkeep +0 -0
- /package/templates/architectures/{feature-based/src/features/home/interfaces → component-based/src/providers}/.gitkeep +0 -0
- /package/templates/architectures/{feature-based/src/lib → component-based/src/styles}/.gitkeep +0 -0
- /package/templates/architectures/feature-based/src/{stores → features/home/types}/.gitkeep +0 -0
- /package/templates/architectures/feature-based/src/{components → shared/components}/ui/index.js +0 -0
- /package/templates/architectures/feature-based/src/{components → shared/components}/ui/index.ts +0 -0
- /package/templates/architectures/feature-based/src/{hooks → shared/hooks}/useLocalStorage.jsx +0 -0
- /package/templates/architectures/feature-based/src/{utils → shared/utils}/cn.jsx +0 -0
- /package/templates/conditional/state/redux/feature-based/src/{stores → shared/stores}/hooks.js +0 -0
- /package/templates/conditional/state/redux/feature-based/src/{stores → shared/stores}/index.js +0 -0
- /package/templates/conditional/testing/vitest/{src → feature-based/src}/__tests__/App.test.jsx +0 -0
- /package/templates/conditional/testing/vitest/{src → feature-based/src}/__tests__/App.test.tsx +0 -0
- /package/templates/css/bootstrap/src/{index.css → globals.css} +0 -0
- /package/templates/{architectures/feature-based/src/styles → css/tailwind/src}/globals.css +0 -0
package/README.md
CHANGED
|
@@ -17,9 +17,9 @@ npm run dev
|
|
|
17
17
|
Non-interactive Quick Setup (TypeScript + Tailwind + Feature-based + Router + ESLint + Prettier + Vitest), no prompts:
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
|
-
npm create lumen my-app -y
|
|
20
|
+
npm create lumen my-app -- -y
|
|
21
21
|
# or
|
|
22
|
-
npm create lumen -y my-app
|
|
22
|
+
npm create lumen -- -y my-app
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
The CLI ignores flag arguments when resolving the project name, so `-y` can appear before or after the app name without being mistaken for the folder name.
|
|
@@ -87,36 +87,40 @@ Feature-based (example):
|
|
|
87
87
|
|
|
88
88
|
```
|
|
89
89
|
src/
|
|
90
|
-
├── app
|
|
90
|
+
├── app # App shell and global providers
|
|
91
91
|
│ ├── App.tsx
|
|
92
|
+
│ ├── contexts
|
|
93
|
+
│ │ └── themecontext.ts # createContext + ThemeContextValue
|
|
92
94
|
│ ├── providers
|
|
93
|
-
│ │ └── ThemeProvider.tsx
|
|
94
|
-
│
|
|
95
|
-
|
|
96
|
-
│ └──
|
|
97
|
-
├──
|
|
98
|
-
│
|
|
99
|
-
|
|
100
|
-
|
|
95
|
+
│ │ └── ThemeProvider.tsx # Provider component
|
|
96
|
+
│ ├── hooks
|
|
97
|
+
│ │ └── useTheme.ts # Hook that reads ThemeContext
|
|
98
|
+
│ └── router # Data router (per feature area)
|
|
99
|
+
│ ├── guards # AuthGuard, RoleGuard
|
|
100
|
+
│ ├── routes # home.routes, auth.routes
|
|
101
|
+
│ └── index.tsx # createBrowserRouter init
|
|
102
|
+
├── features # Feature modules (business logic owned per feature)
|
|
103
|
+
│ └── home
|
|
101
104
|
│ ├── components
|
|
102
|
-
│ ├──
|
|
105
|
+
│ ├── hooks
|
|
106
|
+
│ ├── index.ts # public feature barrel
|
|
103
107
|
│ ├── layouts
|
|
104
108
|
│ ├── pages
|
|
105
109
|
│ ├── services
|
|
106
|
-
│
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
├──
|
|
111
|
-
|
|
112
|
-
├──
|
|
113
|
-
├──
|
|
114
|
-
├──
|
|
115
|
-
|
|
116
|
-
├──
|
|
117
|
-
│ └──
|
|
118
|
-
├── types
|
|
119
|
-
└── utils
|
|
110
|
+
│ ├── store
|
|
111
|
+
│ └── types
|
|
112
|
+
└── shared # Reusable, business-agnostic resources
|
|
113
|
+
├── api/lib # fetch client → api/; axios init → lib/axios/ (per choice)
|
|
114
|
+
├── components
|
|
115
|
+
│ └── ui
|
|
116
|
+
├── hooks
|
|
117
|
+
├── layouts
|
|
118
|
+
├── stores
|
|
119
|
+
├── styles
|
|
120
|
+
│ ├── globals.css # Tailwind/Bootstrap directives (or main.css for vanilla)
|
|
121
|
+
│ └── themes.css # Theme tokens (Tailwind @theme / Bootstrap data-bs-theme / CSS vars)
|
|
122
|
+
├── types
|
|
123
|
+
└── utils
|
|
120
124
|
```
|
|
121
125
|
|
|
122
126
|
Component-based (example):
|
|
@@ -126,28 +130,32 @@ src/
|
|
|
126
130
|
├── App.tsx
|
|
127
131
|
├── components
|
|
128
132
|
│ ├── common
|
|
129
|
-
│
|
|
130
|
-
|
|
131
|
-
├── config
|
|
132
|
-
│ ├── constants.ts
|
|
133
|
-
│ └── routes.ts
|
|
134
|
-
├── context
|
|
133
|
+
│ └── form
|
|
134
|
+
├── config # API config (when an axios/fetch client is chosen)
|
|
135
135
|
├── hooks
|
|
136
|
-
├── index.css
|
|
137
136
|
├── layouts
|
|
138
137
|
├── main.tsx
|
|
139
138
|
├── pages
|
|
140
|
-
├──
|
|
139
|
+
├── providers # Provider components (createContext + Provider in separate files inside providers/)
|
|
140
|
+
│ ├── appcontext.ts # createContext + AppContextValue
|
|
141
|
+
│ └── AppProvider.tsx # Provider component
|
|
142
|
+
├── hooks
|
|
143
|
+
│ └── useApp.ts # Hook that reads AppContext
|
|
144
|
+
├── router # Centralized data router
|
|
145
|
+
│ ├── guards # AuthGuard, GuestGuard
|
|
146
|
+
│ └── index.tsx # Single source of truth for all routes
|
|
141
147
|
├── services
|
|
142
148
|
├── store
|
|
143
149
|
├── styles
|
|
150
|
+
│ ├── globals.css # Tailwind/Bootstrap directives (or main.css for vanilla)
|
|
151
|
+
│ └── themes.css # Theme tokens (Tailwind @theme / Bootstrap data-bs-theme / CSS vars)
|
|
144
152
|
├── test
|
|
145
153
|
└── utils
|
|
146
154
|
```
|
|
147
155
|
|
|
148
156
|
## Roadmap
|
|
149
157
|
|
|
150
|
-
|
|
158
|
+
Released versions live in [`docs/CHANGELOG.md`](./docs/CHANGELOG.md); planned work is tracked in [`docs/ROADMAP.md`](./docs/ROADMAP.md).
|
|
151
159
|
|
|
152
160
|
## Requirements
|
|
153
161
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-lumen",
|
|
3
|
-
"version": "1.1
|
|
3
|
+
"version": "1.2.0-beta.1",
|
|
4
4
|
"description": "Scaffold a React + Vite project with architecture choice: feature-based or component-based.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -15,7 +15,13 @@
|
|
|
15
15
|
"LICENSE"
|
|
16
16
|
],
|
|
17
17
|
"scripts": {
|
|
18
|
-
"test": "node --import ./register.js --test \"tests/unit/*.test.mjs\" \"tests/smoke/*.test.mjs\""
|
|
18
|
+
"test": "node --import ./register.js --test \"tests/unit/*.test.mjs\" \"tests/smoke/*.test.mjs\"",
|
|
19
|
+
"verify:vendor": "node --import ./register.js tests/verify/install-vendor.mjs",
|
|
20
|
+
"verify:offline": "node --import ./register.js tests/verify/verify-offline.mjs",
|
|
21
|
+
"verify:installed": "node --import ./register.js tests/verify/verify-installed.mjs",
|
|
22
|
+
"verify": "npm run verify:vendor && npm run verify:offline",
|
|
23
|
+
"verify:full": "npm run verify:vendor && npm run verify:offline && npm run verify:installed",
|
|
24
|
+
"verify:matrix": "FULL=1 npm run verify:offline"
|
|
19
25
|
},
|
|
20
26
|
"keywords": [
|
|
21
27
|
"scaffold",
|
package/src/configure.js
CHANGED
|
@@ -19,7 +19,7 @@ export async function configureProject(projectPath, language, cssFramework) {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
// Add scripts to package.json
|
|
22
|
-
await configurePackageJson(projectPath);
|
|
22
|
+
await configurePackageJson(projectPath, language);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
async function configureTsconfig(projectPath) {
|
|
@@ -31,8 +31,13 @@ async function configureTsconfig(projectPath) {
|
|
|
31
31
|
const config = JSON.parse(content);
|
|
32
32
|
|
|
33
33
|
if (!config.compilerOptions) config.compilerOptions = {};
|
|
34
|
-
config.compilerOptions.
|
|
34
|
+
config.compilerOptions.strict = true;
|
|
35
35
|
config.compilerOptions.paths = paths;
|
|
36
|
+
if (config.compilerOptions.types?.length && !config.compilerOptions.types.includes("vite/client")) {
|
|
37
|
+
config.compilerOptions.types.push("vite/client");
|
|
38
|
+
} else if (!config.compilerOptions.types) {
|
|
39
|
+
config.compilerOptions.types = ["vite/client"];
|
|
40
|
+
}
|
|
36
41
|
|
|
37
42
|
await fsp.writeFile(
|
|
38
43
|
tsconfigAppPath,
|
|
@@ -58,7 +63,7 @@ async function configureTsconfig(projectPath) {
|
|
|
58
63
|
noUnusedLocals: true,
|
|
59
64
|
noUnusedParameters: true,
|
|
60
65
|
noFallthroughCasesInSwitch: true,
|
|
61
|
-
|
|
66
|
+
types: ["vite/client"],
|
|
62
67
|
paths,
|
|
63
68
|
},
|
|
64
69
|
include: ["src"],
|
|
@@ -70,11 +75,19 @@ async function configureTsconfig(projectPath) {
|
|
|
70
75
|
);
|
|
71
76
|
}
|
|
72
77
|
|
|
73
|
-
// Create/update root tsconfig.json with references
|
|
78
|
+
// Create/update root tsconfig.json with references.
|
|
79
|
+
// Preserve the ./tsconfig.node.json reference (Vite config) when present.
|
|
74
80
|
const rootTsconfigPath = path.join(projectPath, "tsconfig.json");
|
|
81
|
+
const nodeConfigPath = path.join(projectPath, "tsconfig.node.json");
|
|
82
|
+
const references = [{ path: "./tsconfig.app.json" }];
|
|
83
|
+
try {
|
|
84
|
+
await fsp.access(nodeConfigPath);
|
|
85
|
+
references.push({ path: "./tsconfig.node.json" });
|
|
86
|
+
} catch {}
|
|
87
|
+
|
|
75
88
|
const rootTsconfig = {
|
|
76
89
|
files: [],
|
|
77
|
-
references
|
|
90
|
+
references,
|
|
78
91
|
};
|
|
79
92
|
await fsp.writeFile(
|
|
80
93
|
rootTsconfigPath,
|
|
@@ -100,7 +113,7 @@ async function addPathAliasesToViteConfig(projectPath, ext) {
|
|
|
100
113
|
try {
|
|
101
114
|
let content = await readFileContent(viteConfigPath);
|
|
102
115
|
|
|
103
|
-
if (content.includes("
|
|
116
|
+
if (content.includes("find: '@'")) return;
|
|
104
117
|
|
|
105
118
|
const lines = content.split("\n");
|
|
106
119
|
|
|
@@ -112,8 +125,8 @@ async function addPathAliasesToViteConfig(projectPath, ext) {
|
|
|
112
125
|
|
|
113
126
|
// Insert path/fileURLToPath imports after last import
|
|
114
127
|
const newImports = [
|
|
115
|
-
|
|
116
|
-
|
|
128
|
+
"import path from 'path';",
|
|
129
|
+
"import { fileURLToPath } from 'url';",
|
|
117
130
|
"const __dirname = path.dirname(fileURLToPath(import.meta.url));",
|
|
118
131
|
];
|
|
119
132
|
lines.splice(lastImportIdx + 1, 0, ...newImports);
|
|
@@ -121,13 +134,10 @@ async function addPathAliasesToViteConfig(projectPath, ext) {
|
|
|
121
134
|
let result = lines.join("\n");
|
|
122
135
|
|
|
123
136
|
const aliasArray = getViteAliases()
|
|
124
|
-
.map(
|
|
125
|
-
|
|
126
|
-
`{ find: "${a.find}", replacement: ${a.replacement} }`
|
|
127
|
-
)
|
|
128
|
-
.join(",\n ");
|
|
137
|
+
.map((a) => `{ find: '${a.find}', replacement: ${a.replacement} }`)
|
|
138
|
+
.join(",\n ");
|
|
129
139
|
|
|
130
|
-
const resolveBlock = `resolve: {\n
|
|
140
|
+
const resolveBlock = `resolve: {\n alias: [\n ${aliasArray},\n ],\n }`;
|
|
131
141
|
|
|
132
142
|
if (result.includes("resolve:")) {
|
|
133
143
|
result = result.replace(/resolve:\s*\{/, resolveBlock);
|
|
@@ -144,7 +154,7 @@ async function addPathAliasesToViteConfig(projectPath, ext) {
|
|
|
144
154
|
}
|
|
145
155
|
}
|
|
146
156
|
|
|
147
|
-
async function configurePackageJson(projectPath) {
|
|
157
|
+
async function configurePackageJson(projectPath, language) {
|
|
148
158
|
const pkgPath = path.join(projectPath, "package.json");
|
|
149
159
|
try {
|
|
150
160
|
const content = await readFileContent(pkgPath);
|
|
@@ -156,6 +166,10 @@ async function configurePackageJson(projectPath) {
|
|
|
156
166
|
pkg.scripts.build = "vite build";
|
|
157
167
|
pkg.scripts.preview = "vite preview";
|
|
158
168
|
|
|
169
|
+
if (language === "ts") {
|
|
170
|
+
pkg.scripts.typecheck = "tsc -b";
|
|
171
|
+
}
|
|
172
|
+
|
|
159
173
|
await fsp.writeFile(pkgPath, JSON.stringify(pkg, null, 2) + "\n", "utf8");
|
|
160
174
|
} catch {
|
|
161
175
|
// file doesn't exist, skip
|
package/src/css.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import fs from "fs";
|
|
2
1
|
import { promises as fsp } from "fs";
|
|
3
2
|
import path from "path";
|
|
4
3
|
import { deleteIfExists } from "@/utils/fs.js";
|
|
@@ -8,12 +7,28 @@ export async function setupCssFramework({
|
|
|
8
7
|
templatesDir,
|
|
9
8
|
language,
|
|
10
9
|
cssFramework,
|
|
10
|
+
architecture,
|
|
11
11
|
ext,
|
|
12
12
|
pkg,
|
|
13
13
|
}) {
|
|
14
14
|
process.chdir(projectPath);
|
|
15
15
|
const cssDir = path.join(templatesDir, "css");
|
|
16
|
-
|
|
16
|
+
// Feature-based main.* imports ./shared/styles/globals.css (or main.css when
|
|
17
|
+
// framework is "none"); component-based imports ./styles/globals.css (or
|
|
18
|
+
// main.css). The chosen framework's styles land in the file the architecture
|
|
19
|
+
// actually imports.
|
|
20
|
+
const stylesDir =
|
|
21
|
+
architecture === "feature-based"
|
|
22
|
+
? path.join(projectPath, "src", "shared", "styles")
|
|
23
|
+
: path.join(projectPath, "src", "styles");
|
|
24
|
+
|
|
25
|
+
// Vanilla CSS gets a stylesheet named main.css; tailwind/bootstrap keep
|
|
26
|
+
// globals.css (their idiomatic name — they inject framework directives).
|
|
27
|
+
const mainFileName = cssFramework === "none" ? "main.css" : "globals.css";
|
|
28
|
+
|
|
29
|
+
async function writeCss(content, fileName) {
|
|
30
|
+
await fsp.writeFile(path.join(stylesDir, fileName), content, "utf8");
|
|
31
|
+
}
|
|
17
32
|
|
|
18
33
|
if (cssFramework === "tailwind") {
|
|
19
34
|
const viteConfigFile = `vite.config.${language === "ts" ? "ts" : "js"}`;
|
|
@@ -24,14 +39,19 @@ export async function setupCssFramework({
|
|
|
24
39
|
);
|
|
25
40
|
await fsp.writeFile(viteConfigTarget, viteConfigContent, "utf8");
|
|
26
41
|
|
|
27
|
-
const
|
|
28
|
-
path.join(cssDir, "tailwind", "src", "
|
|
42
|
+
const globalsContent = await fsp.readFile(
|
|
43
|
+
path.join(cssDir, "tailwind", "src", "globals.css"),
|
|
29
44
|
"utf8"
|
|
30
45
|
);
|
|
31
|
-
await fsp.
|
|
46
|
+
const themesContent = await fsp.readFile(
|
|
47
|
+
path.join(cssDir, "tailwind", "src", "themes.css"),
|
|
48
|
+
"utf8"
|
|
49
|
+
);
|
|
50
|
+
await writeCss(globalsContent, "globals.css");
|
|
51
|
+
await writeCss(themesContent, "themes.css");
|
|
32
52
|
} else if (cssFramework === "bootstrap") {
|
|
33
53
|
const mainFile = path.join(projectPath, "src", `main.${ext}`);
|
|
34
|
-
|
|
54
|
+
try {
|
|
35
55
|
let mainContent = await fsp.readFile(mainFile, "utf8");
|
|
36
56
|
if (
|
|
37
57
|
!mainContent.includes("bootstrap/dist/css/bootstrap.min.css")
|
|
@@ -40,20 +60,59 @@ export async function setupCssFramework({
|
|
|
40
60
|
"import 'bootstrap/dist/css/bootstrap.min.css';\n" + mainContent;
|
|
41
61
|
await fsp.writeFile(mainFile, mainContent, "utf8");
|
|
42
62
|
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
|
|
63
|
+
} catch {}
|
|
64
|
+
|
|
65
|
+
const globalsContent = await fsp.readFile(
|
|
66
|
+
path.join(cssDir, "bootstrap", "src", "globals.css"),
|
|
67
|
+
"utf8"
|
|
68
|
+
);
|
|
69
|
+
const themesContent = await fsp.readFile(
|
|
70
|
+
path.join(cssDir, "bootstrap", "src", "themes.css"),
|
|
46
71
|
"utf8"
|
|
47
72
|
);
|
|
48
|
-
await
|
|
73
|
+
await writeCss(globalsContent, "globals.css");
|
|
74
|
+
await writeCss(themesContent, "themes.css");
|
|
49
75
|
} else {
|
|
50
|
-
const
|
|
51
|
-
path.join(cssDir, "none", "src", "
|
|
76
|
+
const mainContent = await fsp.readFile(
|
|
77
|
+
path.join(cssDir, "none", "src", "main.css"),
|
|
78
|
+
"utf8"
|
|
79
|
+
);
|
|
80
|
+
const themesContent = await fsp.readFile(
|
|
81
|
+
path.join(cssDir, "none", "src", "themes.css"),
|
|
52
82
|
"utf8"
|
|
53
83
|
);
|
|
54
|
-
await
|
|
84
|
+
await writeCss(mainContent, "main.css");
|
|
85
|
+
await writeCss(themesContent, "themes.css");
|
|
55
86
|
}
|
|
56
87
|
|
|
57
|
-
//
|
|
88
|
+
// Ensure main.{ext} imports the correct stylesheet name for this framework.
|
|
89
|
+
await syncMainCssImport(projectPath, ext, architecture, mainFileName);
|
|
90
|
+
|
|
91
|
+
// Ensure the styles dir exists (for the .gitkeep placeholder when no real
|
|
92
|
+
// file lives there yet — pruneRedundantGitkeeps removes it after overlays).
|
|
93
|
+
await fsp.mkdir(stylesDir, { recursive: true });
|
|
94
|
+
|
|
95
|
+
// Clean up Vite's default CSS files; src/index.css is the framework-agnostic
|
|
96
|
+
// leftover Vite scaffolds and is never imported in our generated projects.
|
|
58
97
|
await deleteIfExists(path.join(projectPath, "src", "App.css"));
|
|
98
|
+
await deleteIfExists(path.join(projectPath, "src", "index.css"));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Rewrite the CSS import in main.{ext} so it matches the file the framework
|
|
102
|
+
// actually wrote (main.css for "none", globals.css for tailwind/bootstrap).
|
|
103
|
+
async function syncMainCssImport(projectPath, ext, architecture, mainFileName) {
|
|
104
|
+
const mainPath = path.join(projectPath, "src", `main.${ext}`);
|
|
105
|
+
try {
|
|
106
|
+
let content = await fsp.readFile(mainPath, "utf8");
|
|
107
|
+
const expected =
|
|
108
|
+
architecture === "feature-based"
|
|
109
|
+
? `./shared/styles/${mainFileName}`
|
|
110
|
+
: `./styles/${mainFileName}`;
|
|
111
|
+
const wrong =
|
|
112
|
+
architecture === "feature-based"
|
|
113
|
+
? /import ['"]\.\/shared\/styles\/(globals|main)\.css['"]/
|
|
114
|
+
: /import ['"]\.\/styles\/(globals|main)\.css['"]/;
|
|
115
|
+
content = content.replace(wrong, `import '${expected}'`);
|
|
116
|
+
await fsp.writeFile(mainPath, content, "utf8");
|
|
117
|
+
} catch {}
|
|
59
118
|
}
|
package/src/dependencies.js
CHANGED
|
@@ -71,11 +71,14 @@ export async function installAllDeps(responses, pkg, cwd) {
|
|
|
71
71
|
} else if (responses.testing === "jest") {
|
|
72
72
|
devDeps.push(
|
|
73
73
|
"jest",
|
|
74
|
-
"
|
|
75
|
-
"@types/jest",
|
|
74
|
+
"jest-environment-jsdom",
|
|
76
75
|
"@testing-library/react",
|
|
77
76
|
"@testing-library/jest-dom",
|
|
78
|
-
"jsdom"
|
|
77
|
+
"jsdom",
|
|
78
|
+
"babel-jest",
|
|
79
|
+
"@babel/preset-env",
|
|
80
|
+
"@babel/preset-react",
|
|
81
|
+
"@babel/preset-typescript"
|
|
79
82
|
);
|
|
80
83
|
}
|
|
81
84
|
|
|
@@ -84,6 +87,8 @@ export async function installAllDeps(responses, pkg, cwd) {
|
|
|
84
87
|
devDeps.push("eslint", "@eslint/js", "eslint-plugin-react-hooks", "eslint-plugin-react-refresh", "globals");
|
|
85
88
|
if (responses.language === "ts") {
|
|
86
89
|
devDeps.push("typescript-eslint");
|
|
90
|
+
// ESLint >= 10 loads TS config files (eslint.config.ts) via jiti.
|
|
91
|
+
devDeps.push("jiti");
|
|
87
92
|
}
|
|
88
93
|
} else if (responses.linter === "oxlint") {
|
|
89
94
|
devDeps.push("oxlint");
|
package/src/format.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { execa } from "execa";
|
|
3
|
+
import { promises as fsp } from "fs";
|
|
4
|
+
|
|
5
|
+
async function exists(p) {
|
|
6
|
+
try {
|
|
7
|
+
await fsp.access(p);
|
|
8
|
+
return true;
|
|
9
|
+
} catch {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Runs the project-local formatter (installed as a devDependency) so a freshly
|
|
15
|
+
// generated project is canonical under its chosen formatter by construction.
|
|
16
|
+
// Falls back to the bare command name so the same helper works when the binary
|
|
17
|
+
// is already on PATH (e.g. verification harnesses resolving from a vendored
|
|
18
|
+
// node_modules symlink).
|
|
19
|
+
export async function runProjectFormat(projectPath, responses) {
|
|
20
|
+
if (!responses.formatter || responses.formatter === "none") return;
|
|
21
|
+
|
|
22
|
+
const formatter = responses.formatter;
|
|
23
|
+
const bin = path.join(projectPath, "node_modules", ".bin", formatter);
|
|
24
|
+
const command = (await exists(bin)) ? bin : formatter;
|
|
25
|
+
const args = formatter === "prettier" ? ["--write", "."] : ["."];
|
|
26
|
+
|
|
27
|
+
await execa(command, args, { cwd: projectPath, stdio: "pipe" });
|
|
28
|
+
}
|