@rootnative/cli 0.0.0-alpha.7 → 0.0.0-alpha.8
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 +3 -0
- package/dist/index.mjs +114 -10
- package/llms.txt +5 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
<!-- Absolute URL: npm does not resolve repository-relative image paths. -->
|
|
2
|
+
<img src="https://raw.githubusercontent.com/rootnative/ui/main/assets/brand/rootnative-mark.png" alt="" width="88" height="88" />
|
|
3
|
+
|
|
1
4
|
# rootnative
|
|
2
5
|
|
|
3
6
|
CLI for adding [RootNative UI](https://github.com/rootnative/ui) components directly into your React Native or Expo project. Inspired by [shadcn/ui](https://ui.shadcn.com) — you own the code.
|
package/dist/index.mjs
CHANGED
|
@@ -697,6 +697,46 @@ function isValidTemplate(value) {
|
|
|
697
697
|
function slugify(input) {
|
|
698
698
|
return input.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
699
699
|
}
|
|
700
|
+
function isCurrentDirName(input) {
|
|
701
|
+
const trimmed = input.trim();
|
|
702
|
+
return trimmed === "." || trimmed === "./" || trimmed === ".\\";
|
|
703
|
+
}
|
|
704
|
+
function resolveProjectTarget(input, cwd) {
|
|
705
|
+
const currentDir = path7.resolve(cwd);
|
|
706
|
+
if (isCurrentDirName(input)) {
|
|
707
|
+
const projectName2 = slugify(path7.basename(currentDir));
|
|
708
|
+
if (!projectName2) return { ok: false, reason: "invalid-folder-name" };
|
|
709
|
+
return {
|
|
710
|
+
ok: true,
|
|
711
|
+
target: { projectName: projectName2, targetDir: currentDir, useCurrentDir: true }
|
|
712
|
+
};
|
|
713
|
+
}
|
|
714
|
+
const projectName = slugify(input);
|
|
715
|
+
if (!projectName) return { ok: false, reason: "invalid-name" };
|
|
716
|
+
const targetDir = path7.resolve(currentDir, projectName);
|
|
717
|
+
return {
|
|
718
|
+
ok: true,
|
|
719
|
+
target: {
|
|
720
|
+
projectName,
|
|
721
|
+
targetDir,
|
|
722
|
+
useCurrentDir: targetDir === currentDir
|
|
723
|
+
}
|
|
724
|
+
};
|
|
725
|
+
}
|
|
726
|
+
function templateFiles(templateName) {
|
|
727
|
+
return [
|
|
728
|
+
...TEMPLATE_CONFIGS[templateName].textFiles,
|
|
729
|
+
...TEMPLATE_OPTIONAL_TEXT_FILES,
|
|
730
|
+
...TEMPLATE_BINARY_FILES
|
|
731
|
+
];
|
|
732
|
+
}
|
|
733
|
+
async function findConflicts(dir, files) {
|
|
734
|
+
const conflicts = [];
|
|
735
|
+
for (const file of files) {
|
|
736
|
+
if (await fs5.pathExists(path7.join(dir, file))) conflicts.push(file);
|
|
737
|
+
}
|
|
738
|
+
return conflicts;
|
|
739
|
+
}
|
|
700
740
|
function toDisplayName(slug) {
|
|
701
741
|
return slug.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
702
742
|
}
|
|
@@ -763,9 +803,9 @@ async function createCommand(name, options = {}) {
|
|
|
763
803
|
}
|
|
764
804
|
templateName = value;
|
|
765
805
|
}
|
|
766
|
-
let
|
|
806
|
+
let nameInput;
|
|
767
807
|
if (name) {
|
|
768
|
-
|
|
808
|
+
nameInput = name;
|
|
769
809
|
} else {
|
|
770
810
|
const { value } = await prompts2({
|
|
771
811
|
type: "text",
|
|
@@ -778,8 +818,26 @@ async function createCommand(name, options = {}) {
|
|
|
778
818
|
logger.info("Create cancelled.");
|
|
779
819
|
return;
|
|
780
820
|
}
|
|
781
|
-
|
|
821
|
+
nameInput = value;
|
|
822
|
+
}
|
|
823
|
+
const resolved = resolveProjectTarget(nameInput, process.cwd());
|
|
824
|
+
if (!resolved.ok) {
|
|
825
|
+
if (resolved.reason === "invalid-folder-name") {
|
|
826
|
+
logger.error(
|
|
827
|
+
`Cannot make a project name from the folder ${chalk3.bold(
|
|
828
|
+
path7.basename(path7.resolve(process.cwd()))
|
|
829
|
+
)}.`
|
|
830
|
+
);
|
|
831
|
+
logger.info(
|
|
832
|
+
`Give a name instead: ${chalk3.bold("npx rootnative create my-app")}`
|
|
833
|
+
);
|
|
834
|
+
} else {
|
|
835
|
+
logger.error(`${chalk3.bold(nameInput)} is not a usable project name.`);
|
|
836
|
+
logger.info("Use letters and numbers, for example my-app.");
|
|
837
|
+
}
|
|
838
|
+
process.exit(1);
|
|
782
839
|
}
|
|
840
|
+
const { projectName, targetDir, useCurrentDir } = resolved.target;
|
|
783
841
|
let displayName;
|
|
784
842
|
if (options.yes) {
|
|
785
843
|
displayName = toDisplayName(projectName);
|
|
@@ -820,8 +878,34 @@ async function createCommand(name, options = {}) {
|
|
|
820
878
|
}
|
|
821
879
|
packageManager = value;
|
|
822
880
|
}
|
|
823
|
-
|
|
824
|
-
|
|
881
|
+
if (useCurrentDir) {
|
|
882
|
+
const conflicts = await findConflicts(
|
|
883
|
+
targetDir,
|
|
884
|
+
templateFiles(templateName)
|
|
885
|
+
);
|
|
886
|
+
if (conflicts.length > 0) {
|
|
887
|
+
logger.warn("These files in the current directory will be overwritten:");
|
|
888
|
+
for (const file of conflicts) {
|
|
889
|
+
logger.info(` ${file}`);
|
|
890
|
+
}
|
|
891
|
+
logger.break();
|
|
892
|
+
if (options.yes) {
|
|
893
|
+
logger.error("Nothing was changed.");
|
|
894
|
+
logger.info("Move or delete these files, then run create again.");
|
|
895
|
+
process.exit(1);
|
|
896
|
+
}
|
|
897
|
+
const { overwrite } = await prompts2({
|
|
898
|
+
type: "confirm",
|
|
899
|
+
name: "overwrite",
|
|
900
|
+
message: "Overwrite them?",
|
|
901
|
+
initial: false
|
|
902
|
+
});
|
|
903
|
+
if (!overwrite) {
|
|
904
|
+
logger.info("Create cancelled.");
|
|
905
|
+
return;
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
} else if (await fs5.pathExists(targetDir)) {
|
|
825
909
|
if (options.yes) {
|
|
826
910
|
logger.warn(`Directory ${chalk3.bold(projectName)} already exists.`);
|
|
827
911
|
process.exit(1);
|
|
@@ -829,7 +913,7 @@ async function createCommand(name, options = {}) {
|
|
|
829
913
|
const { overwrite } = await prompts2({
|
|
830
914
|
type: "confirm",
|
|
831
915
|
name: "overwrite",
|
|
832
|
-
message: `Directory ${chalk3.bold(projectName)} already exists.
|
|
916
|
+
message: `Directory ${chalk3.bold(projectName)} already exists. Delete it and all of its contents?`,
|
|
833
917
|
initial: false
|
|
834
918
|
});
|
|
835
919
|
if (!overwrite) {
|
|
@@ -913,7 +997,9 @@ async function createCommand(name, options = {}) {
|
|
|
913
997
|
logger.break();
|
|
914
998
|
logger.error("Failed to install dependencies");
|
|
915
999
|
logger.info(
|
|
916
|
-
`Run manually: ${chalk3.bold(
|
|
1000
|
+
`Run manually: ${chalk3.bold(
|
|
1001
|
+
useCurrentDir ? installCmd : `cd ${projectName} && ${installCmd}`
|
|
1002
|
+
)}`
|
|
917
1003
|
);
|
|
918
1004
|
}
|
|
919
1005
|
}
|
|
@@ -921,7 +1007,9 @@ async function createCommand(name, options = {}) {
|
|
|
921
1007
|
logger.success(`Project ${chalk3.bold(displayName)} is ready!`);
|
|
922
1008
|
logger.break();
|
|
923
1009
|
logger.info("Next steps:");
|
|
924
|
-
|
|
1010
|
+
if (!useCurrentDir) {
|
|
1011
|
+
logger.info(` cd ${projectName}`);
|
|
1012
|
+
}
|
|
925
1013
|
if (!shouldInstall) {
|
|
926
1014
|
logger.info(` ${getInstallCommand2(packageManager)}`);
|
|
927
1015
|
}
|
|
@@ -2006,10 +2094,26 @@ function isValidPackageManager(value) {
|
|
|
2006
2094
|
return PACKAGE_MANAGERS.includes(value);
|
|
2007
2095
|
}
|
|
2008
2096
|
|
|
2097
|
+
// src/lib/version.ts
|
|
2098
|
+
import { createRequire } from "module";
|
|
2099
|
+
var UNKNOWN_VERSION = "0.0.0-unknown";
|
|
2100
|
+
var PACKAGE_JSON_CANDIDATES = ["../package.json", "../../package.json"];
|
|
2101
|
+
function getCliVersion() {
|
|
2102
|
+
const require2 = createRequire(import.meta.url);
|
|
2103
|
+
for (const candidate of PACKAGE_JSON_CANDIDATES) {
|
|
2104
|
+
try {
|
|
2105
|
+
const pkg = require2(candidate);
|
|
2106
|
+
if (pkg.name === "@rootnative/cli" && pkg.version) return pkg.version;
|
|
2107
|
+
} catch {
|
|
2108
|
+
}
|
|
2109
|
+
}
|
|
2110
|
+
return UNKNOWN_VERSION;
|
|
2111
|
+
}
|
|
2112
|
+
|
|
2009
2113
|
// src/index.ts
|
|
2010
2114
|
var program = new Command();
|
|
2011
|
-
program.name("rootnative").description("Add RootNative UI components to your React Native project").version(
|
|
2012
|
-
program.command("create").description("Create a new project with RootNative UI pre-configured").argument("[name]",
|
|
2115
|
+
program.name("rootnative").description("Add RootNative UI components to your React Native project").version(getCliVersion());
|
|
2116
|
+
program.command("create").description("Create a new project with RootNative UI pre-configured").argument("[name]", 'Project name, or "." to use the current directory').option("-y, --yes", "Skip prompts and use defaults", false).option("-t, --template <name>", "Template to use (blank, with-router)").option(
|
|
2013
2117
|
"--package-manager <pm>",
|
|
2014
2118
|
`Package manager to use (${PACKAGE_MANAGERS.join(", ")})`
|
|
2015
2119
|
).action(async (name, options) => {
|
package/llms.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @rootnative/cli — CLI for RootNative UI
|
|
2
2
|
|
|
3
|
-
> Version: 0.0.0-alpha.
|
|
3
|
+
> Version: 0.0.0-alpha.8
|
|
4
4
|
> Binary: `rootnative`
|
|
5
5
|
> Requirements: Node >=18
|
|
6
6
|
|
|
@@ -15,9 +15,12 @@ Create a new project with RootNative UI pre-configured. Fetches the quickstart t
|
|
|
15
15
|
```bash
|
|
16
16
|
npx rootnative create # Interactive
|
|
17
17
|
npx rootnative create my-app # With name
|
|
18
|
+
npx rootnative create . # Into the current directory, named after it
|
|
18
19
|
npx rootnative create my-app -y # Non-interactive, accept defaults
|
|
19
20
|
```
|
|
20
21
|
|
|
22
|
+
Pass `.` to scaffold into the directory you are already in. The project name comes from that directory's name, and the directory is never deleted — the CLI lists any file the template would overwrite and asks first (with `-y` it stops and changes nothing). A named project goes into a new subdirectory, and the CLI asks before it deletes an existing one.
|
|
23
|
+
|
|
21
24
|
Options:
|
|
22
25
|
- `-y, --yes` — Skip prompts and use defaults
|
|
23
26
|
- `-t, --template <name>` — Template to use (`blank`, `with-router`)
|
|
@@ -47,7 +50,7 @@ Creates `rootnative.json`:
|
|
|
47
50
|
"$schema": "https://rootnative.github.io/ui/schema.json",
|
|
48
51
|
"aliases": { "components": "@/components/ui", "lib": "@/lib" },
|
|
49
52
|
"registryUrl": "https://raw.githubusercontent.com/rootnative/ui",
|
|
50
|
-
"registryVersion": "v0.0.0-alpha.
|
|
53
|
+
"registryVersion": "v0.0.0-alpha.8"
|
|
51
54
|
}
|
|
52
55
|
```
|
|
53
56
|
|