create-next-pro-cli 0.1.12 → 0.1.14
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/.github/workflows/ci.yml +38 -0
- package/README.md +105 -86
- package/bin.ts +0 -0
- package/dist/bin.js +5466 -0
- package/install.sh +64 -8
- package/package.json +9 -3
- package/.husky/commit-msg +0 -2
- package/.husky/pre-commit +0 -2
- package/CODE_OF_CONDUCT.md +0 -33
- package/CONTRIBUTING.md +0 -44
- package/FONCTIONALITY.md +0 -25
- package/src/index.ts +0 -67
- package/src/lib/addComponent.ts +0 -119
- package/src/lib/addPage.ts +0 -170
- package/src/lib/createProject.ts +0 -18
- package/src/lib/createProjectWithPrompt.ts +0 -79
- package/src/lib/rmPage.ts +0 -52
- package/src/lib/utils.ts +0 -36
- package/src/scaffold-dev.ts +0 -89
- package/src/scaffold.ts +0 -70
- package/templates/Projects/default/README.md +0 -36
- package/templates/Projects/default/src/app/[locale]/(public)/Login/page.tsx +0 -6
- package/templates/Projects/default/src/app/[locale]/(public)/Register/page.tsx +0 -6
- package/templates/Projects/default/src/app/[locale]/(public)/_home/loading.tsx +0 -5
- package/templates/Projects/default/src/app/[locale]/(public)/_home/page.tsx +0 -6
- package/templates/Projects/default/src/app/[locale]/(public)/layout.tsx +0 -9
- package/templates/Projects/default/src/app/[locale]/(user)/Dashboard/error.tsx +0 -38
- package/templates/Projects/default/src/app/[locale]/(user)/Dashboard/loading.tsx +0 -10
- package/templates/Projects/default/src/app/[locale]/(user)/Dashboard/page.tsx +0 -5
- package/templates/Projects/default/src/app/[locale]/(user)/Settings/loading.tsx +0 -17
- package/templates/Projects/default/src/app/[locale]/(user)/Settings/page.tsx +0 -6
- package/templates/Projects/default/src/app/[locale]/(user)/UserInfo/loading.tsx +0 -17
- package/templates/Projects/default/src/app/[locale]/(user)/UserInfo/page.tsx +0 -6
- package/templates/Projects/default/src/app/[locale]/(user)/layout.tsx +0 -9
- package/templates/Projects/default/src/app/[locale]/layout.tsx +0 -31
- package/templates/Projects/default/src/app/[locale]/loading.tsx +0 -14
- package/templates/Projects/default/src/app/[locale]/not-found.tsx +0 -22
- package/templates/Projects/default/src/app/[locale]/page.tsx +0 -6
- package/templates/Projects/default/src/app/api/auth/[...nextauth]/route.ts +0 -62
- package/templates/Projects/default/src/app/api/auth/post-login/route.ts +0 -26
- package/templates/Projects/default/src/app/favicon.ico +0 -0
- package/templates/Projects/default/src/app/layout.tsx +0 -11
- package/templates/Projects/default/src/app/not-found.tsx +0 -17
- package/templates/Projects/default/src/app/page.tsx +0 -6
- package/templates/Projects/default/src/app/sitemap.ts +0 -27
- package/templates/Projects/default/src/app/styles/globals.css +0 -305
- package/templates/Projects/default/src/auth.config.ts +0 -0
- package/templates/Projects/default/src/config.ts +0 -4
- package/templates/Projects/default/src/lib/auth/disconnect.ts +0 -11
- package/templates/Projects/default/src/lib/auth/isConnected.ts +0 -18
- package/templates/Projects/default/src/lib/i18n/navigation.ts +0 -19
- package/templates/Projects/default/src/lib/i18n/request.ts +0 -31
- package/templates/Projects/default/src/lib/i18n/routing.ts +0 -20
- package/templates/Projects/default/src/lib/utils.ts +0 -6
- package/templates/Projects/default/src/ui/Dashboard/LogoutButton.tsx +0 -27
- package/templates/Projects/default/src/ui/Dashboard/StatsCard.tsx +0 -14
- package/templates/Projects/default/src/ui/Dashboard/WelcomeCard.tsx +0 -10
- package/templates/Projects/default/src/ui/Dashboard/page-ui.tsx +0 -23
- package/templates/Projects/default/src/ui/Login/page-ui.tsx +0 -22
- package/templates/Projects/default/src/ui/Register/page-ui.tsx +0 -26
- package/templates/Projects/default/src/ui/Settings/page-ui.tsx +0 -17
- package/templates/Projects/default/src/ui/UserInfo/page-ui.tsx +0 -17
- package/templates/Projects/default/src/ui/_global/BackButton.tsx +0 -17
- package/templates/Projects/default/src/ui/_global/Button.tsx +0 -75
- package/templates/Projects/default/src/ui/_global/GlobalHeader.tsx +0 -55
- package/templates/Projects/default/src/ui/_global/GlobalMain.tsx +0 -15
- package/templates/Projects/default/src/ui/_global/Loading.tsx +0 -13
- package/templates/Projects/default/src/ui/_global/LocaleSwitcher.tsx +0 -38
- package/templates/Projects/default/src/ui/_global/PublicNav.tsx +0 -91
- package/templates/Projects/default/src/ui/_global/ThemeToggle.tsx +0 -53
- package/templates/Projects/default/src/ui/_global/UserNav.tsx +0 -35
- package/templates/Projects/default/src/ui/_home/page-ui.tsx +0 -27
package/install.sh
CHANGED
|
@@ -1,18 +1,74 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
# Installation script for create-next-pro
|
|
4
|
+
|
|
5
|
+
# Detect runtimes
|
|
6
|
+
bun_path=$(command -v bun)
|
|
7
|
+
deno_path=$(command -v deno)
|
|
8
|
+
node_path=$(command -v node)
|
|
9
|
+
|
|
10
|
+
if [ -n "$bun_path" ]; then
|
|
11
|
+
echo "Bun detected at $bun_path. Using Bun shebang."
|
|
12
|
+
sed -i '1s|.*|#!/usr/bin/env bun|' dist/bin.js
|
|
13
|
+
elif [ -n "$deno_path" ]; then
|
|
14
|
+
echo "Deno detected at $deno_path. Using Deno shebang."
|
|
15
|
+
sed -i '1s|.*|#!/usr/bin/env deno|' dist/bin.js
|
|
16
|
+
elif [ -n "$node_path" ]; then
|
|
17
|
+
echo "Node.js detected at $node_path. Using Node shebang."
|
|
18
|
+
sed -i '1s|.*|#!/usr/bin/env node|' dist/bin.js
|
|
19
|
+
else
|
|
20
|
+
echo "No compatible runtime (Bun, Deno, Node.js) found."
|
|
21
|
+
read -p "Do you want to install Bun? [Y/n] " yn
|
|
22
|
+
case $yn in
|
|
23
|
+
[Nn]*)
|
|
24
|
+
echo "Installation cancelled. Do you want to delete the parent folder? [Y/n] "
|
|
25
|
+
read delyn
|
|
26
|
+
case $delyn in
|
|
27
|
+
[Nn]*) echo "Folder kept."; exit 1;;
|
|
28
|
+
*)
|
|
29
|
+
parent_dir="$(dirname $(pwd))"
|
|
30
|
+
echo "Deleting folder $parent_dir..."
|
|
31
|
+
rm -rf "$parent_dir"
|
|
32
|
+
echo "Folder deleted."
|
|
33
|
+
exit 1
|
|
34
|
+
;;
|
|
35
|
+
esac
|
|
36
|
+
;;
|
|
37
|
+
*)
|
|
38
|
+
echo "Please install Bun, node or Deno!"
|
|
39
|
+
echo "Installation instructions:"
|
|
40
|
+
echo "Bun: https://bun.com/"
|
|
41
|
+
echo "Node.js: https://nodejs.org/"
|
|
42
|
+
echo "Deno: https://deno.land/"
|
|
43
|
+
exit 1
|
|
44
|
+
;;
|
|
45
|
+
esac
|
|
46
|
+
fi
|
|
3
47
|
|
|
4
48
|
COMPLETION_SCRIPT="$(pwd)/create-next-pro-completion.sh"
|
|
5
|
-
BASHRC="$HOME/.bashrc"
|
|
6
49
|
|
|
7
|
-
|
|
50
|
+
# Choose shell for autocompletion
|
|
51
|
+
read -p "Which shell do you use? [1] zsh, [2] bash (default: bash): " shell_choice
|
|
52
|
+
case $shell_choice in
|
|
53
|
+
1|zsh|Zsh)
|
|
54
|
+
RC_FILE="$HOME/.zshrc"
|
|
55
|
+
SHELL_NAME="zsh"
|
|
56
|
+
;;
|
|
57
|
+
*)
|
|
58
|
+
RC_FILE="$HOME/.bashrc"
|
|
59
|
+
SHELL_NAME="bash"
|
|
60
|
+
;;
|
|
61
|
+
esac
|
|
62
|
+
|
|
63
|
+
read -p "Do you want to add create-next-pro autocompletion to your $SHELL_NAME rc file? [Y/n] " yn
|
|
8
64
|
case $yn in
|
|
9
|
-
[Nn]*) echo "ℹ️
|
|
65
|
+
[Nn]*) echo "ℹ️ Autocompletion not added"; exit;;
|
|
10
66
|
*)
|
|
11
|
-
if ! grep -q "$COMPLETION_SCRIPT" "$
|
|
12
|
-
echo "source $COMPLETION_SCRIPT" >> "$
|
|
13
|
-
echo "✅
|
|
67
|
+
if ! grep -q "$COMPLETION_SCRIPT" "$RC_FILE"; then
|
|
68
|
+
echo "source $COMPLETION_SCRIPT" >> "$RC_FILE"
|
|
69
|
+
echo "✅ Autocompletion script added to $RC_FILE"
|
|
14
70
|
else
|
|
15
|
-
echo "ℹ️ Script
|
|
71
|
+
echo "ℹ️ Script already present in $RC_FILE"
|
|
16
72
|
fi
|
|
17
73
|
;;
|
|
18
74
|
esac
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-next-pro-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.14",
|
|
4
4
|
"description": "Advanced Next.js project scaffolder with i18n, Tailwind, App Router and more.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/Rising-Corporation/create-next-pro-cli.git"
|
|
8
8
|
},
|
|
9
9
|
"bin": {
|
|
10
|
-
"create-next-pro": "./bin.
|
|
10
|
+
"create-next-pro": "./dist/bin.js"
|
|
11
11
|
},
|
|
12
12
|
"author": "MrRise",
|
|
13
13
|
"license": "MIT",
|
|
@@ -16,9 +16,15 @@
|
|
|
16
16
|
"dev": "bun run bin.ts",
|
|
17
17
|
"scaffold-dev": "bun run src/scaffold-dev.ts",
|
|
18
18
|
"postinstall": "bash install.sh",
|
|
19
|
+
"test": "bun test",
|
|
20
|
+
"clean": "rm -rf dist",
|
|
21
|
+
"build": "bun build bin.ts --outdir dist --target bun",
|
|
22
|
+
"prepublishOnly": "bun run clean && bun run build",
|
|
19
23
|
"commit": "cz",
|
|
20
24
|
"release": "bunx --bun standard-version",
|
|
21
|
-
"prepare-husky": "husky"
|
|
25
|
+
"prepare-husky": "husky",
|
|
26
|
+
"version-patch": "npm version patch",
|
|
27
|
+
"git-fullpush": "git add -A && bun commit && bun version-patch && git push origin master"
|
|
22
28
|
},
|
|
23
29
|
"config": {
|
|
24
30
|
"commitizen": {
|
package/.husky/commit-msg
DELETED
package/.husky/pre-commit
DELETED
package/CODE_OF_CONDUCT.md
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
# Contributor Covenant Code of Conduct
|
|
2
|
-
|
|
3
|
-
## Our Pledge
|
|
4
|
-
|
|
5
|
-
We as members, contributors, and leaders pledge to make participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
|
6
|
-
|
|
7
|
-
## Our Standards
|
|
8
|
-
|
|
9
|
-
Examples of behavior that contributes to a positive environment for our community include:
|
|
10
|
-
|
|
11
|
-
- Using welcoming and inclusive language
|
|
12
|
-
- Being respectful of differing viewpoints and experiences
|
|
13
|
-
- Gracefully accepting constructive criticism
|
|
14
|
-
- Focusing on what is best for the community
|
|
15
|
-
- Showing empathy towards other community members
|
|
16
|
-
|
|
17
|
-
Examples of unacceptable behavior include:
|
|
18
|
-
|
|
19
|
-
- The use of sexualized language or imagery and unwelcome sexual attention or advances
|
|
20
|
-
- Trolling, insulting/derogatory comments, and personal or political attacks
|
|
21
|
-
- Public or private harassment
|
|
22
|
-
- Publishing others' private information, such as a physical or electronic address, without explicit permission
|
|
23
|
-
- Other conduct which could reasonably be considered inappropriate in a professional setting
|
|
24
|
-
|
|
25
|
-
## Enforcement
|
|
26
|
-
|
|
27
|
-
Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
|
|
28
|
-
|
|
29
|
-
Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.
|
|
30
|
-
|
|
31
|
-
## Attribution
|
|
32
|
-
|
|
33
|
-
This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 2.1.
|
package/CONTRIBUTING.md
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
# Contributing to create-next-pro-cli
|
|
2
|
-
|
|
3
|
-
Thank you for considering contributing! Here’s how to get started:
|
|
4
|
-
|
|
5
|
-
## Branches
|
|
6
|
-
|
|
7
|
-
- `master`: Stable releases only.
|
|
8
|
-
- `dev`: All new features and fixes are merged here first.
|
|
9
|
-
- Create your feature/fix branch from `dev`:
|
|
10
|
-
- `feature/your-feature-name`
|
|
11
|
-
- `fix/your-bug-description`
|
|
12
|
-
|
|
13
|
-
## Workflow
|
|
14
|
-
|
|
15
|
-
1. Fork the repository.
|
|
16
|
-
2. Create your branch from `dev`.
|
|
17
|
-
3. Commit your changes with clear messages.
|
|
18
|
-
4. Open a Pull Request (PR) to `dev`.
|
|
19
|
-
5. Describe your changes and reference any related issues.
|
|
20
|
-
|
|
21
|
-
## Code Style
|
|
22
|
-
|
|
23
|
-
- Use TypeScript and follow existing formatting.
|
|
24
|
-
- Document your code with comments.
|
|
25
|
-
- Run `bun lint` and `bun test` before submitting.
|
|
26
|
-
|
|
27
|
-
## Issues
|
|
28
|
-
|
|
29
|
-
- Search for existing issues before opening a new one.
|
|
30
|
-
- Be clear and provide context, steps to reproduce, and screenshots if possible.
|
|
31
|
-
|
|
32
|
-
## Review & Merge
|
|
33
|
-
|
|
34
|
-
- All PRs are reviewed by maintainers or the community.
|
|
35
|
-
- Once approved, PRs are merged into `dev`, then into `master` for releases.
|
|
36
|
-
|
|
37
|
-
## Community
|
|
38
|
-
|
|
39
|
-
- Be respectful and constructive.
|
|
40
|
-
- Use GitHub Discussions for questions and ideas.
|
|
41
|
-
|
|
42
|
-
---
|
|
43
|
-
|
|
44
|
-
Happy coding! 🚀
|
package/FONCTIONALITY.md
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
# Features of the create-next-pro binary
|
|
2
|
-
|
|
3
|
-
- Advanced Next.js project creation with options (TypeScript, ESLint, Tailwind, src/, Turbopack, i18n, import alias)
|
|
4
|
-
- `addpage` command:
|
|
5
|
-
- Add a page with templates (layout, page, loading, etc.)
|
|
6
|
-
- Automatically create folders/files in `src/app/[locale]` and `src/ui`
|
|
7
|
-
- Add translation files in `messages/<locale>`
|
|
8
|
-
- Supports nested pages (e.g. `PageParent.PageChild`)
|
|
9
|
-
- Creates in the parent folder
|
|
10
|
-
- Appends JSON to the parent object
|
|
11
|
-
- `addcomponent` command:
|
|
12
|
-
- Add a component to a page or globally
|
|
13
|
-
- Create the TSX file in `src/ui/<Page>/` or `src/ui/_global/`
|
|
14
|
-
- Add the component to the page or global translation JSON
|
|
15
|
-
- `rmpage` command:
|
|
16
|
-
- Remove a page and all its associated files
|
|
17
|
-
- Folders/files in `src/ui`, `src/app/[locale]`, and `messages/<locale>`
|
|
18
|
-
- Bash autocompletion:
|
|
19
|
-
- Suggests commands and existing pages
|
|
20
|
-
- Supports nested pages for completion
|
|
21
|
-
- Installation script proposed at first launch
|
|
22
|
-
- Fast CLI mode (non-interactive) and interactive mode (prompts)
|
|
23
|
-
- File generation from customizable templates
|
|
24
|
-
- Name handling (respects user input casing)
|
|
25
|
-
- Optional addition of the autocompletion script to `.bashrc` via prompt
|
package/src/index.ts
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
// src/index.ts
|
|
2
|
-
|
|
3
|
-
import { addComponent } from "./lib/addComponent";
|
|
4
|
-
import { addPage } from "./lib/addPage";
|
|
5
|
-
import { rmPage } from "./lib/rmPage";
|
|
6
|
-
import { createProject } from "./lib/createProject";
|
|
7
|
-
import { createProjectWithPrompt } from "./lib/createProjectWithPrompt";
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Main CLI entry point for create-next-pro.
|
|
11
|
-
*
|
|
12
|
-
* Note: For now, the project behaves as if --force is always enabled and no creation prompt is taken into account.
|
|
13
|
-
* All actions are performed directly without confirmation.
|
|
14
|
-
*/
|
|
15
|
-
export async function main() {
|
|
16
|
-
console.log("🚀 Welcome to create-next-pro\n");
|
|
17
|
-
|
|
18
|
-
let args = Bun.argv.slice(2);
|
|
19
|
-
const force = args.includes("--force");
|
|
20
|
-
// For now, --force is always considered enabled but do not overwrite existing projects
|
|
21
|
-
// WARNING: if you enable --force it will overwrite existing projects. This is a temporary setting for development purposes.
|
|
22
|
-
// const force = true;
|
|
23
|
-
|
|
24
|
-
// If addpage is called without options, add default flags -LPl
|
|
25
|
-
if (args[0] === "addpage" && args.length === 1) {
|
|
26
|
-
args.push("-LPl");
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Handle addcomponent command: create a component in the correct location and update translation JSON.
|
|
31
|
-
*/
|
|
32
|
-
if (args[0] === "addcomponent") {
|
|
33
|
-
addComponent(args);
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Handle addpage command: create a page (nested or not) and update translation JSON.
|
|
39
|
-
*/
|
|
40
|
-
if (args[0] === "addpage") {
|
|
41
|
-
addPage(args);
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Handle rmpage command: remove a page and all related files/folders.
|
|
47
|
-
*/
|
|
48
|
-
if (args[0] === "rmpage") {
|
|
49
|
-
rmPage(args);
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Handle direct project creation if a name argument is provided.
|
|
55
|
-
*/
|
|
56
|
-
const nameArg = args.find((arg) => !arg.startsWith("--"));
|
|
57
|
-
|
|
58
|
-
if (nameArg) {
|
|
59
|
-
createProject(nameArg, force);
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Interactive prompt for project creation (not currently used, see note above).
|
|
65
|
-
*/
|
|
66
|
-
await createProjectWithPrompt();
|
|
67
|
-
}
|
package/src/lib/addComponent.ts
DELETED
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import { join } from "node:path";
|
|
2
|
-
import { mkdir, readFile, writeFile, readdir } from "node:fs/promises";
|
|
3
|
-
import prompts from "prompts";
|
|
4
|
-
import { capitalize } from "./utils"; // Assuming you have a utility function to capitalize strings
|
|
5
|
-
import { existsSync } from "node:fs";
|
|
6
|
-
|
|
7
|
-
export async function addComponent(args: string[]) {
|
|
8
|
-
let componentName = args[1];
|
|
9
|
-
let pageScope = null;
|
|
10
|
-
let pageIndex = args.findIndex((arg) => arg === "-P" || arg === "--page");
|
|
11
|
-
if (pageIndex !== -1 && args[pageIndex + 1]) {
|
|
12
|
-
pageScope = args[pageIndex + 1];
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
// Handle nested pageScope (e.g. ParentPage.ChildPage)
|
|
16
|
-
let nestedPath = null;
|
|
17
|
-
if (pageScope && pageScope.includes(".")) {
|
|
18
|
-
nestedPath = join(...pageScope.split("."));
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
if (!componentName || componentName.startsWith("-")) {
|
|
22
|
-
// Si le nom n'est pas fourni ou est une option, demander via prompt
|
|
23
|
-
const response = await prompts.prompt({
|
|
24
|
-
type: "text",
|
|
25
|
-
name: "componentName",
|
|
26
|
-
message: "🧩 Component name to add:",
|
|
27
|
-
validate: (name: string) => (name ? true : "Component name is required"),
|
|
28
|
-
});
|
|
29
|
-
componentName = response.componentName;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const componentNameUpper = capitalize(componentName);
|
|
33
|
-
const templatePath = join(
|
|
34
|
-
import.meta.dir,
|
|
35
|
-
"..",
|
|
36
|
-
"..",
|
|
37
|
-
"templates",
|
|
38
|
-
"Component"
|
|
39
|
-
);
|
|
40
|
-
const messagesPath = join(process.cwd(), "messages");
|
|
41
|
-
|
|
42
|
-
// Determine target path for the component
|
|
43
|
-
let componentTargetPath;
|
|
44
|
-
let translationKey;
|
|
45
|
-
if (pageScope) {
|
|
46
|
-
if (nestedPath) {
|
|
47
|
-
componentTargetPath = join(process.cwd(), "src", "ui", nestedPath);
|
|
48
|
-
translationKey = pageScope;
|
|
49
|
-
} else {
|
|
50
|
-
componentTargetPath = join(process.cwd(), "src", "ui", pageScope);
|
|
51
|
-
translationKey = pageScope;
|
|
52
|
-
}
|
|
53
|
-
} else {
|
|
54
|
-
componentTargetPath = join(process.cwd(), "src", "ui", "_global");
|
|
55
|
-
translationKey = "_global_ui";
|
|
56
|
-
}
|
|
57
|
-
if (!existsSync(componentTargetPath)) {
|
|
58
|
-
await mkdir(componentTargetPath, { recursive: true });
|
|
59
|
-
}
|
|
60
|
-
const componentFile = join(componentTargetPath, `${componentNameUpper}.tsx`);
|
|
61
|
-
|
|
62
|
-
// Read and adapt the TSX template
|
|
63
|
-
const templateComponentPath = join(templatePath, "Component.tsx");
|
|
64
|
-
if (existsSync(templateComponentPath)) {
|
|
65
|
-
let content = await readFile(templateComponentPath, "utf-8");
|
|
66
|
-
// Remplacement du nom du component et de la clé de traduction
|
|
67
|
-
content = content
|
|
68
|
-
.replace(/Component/g, componentNameUpper)
|
|
69
|
-
.replace(/componentPage/g, translationKey);
|
|
70
|
-
await writeFile(componentFile, content);
|
|
71
|
-
console.log(`📄 File created: ${componentFile}`);
|
|
72
|
-
} else {
|
|
73
|
-
console.error(
|
|
74
|
-
"❌ Template Component.tsx introuvable :",
|
|
75
|
-
templateComponentPath
|
|
76
|
-
);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Add the component to each language's JSON file (only folders)
|
|
80
|
-
const entries = await readdir(messagesPath, { withFileTypes: true });
|
|
81
|
-
const langDirs = entries.filter((e) => e.isDirectory()).map((e) => e.name);
|
|
82
|
-
const jsonTemplate = join(templatePath, "component.json");
|
|
83
|
-
if (!existsSync(jsonTemplate)) {
|
|
84
|
-
console.error("❌ Template component.json not found:", jsonTemplate);
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
const jsonContent = await readFile(jsonTemplate, "utf-8");
|
|
88
|
-
const parsed = JSON.parse(jsonContent);
|
|
89
|
-
|
|
90
|
-
for (const locale of langDirs) {
|
|
91
|
-
// Only process if messages/<locale> is a directory
|
|
92
|
-
const localeDir = join(messagesPath, locale);
|
|
93
|
-
if (
|
|
94
|
-
!existsSync(localeDir) ||
|
|
95
|
-
!require("node:fs").statSync(localeDir).isDirectory()
|
|
96
|
-
)
|
|
97
|
-
continue;
|
|
98
|
-
let jsonTarget;
|
|
99
|
-
if (pageScope) {
|
|
100
|
-
jsonTarget = join(messagesPath, locale, `${pageScope}.json`);
|
|
101
|
-
} else {
|
|
102
|
-
jsonTarget = join(messagesPath, locale, `_global_ui.json`);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
let current: Record<string, any> = {};
|
|
106
|
-
if (existsSync(jsonTarget)) {
|
|
107
|
-
const jsonFile = await readFile(jsonTarget, "utf-8");
|
|
108
|
-
current = JSON.parse(jsonFile) as Record<string, any>;
|
|
109
|
-
}
|
|
110
|
-
current[componentNameUpper] = parsed;
|
|
111
|
-
await writeFile(jsonTarget, JSON.stringify(current, null, 2));
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
console.log(
|
|
115
|
-
`✅ Component "${componentNameUpper}" added ${
|
|
116
|
-
pageScope ? `to page ${pageScope}` : "globally"
|
|
117
|
-
} with localized messages.`
|
|
118
|
-
);
|
|
119
|
-
}
|
package/src/lib/addPage.ts
DELETED
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
import { join } from "node:path";
|
|
2
|
-
import { mkdir, readFile, writeFile, readdir } from "node:fs/promises";
|
|
3
|
-
import prompts from "prompts";
|
|
4
|
-
import { capitalize, toFileName } from "./utils"; // Assuming you have a utility function to capitalize strings
|
|
5
|
-
import { existsSync } from "node:fs";
|
|
6
|
-
|
|
7
|
-
export async function addPage(args: string[]) {
|
|
8
|
-
let pageName = args[1];
|
|
9
|
-
if (!pageName || pageName.startsWith("-")) {
|
|
10
|
-
const response = await prompts.prompt({
|
|
11
|
-
type: "text",
|
|
12
|
-
name: "pageName",
|
|
13
|
-
message: "📝 Page name to add:",
|
|
14
|
-
validate: (name: string) => (name ? true : "Page name is required"),
|
|
15
|
-
});
|
|
16
|
-
pageName = response.pageName;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// Handle nested pages
|
|
20
|
-
let parentName = null;
|
|
21
|
-
let childName = null;
|
|
22
|
-
if (pageName.includes(".")) {
|
|
23
|
-
[parentName, childName] = pageName.split(".");
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
let shortFlags = args.find((arg) => /^-[A-Za-z]+$/.test(arg));
|
|
27
|
-
let longFlags = new Set(args.filter((a) => a.startsWith("--")));
|
|
28
|
-
const flags = new Set<string>();
|
|
29
|
-
|
|
30
|
-
if (!shortFlags && Array.from(longFlags).length === 0) {
|
|
31
|
-
shortFlags = "-LPl";
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
if (shortFlags) {
|
|
35
|
-
for (const char of shortFlags.slice(1)) {
|
|
36
|
-
switch (char) {
|
|
37
|
-
case "L":
|
|
38
|
-
flags.add("layout");
|
|
39
|
-
break;
|
|
40
|
-
case "P":
|
|
41
|
-
flags.add("page");
|
|
42
|
-
break;
|
|
43
|
-
case "l":
|
|
44
|
-
flags.add("loading");
|
|
45
|
-
break;
|
|
46
|
-
case "n":
|
|
47
|
-
flags.add("not-found");
|
|
48
|
-
break;
|
|
49
|
-
case "e":
|
|
50
|
-
flags.add("error");
|
|
51
|
-
break;
|
|
52
|
-
case "g":
|
|
53
|
-
flags.add("global-error");
|
|
54
|
-
break;
|
|
55
|
-
case "r":
|
|
56
|
-
flags.add("route");
|
|
57
|
-
break;
|
|
58
|
-
case "t":
|
|
59
|
-
flags.add("template");
|
|
60
|
-
break;
|
|
61
|
-
case "d":
|
|
62
|
-
flags.add("default");
|
|
63
|
-
break;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
for (const flag of [
|
|
69
|
-
"layout",
|
|
70
|
-
"page",
|
|
71
|
-
"loading",
|
|
72
|
-
"not-found",
|
|
73
|
-
"error",
|
|
74
|
-
"global-error",
|
|
75
|
-
"route",
|
|
76
|
-
"template",
|
|
77
|
-
"default",
|
|
78
|
-
]) {
|
|
79
|
-
if (longFlags.has("--" + flag)) flags.add(flag);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
const srcPath = join(process.cwd(), "src", "app", "[locale]");
|
|
83
|
-
const messagesPath = join(process.cwd(), "messages");
|
|
84
|
-
const templatePath = join(import.meta.dir, "..", "..", "templates", "Page");
|
|
85
|
-
const entries = await readdir(messagesPath, { withFileTypes: true });
|
|
86
|
-
const locales = entries.filter((e) => e.isDirectory()).map((e) => e.name);
|
|
87
|
-
|
|
88
|
-
// Create folders/files for nested or simple page
|
|
89
|
-
let uiPageDir, localePagePath, jsonFileName;
|
|
90
|
-
if (parentName && childName) {
|
|
91
|
-
uiPageDir = join(process.cwd(), "src", "ui", parentName, childName);
|
|
92
|
-
localePagePath = join(srcPath, parentName, childName);
|
|
93
|
-
jsonFileName = parentName;
|
|
94
|
-
} else {
|
|
95
|
-
uiPageDir = join(process.cwd(), "src", "ui", pageName);
|
|
96
|
-
localePagePath = join(srcPath, pageName);
|
|
97
|
-
jsonFileName = pageName;
|
|
98
|
-
}
|
|
99
|
-
if (!existsSync(uiPageDir)) {
|
|
100
|
-
await mkdir(uiPageDir, { recursive: true });
|
|
101
|
-
}
|
|
102
|
-
const uiPageFile = join(uiPageDir, "page-ui.tsx");
|
|
103
|
-
const uiPageTemplate = join(templatePath, "page-ui.tsx");
|
|
104
|
-
if (existsSync(uiPageTemplate)) {
|
|
105
|
-
let uiContent = await readFile(uiPageTemplate, "utf-8");
|
|
106
|
-
uiContent = uiContent
|
|
107
|
-
.replace(/template/g, childName || pageName)
|
|
108
|
-
.replace(/Template/g, capitalize(childName || pageName));
|
|
109
|
-
await writeFile(uiPageFile, uiContent);
|
|
110
|
-
console.log(`📄 File created: ${uiPageFile}`);
|
|
111
|
-
} else {
|
|
112
|
-
console.warn("⚠️ Template page-ui.tsx manquant.");
|
|
113
|
-
}
|
|
114
|
-
if (!existsSync(localePagePath)) {
|
|
115
|
-
await mkdir(localePagePath, { recursive: true });
|
|
116
|
-
}
|
|
117
|
-
for (const flag of flags) {
|
|
118
|
-
const filename = toFileName(flag);
|
|
119
|
-
const src = join(templatePath, filename);
|
|
120
|
-
const dst = join(localePagePath, filename);
|
|
121
|
-
if (!existsSync(src)) {
|
|
122
|
-
console.warn(`⚠️ Missing template file: ${filename}`);
|
|
123
|
-
continue;
|
|
124
|
-
}
|
|
125
|
-
const content = await readFile(src, "utf-8");
|
|
126
|
-
const replaced = content
|
|
127
|
-
.replace(/template/g, childName || pageName)
|
|
128
|
-
.replace(/Template/g, capitalize(childName || pageName));
|
|
129
|
-
await writeFile(dst, replaced);
|
|
130
|
-
console.log(`📄 File created: ${dst}`);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
// Add JSON to parent object if nested, otherwise create a simple file
|
|
134
|
-
const jsonTemplate = join(templatePath, "page.json");
|
|
135
|
-
if (!existsSync(jsonTemplate)) {
|
|
136
|
-
console.warn("⚠️ Missing template page.json.");
|
|
137
|
-
}
|
|
138
|
-
const content = await readFile(jsonTemplate, "utf-8");
|
|
139
|
-
const replaced = content
|
|
140
|
-
.replace(/template/g, childName || pageName)
|
|
141
|
-
.replace(/Template/g, capitalize(childName || pageName));
|
|
142
|
-
for (const locale of locales) {
|
|
143
|
-
// Only process if messages/<locale> is a directory
|
|
144
|
-
const localeDir = join(messagesPath, locale);
|
|
145
|
-
if (
|
|
146
|
-
!existsSync(localeDir) ||
|
|
147
|
-
!require("node:fs").statSync(localeDir).isDirectory()
|
|
148
|
-
)
|
|
149
|
-
continue;
|
|
150
|
-
const jsonTarget = join(messagesPath, locale, `${jsonFileName}.json`);
|
|
151
|
-
let current: Record<string, any> = {};
|
|
152
|
-
if (existsSync(jsonTarget)) {
|
|
153
|
-
const jsonFile = await readFile(jsonTarget, "utf-8");
|
|
154
|
-
try {
|
|
155
|
-
current = JSON.parse(jsonFile) as Record<string, any>;
|
|
156
|
-
} catch {
|
|
157
|
-
current = {};
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
if (parentName && childName) {
|
|
161
|
-
current[childName] = JSON.parse(replaced);
|
|
162
|
-
} else {
|
|
163
|
-
// fichier simple
|
|
164
|
-
current = JSON.parse(replaced);
|
|
165
|
-
}
|
|
166
|
-
await writeFile(jsonTarget, JSON.stringify(current, null, 2));
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
console.log(`✅ Page "${pageName}" with templates added for each locale.`);
|
|
170
|
-
}
|
package/src/lib/createProject.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { scaffoldProject } from "../scaffold";
|
|
2
|
-
export async function createProject(nameArg: string, force: boolean) {
|
|
3
|
-
const response = {
|
|
4
|
-
projectName: nameArg,
|
|
5
|
-
useTypescript: true,
|
|
6
|
-
useEslint: true,
|
|
7
|
-
useTailwind: true,
|
|
8
|
-
useSrcDir: true,
|
|
9
|
-
useTurbopack: true,
|
|
10
|
-
useI18n: true,
|
|
11
|
-
customAlias: false,
|
|
12
|
-
importAlias: "@/*",
|
|
13
|
-
force,
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
console.log(`📦 Creating project "${response.projectName}"...`);
|
|
17
|
-
await scaffoldProject(response);
|
|
18
|
-
}
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import { scaffoldProject } from "../scaffold";
|
|
2
|
-
import prompts from "prompts";
|
|
3
|
-
export async function createProjectWithPrompt() {
|
|
4
|
-
const response = await prompts.prompt([
|
|
5
|
-
{
|
|
6
|
-
type: "text",
|
|
7
|
-
name: "projectName",
|
|
8
|
-
message: "🧱 Project name:",
|
|
9
|
-
initial: "my-next-app",
|
|
10
|
-
},
|
|
11
|
-
{
|
|
12
|
-
type: "toggle",
|
|
13
|
-
name: "useTypescript",
|
|
14
|
-
message: "✔ Use TypeScript?",
|
|
15
|
-
initial: true,
|
|
16
|
-
active: "Yes",
|
|
17
|
-
inactive: "No",
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
type: "toggle",
|
|
21
|
-
name: "useEslint",
|
|
22
|
-
message: "✔ Use ESLint?",
|
|
23
|
-
initial: true,
|
|
24
|
-
active: "Yes",
|
|
25
|
-
inactive: "No",
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
type: "toggle",
|
|
29
|
-
name: "useTailwind",
|
|
30
|
-
message: "✔ Use Tailwind CSS?",
|
|
31
|
-
initial: true,
|
|
32
|
-
active: "Yes",
|
|
33
|
-
inactive: "No",
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
type: "toggle",
|
|
37
|
-
name: "useSrcDir",
|
|
38
|
-
message: "✔ Use `src/` directory?",
|
|
39
|
-
initial: false,
|
|
40
|
-
active: "Yes",
|
|
41
|
-
inactive: "No",
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
type: "toggle",
|
|
45
|
-
name: "useTurbopack",
|
|
46
|
-
message: "✔ Use Turbopack for `next dev`?",
|
|
47
|
-
initial: true,
|
|
48
|
-
active: "Yes",
|
|
49
|
-
inactive: "No",
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
type: "toggle",
|
|
53
|
-
name: "useI18n",
|
|
54
|
-
message: "✔ Use i18n with next-intl for translations?",
|
|
55
|
-
initial: true,
|
|
56
|
-
active: "Yes",
|
|
57
|
-
inactive: "No",
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
type: "toggle",
|
|
61
|
-
name: "customAlias",
|
|
62
|
-
message: "✔ Customize import alias (`@/*` by default)?",
|
|
63
|
-
initial: false,
|
|
64
|
-
active: "Yes",
|
|
65
|
-
inactive: "No",
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
type: (prev: boolean) => (prev ? "text" : null),
|
|
69
|
-
name: "importAlias",
|
|
70
|
-
message: "✔ What import alias would you like?",
|
|
71
|
-
initial: "@core/*",
|
|
72
|
-
},
|
|
73
|
-
]);
|
|
74
|
-
|
|
75
|
-
console.log("\n✅ Your choices:");
|
|
76
|
-
console.log(response);
|
|
77
|
-
|
|
78
|
-
await scaffoldProject(response);
|
|
79
|
-
}
|