create-nextjs-cms 0.9.6 → 0.9.7
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/LICENSE +21 -21
- package/README.md +71 -71
- package/dist/helpers/check-directory.d.ts +1 -0
- package/dist/helpers/check-directory.d.ts.map +1 -1
- package/dist/helpers/check-directory.js +98 -23
- package/dist/helpers/utils.js +16 -16
- package/dist/index.js +13 -8
- package/dist/lib/create-project.js +1 -1
- package/dist/lib/section-creators.js +166 -166
- package/package.json +1 -1
- package/templates/default/.eslintrc.json +5 -5
- package/templates/default/.prettierignore +7 -7
- package/templates/default/.prettierrc.json +27 -27
- package/templates/default/CHANGELOG.md +140 -140
- package/templates/default/_gitignore +57 -57
- package/templates/default/app/(auth)/auth/login/LoginPage.tsx +192 -192
- package/templates/default/app/(auth)/auth/login/page.tsx +11 -11
- package/templates/default/app/(auth)/auth-language-provider.tsx +34 -34
- package/templates/default/app/(auth)/layout.tsx +81 -81
- package/templates/default/app/(rootLayout)/(plugins)/[...slug]/page.tsx +40 -40
- package/templates/default/app/(rootLayout)/(plugins)/[...slug]/plugin-server-registry.ts +16 -16
- package/templates/default/app/(rootLayout)/admins/page.tsx +10 -10
- package/templates/default/app/(rootLayout)/browse/[section]/[page]/page.tsx +22 -22
- package/templates/default/app/(rootLayout)/categorized/[section]/page.tsx +15 -15
- package/templates/default/app/(rootLayout)/dashboard/page.tsx +63 -63
- package/templates/default/app/(rootLayout)/edit/[section]/[itemId]/page.tsx +20 -20
- package/templates/default/app/(rootLayout)/layout.tsx +81 -81
- package/templates/default/app/(rootLayout)/loading.tsx +10 -10
- package/templates/default/app/(rootLayout)/log/page.tsx +7 -7
- package/templates/default/app/(rootLayout)/new/[section]/page.tsx +15 -15
- package/templates/default/app/(rootLayout)/section/[section]/page.tsx +19 -19
- package/templates/default/app/(rootLayout)/settings/page.tsx +13 -13
- package/templates/default/app/_trpc/client.ts +3 -3
- package/templates/default/app/api/auth/csrf/route.ts +25 -25
- package/templates/default/app/api/auth/refresh/route.ts +10 -10
- package/templates/default/app/api/auth/route.ts +49 -49
- package/templates/default/app/api/auth/session/route.ts +20 -20
- package/templates/default/app/api/document/route.ts +165 -165
- package/templates/default/app/api/editor/photo/route.ts +49 -49
- package/templates/default/app/api/photo/route.ts +27 -27
- package/templates/default/app/api/submit/section/item/[slug]/route.ts +95 -95
- package/templates/default/app/api/submit/section/item/route.ts +56 -56
- package/templates/default/app/api/submit/section/simple/route.ts +86 -86
- package/templates/default/app/api/trpc/[trpc]/route.ts +33 -33
- package/templates/default/app/api/video/route.ts +174 -174
- package/templates/default/app/globals.css +228 -228
- package/templates/default/app/providers.tsx +152 -152
- package/templates/default/cms.config.ts +57 -58
- package/templates/default/components/AdminCard.tsx +166 -166
- package/templates/default/components/AdminEditPage.tsx +124 -124
- package/templates/default/components/AdminPrivilegeCard.tsx +185 -185
- package/templates/default/components/AdminsPage.tsx +43 -43
- package/templates/default/components/AnalyticsPage.tsx +144 -144
- package/templates/default/components/BarChartBox.tsx +42 -42
- package/templates/default/components/BrowsePage.tsx +106 -106
- package/templates/default/components/CategorizedSectionPage.tsx +31 -31
- package/templates/default/components/CategoryDeleteConfirmPage.tsx +130 -130
- package/templates/default/components/CategorySectionSelectInput.tsx +140 -140
- package/templates/default/components/ConditionalFields.tsx +49 -49
- package/templates/default/components/ContainerBox.tsx +24 -24
- package/templates/default/components/DashboardPageAlt.tsx +45 -45
- package/templates/default/components/DefaultNavItems.tsx +3 -3
- package/templates/default/components/Dropzone.tsx +154 -154
- package/templates/default/components/ErrorComponent.tsx +16 -16
- package/templates/default/components/GalleryPhoto.tsx +93 -93
- package/templates/default/components/InfoCard.tsx +93 -93
- package/templates/default/components/ItemEditPage.tsx +294 -294
- package/templates/default/components/Layout.tsx +84 -84
- package/templates/default/components/LoadingSpinners.tsx +67 -67
- package/templates/default/components/LocaleSwitcher.tsx +89 -89
- package/templates/default/components/LogPage.tsx +107 -107
- package/templates/default/components/Modal.tsx +166 -166
- package/templates/default/components/Navbar.tsx +258 -258
- package/templates/default/components/NewAdminForm.tsx +173 -173
- package/templates/default/components/NewPage.tsx +206 -206
- package/templates/default/components/NewVariantComponent.tsx +229 -229
- package/templates/default/components/PhotoGallery.tsx +35 -35
- package/templates/default/components/PieChartBox.tsx +101 -101
- package/templates/default/components/ProgressBar.tsx +48 -48
- package/templates/default/components/ProtectedDocument.tsx +44 -44
- package/templates/default/components/ProtectedImage.tsx +143 -143
- package/templates/default/components/ProtectedVideo.tsx +76 -76
- package/templates/default/components/SectionIcon.tsx +8 -8
- package/templates/default/components/SectionItemCard.tsx +144 -144
- package/templates/default/components/SectionItemStatusBadge.tsx +17 -17
- package/templates/default/components/SectionPage.tsx +205 -205
- package/templates/default/components/SelectBox.tsx +98 -98
- package/templates/default/components/SelectInputButtons.tsx +125 -125
- package/templates/default/components/SettingsPage.tsx +232 -232
- package/templates/default/components/Sidebar.tsx +204 -204
- package/templates/default/components/SidebarDropdownItem.tsx +83 -83
- package/templates/default/components/SidebarItem.tsx +24 -24
- package/templates/default/components/ThemeProvider.tsx +8 -8
- package/templates/default/components/TooltipComponent.tsx +27 -27
- package/templates/default/components/VariantCard.tsx +124 -124
- package/templates/default/components/VariantEditPage.tsx +230 -230
- package/templates/default/components/analytics/BounceRate.tsx +70 -70
- package/templates/default/components/analytics/LivePageViews.tsx +55 -55
- package/templates/default/components/analytics/LiveUsersCount.tsx +33 -33
- package/templates/default/components/analytics/MonthlyPageViews.tsx +42 -42
- package/templates/default/components/analytics/TopCountries.tsx +52 -52
- package/templates/default/components/analytics/TopDevices.tsx +46 -46
- package/templates/default/components/analytics/TopMediums.tsx +58 -58
- package/templates/default/components/analytics/TopSources.tsx +45 -45
- package/templates/default/components/analytics/TotalPageViews.tsx +41 -41
- package/templates/default/components/analytics/TotalSessions.tsx +41 -41
- package/templates/default/components/analytics/TotalUniqueUsers.tsx +41 -41
- package/templates/default/components/custom/RightHomeRoomVariantCard.tsx +138 -138
- package/templates/default/components/dndKit/Draggable.tsx +21 -21
- package/templates/default/components/dndKit/Droppable.tsx +20 -20
- package/templates/default/components/dndKit/SortableItem.tsx +18 -18
- package/templates/default/components/form/Form.tsx +370 -370
- package/templates/default/components/form/FormInputElement.tsx +70 -70
- package/templates/default/components/form/FormInputs.tsx +136 -136
- package/templates/default/components/form/helpers/_section-hot-reload.js +1 -1
- package/templates/default/components/form/helpers/util.ts +17 -17
- package/templates/default/components/form/inputs/CheckboxFormInput.tsx +46 -46
- package/templates/default/components/form/inputs/ColorFormInput.tsx +44 -44
- package/templates/default/components/form/inputs/DateFormInput.tsx +167 -110
- package/templates/default/components/form/inputs/DateRangeFormInput.tsx +23 -1
- package/templates/default/components/form/inputs/DocumentFormInput.tsx +222 -222
- package/templates/default/components/form/inputs/MapFormInput.tsx +140 -140
- package/templates/default/components/form/inputs/MultipleSelectFormInput.tsx +85 -85
- package/templates/default/components/form/inputs/NumberFormInput.tsx +43 -43
- package/templates/default/components/form/inputs/PasswordFormInput.tsx +47 -47
- package/templates/default/components/form/inputs/PhotoFormInput.tsx +275 -275
- package/templates/default/components/form/inputs/RichTextFormInput.tsx +138 -138
- package/templates/default/components/form/inputs/SelectFormInput.tsx +175 -175
- package/templates/default/components/form/inputs/SlugFormInput.tsx +131 -131
- package/templates/default/components/form/inputs/TagsFormInput.tsx +265 -265
- package/templates/default/components/form/inputs/TextFormInput.tsx +51 -51
- package/templates/default/components/form/inputs/TextareaFormInput.tsx +50 -50
- package/templates/default/components/form/inputs/VideoFormInput.tsx +118 -118
- package/templates/default/components/multi-select.tsx +1146 -1146
- package/templates/default/components/pagination/Pagination.tsx +36 -36
- package/templates/default/components/pagination/PaginationButtons.tsx +147 -147
- package/templates/default/components/theme-toggle.tsx +39 -39
- package/templates/default/components/ui/accordion.tsx +53 -53
- package/templates/default/components/ui/alert-dialog.tsx +157 -157
- package/templates/default/components/ui/alert.tsx +47 -47
- package/templates/default/components/ui/badge.tsx +38 -38
- package/templates/default/components/ui/button.tsx +62 -62
- package/templates/default/components/ui/calendar.tsx +166 -166
- package/templates/default/components/ui/card.tsx +43 -43
- package/templates/default/components/ui/checkbox.tsx +29 -29
- package/templates/default/components/ui/command.tsx +137 -137
- package/templates/default/components/ui/custom-alert-dialog.tsx +113 -113
- package/templates/default/components/ui/custom-dialog.tsx +123 -123
- package/templates/default/components/ui/dialog.tsx +123 -123
- package/templates/default/components/ui/direction.tsx +22 -22
- package/templates/default/components/ui/dropdown-menu.tsx +182 -182
- package/templates/default/components/ui/input-group.tsx +54 -54
- package/templates/default/components/ui/input.tsx +22 -22
- package/templates/default/components/ui/label.tsx +19 -19
- package/templates/default/components/ui/popover.tsx +42 -42
- package/templates/default/components/ui/progress.tsx +31 -31
- package/templates/default/components/ui/scroll-area.tsx +42 -42
- package/templates/default/components/ui/select.tsx +165 -165
- package/templates/default/components/ui/separator.tsx +28 -28
- package/templates/default/components/ui/sheet.tsx +103 -103
- package/templates/default/components/ui/spinner.tsx +16 -16
- package/templates/default/components/ui/switch.tsx +29 -29
- package/templates/default/components/ui/table.tsx +83 -83
- package/templates/default/components/ui/tabs.tsx +55 -55
- package/templates/default/components/ui/toast.tsx +113 -113
- package/templates/default/components/ui/toaster.tsx +35 -35
- package/templates/default/components/ui/tooltip.tsx +30 -30
- package/templates/default/components/ui/use-toast.ts +188 -188
- package/templates/default/components.json +21 -21
- package/templates/default/context/ModalProvider.tsx +53 -53
- package/templates/default/drizzle.config.ts +4 -4
- package/templates/default/dynamic-schemas/schema.ts +475 -0
- package/templates/default/env/env.js +130 -130
- package/templates/default/envConfig.ts +4 -4
- package/templates/default/hooks/useModal.ts +8 -8
- package/templates/default/lib/apiHelpers.ts +92 -92
- package/templates/default/lib/postinstall.js +14 -14
- package/templates/default/lib/utils.ts +6 -6
- package/templates/default/next-env.d.ts +6 -6
- package/templates/default/next.config.ts +23 -23
- package/templates/default/package.json +1 -1
- package/templates/default/postcss.config.mjs +6 -6
- package/templates/default/proxy.ts +32 -32
- package/templates/default/tsconfig.json +48 -48
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2025 create-nextjs-cms
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 create-nextjs-cms
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,71 +1,71 @@
|
|
|
1
|
-
# Create Nextjs CMS
|
|
2
|
-
|
|
3
|
-
The best and official way to create a nextjs-cms project with all the necessary configuration and dependencies.
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
You can create a new cms project interactively by running:
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
npx create-nextjs-cms
|
|
11
|
-
# or
|
|
12
|
-
yarn create nextjs-cms
|
|
13
|
-
# or
|
|
14
|
-
pnpm create nextjs-cms
|
|
15
|
-
# or
|
|
16
|
-
bun create nextjs-cms
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
## Project Structure
|
|
20
|
-
|
|
21
|
-
After running `create-nextjs-cms`, you'll have a fully configured nextjs-cms project with:
|
|
22
|
-
|
|
23
|
-
- ✅ Next.js application setup
|
|
24
|
-
- ✅ CMS configuration files
|
|
25
|
-
- ✅ Database configuration
|
|
26
|
-
- ✅ TypeScript configuration
|
|
27
|
-
- ✅ All necessary dependencies
|
|
28
|
-
- ✅ Example sections and fields
|
|
29
|
-
- ✅ Development scripts
|
|
30
|
-
|
|
31
|
-
## Next Steps
|
|
32
|
-
|
|
33
|
-
After creating your project:
|
|
34
|
-
|
|
35
|
-
```bash
|
|
36
|
-
cd my-cms-app
|
|
37
|
-
pnpm dev
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
Then visit `http://localhost:3000` to see your CMS in action!
|
|
41
|
-
|
|
42
|
-
## Requirements
|
|
43
|
-
|
|
44
|
-
- Node.js 18+
|
|
45
|
-
- A package manager (pnpm, npm, yarn, or bun)
|
|
46
|
-
|
|
47
|
-
## Troubleshooting
|
|
48
|
-
|
|
49
|
-
### Directory already exists
|
|
50
|
-
|
|
51
|
-
If you try to create a project in a directory that already exists, you'll get an error. Either:
|
|
52
|
-
- Choose a different directory name
|
|
53
|
-
- Use `.` to create in the current directory (must be empty)
|
|
54
|
-
|
|
55
|
-
### Installation fails
|
|
56
|
-
|
|
57
|
-
If automatic dependency installation fails, you can manually install:
|
|
58
|
-
|
|
59
|
-
```bash
|
|
60
|
-
cd my-cms-app
|
|
61
|
-
pnpm install
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
### Template not found
|
|
65
|
-
|
|
66
|
-
If you see an error about the template directory not being found, ensure you're using the published version of the package from npm, not a local development version.
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
## License
|
|
70
|
-
|
|
71
|
-
MIT License - see LICENSE file for details.
|
|
1
|
+
# Create Nextjs CMS
|
|
2
|
+
|
|
3
|
+
The best and official way to create a nextjs-cms project with all the necessary configuration and dependencies.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
You can create a new cms project interactively by running:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx create-nextjs-cms
|
|
11
|
+
# or
|
|
12
|
+
yarn create nextjs-cms
|
|
13
|
+
# or
|
|
14
|
+
pnpm create nextjs-cms
|
|
15
|
+
# or
|
|
16
|
+
bun create nextjs-cms
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Project Structure
|
|
20
|
+
|
|
21
|
+
After running `create-nextjs-cms`, you'll have a fully configured nextjs-cms project with:
|
|
22
|
+
|
|
23
|
+
- ✅ Next.js application setup
|
|
24
|
+
- ✅ CMS configuration files
|
|
25
|
+
- ✅ Database configuration
|
|
26
|
+
- ✅ TypeScript configuration
|
|
27
|
+
- ✅ All necessary dependencies
|
|
28
|
+
- ✅ Example sections and fields
|
|
29
|
+
- ✅ Development scripts
|
|
30
|
+
|
|
31
|
+
## Next Steps
|
|
32
|
+
|
|
33
|
+
After creating your project:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
cd my-cms-app
|
|
37
|
+
pnpm dev
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Then visit `http://localhost:3000` to see your CMS in action!
|
|
41
|
+
|
|
42
|
+
## Requirements
|
|
43
|
+
|
|
44
|
+
- Node.js 18+
|
|
45
|
+
- A package manager (pnpm, npm, yarn, or bun)
|
|
46
|
+
|
|
47
|
+
## Troubleshooting
|
|
48
|
+
|
|
49
|
+
### Directory already exists
|
|
50
|
+
|
|
51
|
+
If you try to create a project in a directory that already exists, you'll get an error. Either:
|
|
52
|
+
- Choose a different directory name
|
|
53
|
+
- Use `.` to create in the current directory (must be empty)
|
|
54
|
+
|
|
55
|
+
### Installation fails
|
|
56
|
+
|
|
57
|
+
If automatic dependency installation fails, you can manually install:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
cd my-cms-app
|
|
61
|
+
pnpm install
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Template not found
|
|
65
|
+
|
|
66
|
+
If you see an error about the template directory not being found, ensure you're using the published version of the package from npm, not a local development version.
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
## License
|
|
70
|
+
|
|
71
|
+
MIT License - see LICENSE file for details.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check-directory.d.ts","sourceRoot":"","sources":["../../src/helpers/check-directory.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"check-directory.d.ts","sourceRoot":"","sources":["../../src/helpers/check-directory.ts"],"names":[],"mappings":"AA2HA,eAAO,MAAM,gBAAgB,GACzB,SAAS,MAAM,KAChB,OAAO,CAAC;IACP,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,OAAO,CAAA;IACpB,mBAAmB,EAAE,OAAO,CAAA;CAC/B,CAqCA,CAAA"}
|
|
@@ -6,6 +6,85 @@ import fs from 'fs-extra';
|
|
|
6
6
|
import { isEmptyDir } from './utils.js';
|
|
7
7
|
import * as p from '@clack/prompts';
|
|
8
8
|
import chalk from 'chalk';
|
|
9
|
+
import ora from 'ora';
|
|
10
|
+
const abortInstallation = () => {
|
|
11
|
+
p.cancel('Aborting installation');
|
|
12
|
+
process.exit(1);
|
|
13
|
+
};
|
|
14
|
+
const abortDirectoryCleanup = (targetDir, error) => {
|
|
15
|
+
p.log.error(`Failed to empty ${targetDir === process.cwd() ? 'the current directory' : `"${targetDir}"`}.`);
|
|
16
|
+
p.log.message('Some files may already have been deleted.');
|
|
17
|
+
p.log.message(`Please review and clean this directory manually: ${targetDir}`);
|
|
18
|
+
p.log.message(`Reason: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
19
|
+
return abortInstallation();
|
|
20
|
+
};
|
|
21
|
+
const getDirectoryEntriesToDelete = async (targetDir, keepGit) => {
|
|
22
|
+
const entries = await fs.readdir(targetDir);
|
|
23
|
+
return entries.filter((entry) => !(keepGit && entry === '.git'));
|
|
24
|
+
};
|
|
25
|
+
const emptyDirectory = async (targetDir, entries, onEntryDeleted) => {
|
|
26
|
+
let deletedCount = 0;
|
|
27
|
+
for (const entry of entries) {
|
|
28
|
+
await fs.remove(path.join(targetDir, entry));
|
|
29
|
+
deletedCount += 1;
|
|
30
|
+
onEntryDeleted?.(deletedCount, entries.length);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
const runDirectoryCleanup = async ({ targetDir, targetIsCwd, keepGit, }) => {
|
|
34
|
+
const spinnerText = keepGit
|
|
35
|
+
? `Emptying ${targetIsCwd ? 'the current directory' : `"${targetDir}"`} and keeping .git...`
|
|
36
|
+
: `Emptying ${targetIsCwd ? 'the current directory' : `"${targetDir}"`}...`;
|
|
37
|
+
const successMessage = keepGit
|
|
38
|
+
? `Emptied ${targetIsCwd ? 'the current directory' : `"${targetDir}"`} and kept ${chalk.green('.git')}.`
|
|
39
|
+
: `Emptied ${targetIsCwd ? 'the current directory' : `"${targetDir}"`}.`;
|
|
40
|
+
const entriesToDelete = await getDirectoryEntriesToDelete(targetDir, keepGit);
|
|
41
|
+
const spinner = ora(entriesToDelete.length > 0 ? `${spinnerText} (0/${entriesToDelete.length})` : spinnerText).start();
|
|
42
|
+
try {
|
|
43
|
+
await emptyDirectory(targetDir, entriesToDelete, (deletedCount, totalCount) => {
|
|
44
|
+
spinner.text = `${spinnerText} (${deletedCount}/${totalCount})`;
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
spinner.stop();
|
|
49
|
+
abortDirectoryCleanup(targetDir, error);
|
|
50
|
+
}
|
|
51
|
+
spinner.stop();
|
|
52
|
+
p.log.info(successMessage);
|
|
53
|
+
};
|
|
54
|
+
const promptForNonEmptyDirectoryAction = async (targetDir, targetIsCwd) => {
|
|
55
|
+
if (targetIsCwd) {
|
|
56
|
+
p.log.error('Current directory is not empty.');
|
|
57
|
+
p.log.message(chalk.gray('Tip: You can also specify a directory name like this: \n') +
|
|
58
|
+
chalk.green('pnpm create nextjs-cms ') +
|
|
59
|
+
chalk.italic.magenta('my-app'));
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
p.log.error(`Directory "${targetDir}" is not empty.`);
|
|
63
|
+
}
|
|
64
|
+
p.log.message('Choose how you want to proceed:');
|
|
65
|
+
const action = await p.select({
|
|
66
|
+
message: 'How would you like to proceed?',
|
|
67
|
+
initialValue: 'abort',
|
|
68
|
+
options: [
|
|
69
|
+
{ value: 'abort', label: 'Abort' },
|
|
70
|
+
{ value: 'empty', label: 'Empty directory ⚠️', hint: 'Delete everything in the target directory' },
|
|
71
|
+
{
|
|
72
|
+
value: 'empty-keep-git',
|
|
73
|
+
label: 'Empty directory and keep .git folder ⚠️',
|
|
74
|
+
hint: 'Delete everything except the root .git folder',
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
value: 'continue',
|
|
78
|
+
label: 'Continue anyway ⚠️',
|
|
79
|
+
hint: 'Existing files may be overwritten and the app may be unstable',
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
});
|
|
83
|
+
if (p.isCancel(action) || action === 'abort') {
|
|
84
|
+
abortInstallation();
|
|
85
|
+
}
|
|
86
|
+
return action;
|
|
87
|
+
};
|
|
9
88
|
export const resolveDirectory = async (appName) => {
|
|
10
89
|
// Resolve target path from the caller's CWD
|
|
11
90
|
const rawTarget = expandHome(appName);
|
|
@@ -13,35 +92,31 @@ export const resolveDirectory = async (appName) => {
|
|
|
13
92
|
// Derive package name from final path
|
|
14
93
|
const projectName = basename(targetDir);
|
|
15
94
|
const targetIsCwd = path.normalize(targetDir) === path.normalize(process.cwd());
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
await fs.ensureDir(targetDir);
|
|
20
|
-
}
|
|
21
|
-
else if (!(await isEmptyDir(targetDir))) {
|
|
22
|
-
p.log.error('Current directory is not empty. Choose an empty folder or a new directory name.');
|
|
23
|
-
p.log.message(chalk.gray('Tip: You can also specify a directory name like this: \n') +
|
|
24
|
-
chalk.green('pnpm create nextjs-cms ') +
|
|
25
|
-
chalk.italic.magenta('my-app'));
|
|
26
|
-
p.log.message(' ');
|
|
27
|
-
process.exit(1);
|
|
28
|
-
}
|
|
95
|
+
const targetExistedBefore = await fs.pathExists(targetDir);
|
|
96
|
+
if (!targetExistedBefore) {
|
|
97
|
+
await fs.ensureDir(targetDir);
|
|
29
98
|
}
|
|
30
|
-
else {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
99
|
+
else if (!(await isEmptyDir(targetDir))) {
|
|
100
|
+
const action = await promptForNonEmptyDirectoryAction(targetDir, targetIsCwd);
|
|
101
|
+
switch (action) {
|
|
102
|
+
case 'empty':
|
|
103
|
+
await runDirectoryCleanup({ targetDir, targetIsCwd, keepGit: false });
|
|
104
|
+
break;
|
|
105
|
+
case 'empty-keep-git':
|
|
106
|
+
await runDirectoryCleanup({ targetDir, targetIsCwd, keepGit: true });
|
|
107
|
+
break;
|
|
108
|
+
case 'continue':
|
|
109
|
+
p.log.warn('Continuing in a non-empty directory. Existing files may be overwritten.');
|
|
110
|
+
break;
|
|
111
|
+
default:
|
|
112
|
+
action;
|
|
113
|
+
break;
|
|
40
114
|
}
|
|
41
115
|
}
|
|
42
116
|
return {
|
|
43
117
|
targetDir,
|
|
44
118
|
projectName,
|
|
45
119
|
targetIsCwd,
|
|
120
|
+
targetExistedBefore,
|
|
46
121
|
};
|
|
47
122
|
};
|
package/dist/helpers/utils.js
CHANGED
|
@@ -4,22 +4,22 @@ import os from 'node:os';
|
|
|
4
4
|
import { randomBytes } from 'node:crypto';
|
|
5
5
|
import { log } from '@clack/prompts';
|
|
6
6
|
import chalk from 'chalk';
|
|
7
|
-
export const TITLE_TEXT = `
|
|
8
|
-
_
|
|
9
|
-
___ _ __ ___ __ _| |_ ___
|
|
10
|
-
/ __| '__/ _ \\/ _\\\` | __/ _ \\
|
|
11
|
-
| (__| | | __/ (_| | || __/
|
|
12
|
-
\\___|_| \\___|\\__,_|\\__\\___|
|
|
13
|
-
_ _
|
|
14
|
-
_ __ _____ _| |_ (_)___
|
|
15
|
-
| '_ \\ / _ \\ \\/ / __|| / __|
|
|
16
|
-
| | | | __/> <| |_ | \\__ \\
|
|
17
|
-
|_| |_|\\___/_/\\_\\__|/ |___/
|
|
18
|
-
|__/
|
|
19
|
-
___ _ __ ___ ___
|
|
20
|
-
/ __| '_ \\\` _ \\/ __|
|
|
21
|
-
| (__| | | | | \\__ \\
|
|
22
|
-
\\___|_| |_| |_|___/
|
|
7
|
+
export const TITLE_TEXT = `
|
|
8
|
+
_
|
|
9
|
+
___ _ __ ___ __ _| |_ ___
|
|
10
|
+
/ __| '__/ _ \\/ _\\\` | __/ _ \\
|
|
11
|
+
| (__| | | __/ (_| | || __/
|
|
12
|
+
\\___|_| \\___|\\__,_|\\__\\___|
|
|
13
|
+
_ _
|
|
14
|
+
_ __ _____ _| |_ (_)___
|
|
15
|
+
| '_ \\ / _ \\ \\/ / __|| / __|
|
|
16
|
+
| | | | __/> <| |_ | \\__ \\
|
|
17
|
+
|_| |_|\\___/_/\\_\\__|/ |___/
|
|
18
|
+
|__/
|
|
19
|
+
___ _ __ ___ ___
|
|
20
|
+
/ __| '_ \\\` _ \\/ __|
|
|
21
|
+
| (__| | | | | \\__ \\
|
|
22
|
+
\\___|_| |_| |_|___/
|
|
23
23
|
`;
|
|
24
24
|
/** Expand ~ to home */
|
|
25
25
|
export function expandHome(p) {
|
package/dist/index.js
CHANGED
|
@@ -21,7 +21,7 @@ async function createNextjsCms() {
|
|
|
21
21
|
// Run CLI to get user input
|
|
22
22
|
const { appName, sectionsToAdd, git /*, databaseProvider*/ } = await runCli();
|
|
23
23
|
// Resolve directory
|
|
24
|
-
const { targetDir, projectName, targetIsCwd } = await resolveDirectory(appName);
|
|
24
|
+
const { targetDir, projectName, targetIsCwd, targetExistedBefore } = await resolveDirectory(appName);
|
|
25
25
|
try {
|
|
26
26
|
// Detect package manager
|
|
27
27
|
const preferredPM = detectPackageManager();
|
|
@@ -63,14 +63,19 @@ async function createNextjsCms() {
|
|
|
63
63
|
p.outro(chalk.red(`❌ Failed to create project: ${error instanceof Error ? error.message : 'Unknown error'}`));
|
|
64
64
|
// Clean up partial installation on error
|
|
65
65
|
if ((await fs.pathExists(targetDir)) && !targetIsCwd) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
await fs.remove(targetDir);
|
|
69
|
-
p.log.success('✅ Cleanup completed.');
|
|
66
|
+
if (targetExistedBefore) {
|
|
67
|
+
p.log.warn('Project creation failed in a pre-existing directory. Existing files were left in place.');
|
|
70
68
|
}
|
|
71
|
-
|
|
72
|
-
p.log.
|
|
73
|
-
|
|
69
|
+
else {
|
|
70
|
+
p.log.info('🧹 Cleaning up partial installation...');
|
|
71
|
+
try {
|
|
72
|
+
await fs.remove(targetDir);
|
|
73
|
+
p.log.success('✅ Cleanup completed.');
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
p.log.error('⚠️ Could not clean up partial installation.');
|
|
77
|
+
p.log.message(` Please manually remove: ${targetDir}`);
|
|
78
|
+
}
|
|
74
79
|
}
|
|
75
80
|
}
|
|
76
81
|
process.exit(1);
|
|
@@ -22,7 +22,7 @@ export const createProject = async ({ targetDir, sectionsToAdd, projectName, pre
|
|
|
22
22
|
!rel.startsWith('.turbo') &&
|
|
23
23
|
!rel.includes('tsconfig.tsbuildinfo'));
|
|
24
24
|
},
|
|
25
|
-
// Overwrite is
|
|
25
|
+
// Overwrite is intentional because the target is new, user-approved, or was explicitly emptied
|
|
26
26
|
overwrite: true,
|
|
27
27
|
errorOnExist: false,
|
|
28
28
|
});
|