orizon 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.mjs +52 -0
- package/bin/init.mjs +257 -0
- package/package.json +8 -2
package/bin/cli.mjs
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import { dirname, resolve } from "node:path";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
|
|
7
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
const pkg = JSON.parse(
|
|
9
|
+
readFileSync(resolve(__dirname, "..", "package.json"), "utf8"),
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
const [command] = process.argv.slice(2);
|
|
13
|
+
|
|
14
|
+
function printHelp() {
|
|
15
|
+
console.log(`
|
|
16
|
+
orizon v${pkg.version}
|
|
17
|
+
|
|
18
|
+
Usage:
|
|
19
|
+
npx orizon <command>
|
|
20
|
+
|
|
21
|
+
Commands:
|
|
22
|
+
init Set up Orizon in your React + Vite project
|
|
23
|
+
|
|
24
|
+
Options:
|
|
25
|
+
--version Show version number
|
|
26
|
+
--help Show this help message
|
|
27
|
+
`);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
switch (command) {
|
|
31
|
+
case "init": {
|
|
32
|
+
const { init } = await import("./init.mjs");
|
|
33
|
+
await init();
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
case "--version":
|
|
38
|
+
case "-v":
|
|
39
|
+
console.log(pkg.version);
|
|
40
|
+
break;
|
|
41
|
+
|
|
42
|
+
case "--help":
|
|
43
|
+
case "-h":
|
|
44
|
+
case undefined:
|
|
45
|
+
printHelp();
|
|
46
|
+
break;
|
|
47
|
+
|
|
48
|
+
default:
|
|
49
|
+
console.error(`Unknown command: ${command}\n`);
|
|
50
|
+
printHelp();
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
package/bin/init.mjs
ADDED
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
|
|
4
|
+
import { resolve, join } from "node:path";
|
|
5
|
+
import { execSync } from "node:child_process";
|
|
6
|
+
import pc from "picocolors";
|
|
7
|
+
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
// Logging helpers
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
const log = {
|
|
12
|
+
step: (msg) => console.log(pc.cyan("●") + " " + msg),
|
|
13
|
+
success: (msg) => console.log(pc.green("✔") + " " + msg),
|
|
14
|
+
skip: (msg) => console.log(pc.yellow("⊘") + " " + pc.dim(msg)),
|
|
15
|
+
error: (msg) => console.error(pc.red("✖") + " " + msg),
|
|
16
|
+
info: (msg) => console.log(pc.dim(" " + msg)),
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
// Detect package manager
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
function detectPM(cwd) {
|
|
23
|
+
if (existsSync(join(cwd, "bun.lock")) || existsSync(join(cwd, "bun.lockb")))
|
|
24
|
+
return { name: "bun", install: "bun add -D" };
|
|
25
|
+
if (existsSync(join(cwd, "pnpm-lock.yaml")))
|
|
26
|
+
return { name: "pnpm", install: "pnpm add -D" };
|
|
27
|
+
if (existsSync(join(cwd, "yarn.lock")))
|
|
28
|
+
return { name: "yarn", install: "yarn add -D" };
|
|
29
|
+
return { name: "npm", install: "npm install -D" };
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
// Check if a package is already installed (deps or devDeps)
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
function isInstalled(pkg, pkgJson) {
|
|
36
|
+
const deps = pkgJson.dependencies || {};
|
|
37
|
+
const devDeps = pkgJson.devDependencies || {};
|
|
38
|
+
return Boolean(deps[pkg] || devDeps[pkg]);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
// Patch vite.config.ts — add tailwindcss import + plugin
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
function patchViteConfig(filePath) {
|
|
45
|
+
let content = readFileSync(filePath, "utf8");
|
|
46
|
+
let modified = false;
|
|
47
|
+
|
|
48
|
+
// 1. Add import if missing
|
|
49
|
+
if (!content.includes("@tailwindcss/vite")) {
|
|
50
|
+
// Find the last import statement and add after it
|
|
51
|
+
const importRegex = /^import\s.+$/gm;
|
|
52
|
+
let lastImportMatch = null;
|
|
53
|
+
let match;
|
|
54
|
+
while ((match = importRegex.exec(content)) !== null) {
|
|
55
|
+
lastImportMatch = match;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const importLine = 'import tailwindcss from "@tailwindcss/vite";';
|
|
59
|
+
|
|
60
|
+
if (lastImportMatch) {
|
|
61
|
+
const insertPos = lastImportMatch.index + lastImportMatch[0].length;
|
|
62
|
+
content =
|
|
63
|
+
content.slice(0, insertPos) + "\n" + importLine + content.slice(insertPos);
|
|
64
|
+
} else {
|
|
65
|
+
// No imports found — add at top
|
|
66
|
+
content = importLine + "\n" + content;
|
|
67
|
+
}
|
|
68
|
+
modified = true;
|
|
69
|
+
log.success("Added tailwindcss import to " + filePath.split(/[\\/]/).pop());
|
|
70
|
+
} else {
|
|
71
|
+
log.skip("tailwindcss import already in vite config");
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// 2. Add plugin if missing
|
|
75
|
+
if (!content.includes("tailwindcss()")) {
|
|
76
|
+
// Find plugins: [ and insert tailwindcss() after the opening bracket
|
|
77
|
+
const pluginsMatch = content.match(/plugins\s*:\s*\[/);
|
|
78
|
+
if (pluginsMatch) {
|
|
79
|
+
const insertPos = pluginsMatch.index + pluginsMatch[0].length;
|
|
80
|
+
content =
|
|
81
|
+
content.slice(0, insertPos) +
|
|
82
|
+
"tailwindcss(), " +
|
|
83
|
+
content.slice(insertPos);
|
|
84
|
+
modified = true;
|
|
85
|
+
log.success("Added tailwindcss() plugin to vite config");
|
|
86
|
+
} else {
|
|
87
|
+
log.error(
|
|
88
|
+
"Could not find plugins array in vite config — please add tailwindcss() manually",
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
} else {
|
|
92
|
+
log.skip("tailwindcss() plugin already in vite config");
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (modified) {
|
|
96
|
+
writeFileSync(filePath, content, "utf8");
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// ---------------------------------------------------------------------------
|
|
101
|
+
// Patch CSS file — prepend required @import / @source lines
|
|
102
|
+
// ---------------------------------------------------------------------------
|
|
103
|
+
function patchCSS(filePath, created) {
|
|
104
|
+
let content = created ? "" : readFileSync(filePath, "utf8");
|
|
105
|
+
const requiredLines = [
|
|
106
|
+
'@import "tailwindcss";',
|
|
107
|
+
'@import "orizon/preset.css";',
|
|
108
|
+
'@source "../node_modules/orizon/dist";',
|
|
109
|
+
];
|
|
110
|
+
|
|
111
|
+
const toAdd = [];
|
|
112
|
+
for (const line of requiredLines) {
|
|
113
|
+
if (!content.includes(line)) {
|
|
114
|
+
toAdd.push(line);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (toAdd.length === 0) {
|
|
119
|
+
log.skip("CSS file already has all required imports");
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Prepend missing lines at the top
|
|
124
|
+
content = toAdd.join("\n") + (content ? "\n" + content : "\n");
|
|
125
|
+
writeFileSync(filePath, content, "utf8");
|
|
126
|
+
log.success(
|
|
127
|
+
`Added ${toAdd.length} line${toAdd.length > 1 ? "s" : ""} to ${filePath.split(/[\\/]/).pop()}`,
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// ---------------------------------------------------------------------------
|
|
132
|
+
// Main init function
|
|
133
|
+
// ---------------------------------------------------------------------------
|
|
134
|
+
export async function init() {
|
|
135
|
+
const cwd = process.cwd();
|
|
136
|
+
|
|
137
|
+
console.log();
|
|
138
|
+
console.log(pc.bold(" Orizon") + pc.dim(" — setting up your project"));
|
|
139
|
+
console.log();
|
|
140
|
+
|
|
141
|
+
// -----------------------------------------------------------------------
|
|
142
|
+
// Step 0: Validate we're in a project
|
|
143
|
+
// -----------------------------------------------------------------------
|
|
144
|
+
const pkgPath = join(cwd, "package.json");
|
|
145
|
+
if (!existsSync(pkgPath)) {
|
|
146
|
+
log.error("No package.json found in current directory.");
|
|
147
|
+
log.info("Run this command from the root of your project.");
|
|
148
|
+
process.exit(1);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Check for vite config
|
|
152
|
+
const viteConfigTS = join(cwd, "vite.config.ts");
|
|
153
|
+
const viteConfigJS = join(cwd, "vite.config.js");
|
|
154
|
+
const viteConfigMTS = join(cwd, "vite.config.mts");
|
|
155
|
+
const viteConfigPath = existsSync(viteConfigTS)
|
|
156
|
+
? viteConfigTS
|
|
157
|
+
: existsSync(viteConfigJS)
|
|
158
|
+
? viteConfigJS
|
|
159
|
+
: existsSync(viteConfigMTS)
|
|
160
|
+
? viteConfigMTS
|
|
161
|
+
: null;
|
|
162
|
+
|
|
163
|
+
if (!viteConfigPath) {
|
|
164
|
+
log.error("No vite.config.ts/js found. Currently only Vite projects are supported.");
|
|
165
|
+
process.exit(1);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
log.success("Detected Vite project");
|
|
169
|
+
|
|
170
|
+
// -----------------------------------------------------------------------
|
|
171
|
+
// Step 1: Detect package manager
|
|
172
|
+
// -----------------------------------------------------------------------
|
|
173
|
+
const pm = detectPM(cwd);
|
|
174
|
+
log.info(`Using ${pc.bold(pm.name)}`);
|
|
175
|
+
console.log();
|
|
176
|
+
|
|
177
|
+
// -----------------------------------------------------------------------
|
|
178
|
+
// Step 2: Install dependencies
|
|
179
|
+
// -----------------------------------------------------------------------
|
|
180
|
+
log.step("Installing dependencies...");
|
|
181
|
+
|
|
182
|
+
const pkgJson = JSON.parse(readFileSync(pkgPath, "utf8"));
|
|
183
|
+
const toInstall = [];
|
|
184
|
+
|
|
185
|
+
if (!isInstalled("tailwindcss", pkgJson)) toInstall.push("tailwindcss");
|
|
186
|
+
if (!isInstalled("@tailwindcss/vite", pkgJson))
|
|
187
|
+
toInstall.push("@tailwindcss/vite");
|
|
188
|
+
|
|
189
|
+
if (toInstall.length > 0) {
|
|
190
|
+
const cmd = `${pm.install} ${toInstall.join(" ")}`;
|
|
191
|
+
log.info(pc.dim(`$ ${cmd}`));
|
|
192
|
+
try {
|
|
193
|
+
execSync(cmd, { cwd, stdio: "pipe" });
|
|
194
|
+
log.success(`Installed ${toInstall.join(", ")}`);
|
|
195
|
+
} catch (err) {
|
|
196
|
+
log.error(`Failed to install dependencies. Run manually:\n ${cmd}`);
|
|
197
|
+
process.exit(1);
|
|
198
|
+
}
|
|
199
|
+
} else {
|
|
200
|
+
log.skip("tailwindcss & @tailwindcss/vite already installed");
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
console.log();
|
|
204
|
+
|
|
205
|
+
// -----------------------------------------------------------------------
|
|
206
|
+
// Step 3: Patch vite config
|
|
207
|
+
// -----------------------------------------------------------------------
|
|
208
|
+
log.step("Configuring Vite...");
|
|
209
|
+
patchViteConfig(viteConfigPath);
|
|
210
|
+
console.log();
|
|
211
|
+
|
|
212
|
+
// -----------------------------------------------------------------------
|
|
213
|
+
// Step 4: Patch CSS
|
|
214
|
+
// -----------------------------------------------------------------------
|
|
215
|
+
log.step("Setting up CSS...");
|
|
216
|
+
|
|
217
|
+
const cssSearchOrder = [
|
|
218
|
+
"src/index.css",
|
|
219
|
+
"src/main.css",
|
|
220
|
+
"src/styles.css",
|
|
221
|
+
"src/globals.css",
|
|
222
|
+
"src/app.css",
|
|
223
|
+
"src/App.css",
|
|
224
|
+
];
|
|
225
|
+
|
|
226
|
+
let cssPath = null;
|
|
227
|
+
let cssCreated = false;
|
|
228
|
+
|
|
229
|
+
for (const candidate of cssSearchOrder) {
|
|
230
|
+
const full = join(cwd, candidate);
|
|
231
|
+
if (existsSync(full)) {
|
|
232
|
+
cssPath = full;
|
|
233
|
+
break;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (!cssPath) {
|
|
238
|
+
// Create src/index.css
|
|
239
|
+
const srcDir = join(cwd, "src");
|
|
240
|
+
if (!existsSync(srcDir)) mkdirSync(srcDir, { recursive: true });
|
|
241
|
+
cssPath = join(srcDir, "index.css");
|
|
242
|
+
cssCreated = true;
|
|
243
|
+
log.info("Creating src/index.css");
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
patchCSS(cssPath, cssCreated);
|
|
247
|
+
console.log();
|
|
248
|
+
|
|
249
|
+
// -----------------------------------------------------------------------
|
|
250
|
+
// Step 5: Done!
|
|
251
|
+
// -----------------------------------------------------------------------
|
|
252
|
+
console.log(pc.green(pc.bold(" ✓ Orizon is ready!")));
|
|
253
|
+
console.log();
|
|
254
|
+
console.log(" You can now import components:");
|
|
255
|
+
console.log(pc.cyan(' import { Button } from "orizon";'));
|
|
256
|
+
console.log();
|
|
257
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "orizon",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Ant Design API on shadcn/ui primitives — 68 components for React with Tailwind CSS",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -17,6 +17,9 @@
|
|
|
17
17
|
"typescript",
|
|
18
18
|
"accessible"
|
|
19
19
|
],
|
|
20
|
+
"bin": {
|
|
21
|
+
"orizon": "./bin/cli.mjs"
|
|
22
|
+
},
|
|
20
23
|
"sideEffects": false,
|
|
21
24
|
"main": "./dist/orizon.cjs.js",
|
|
22
25
|
"module": "./dist/orizon.es.js",
|
|
@@ -31,6 +34,7 @@
|
|
|
31
34
|
},
|
|
32
35
|
"files": [
|
|
33
36
|
"dist",
|
|
37
|
+
"bin",
|
|
34
38
|
"README.md",
|
|
35
39
|
"LICENSE"
|
|
36
40
|
],
|
|
@@ -58,7 +62,9 @@
|
|
|
58
62
|
"optional": true
|
|
59
63
|
}
|
|
60
64
|
},
|
|
61
|
-
"dependencies": {
|
|
65
|
+
"dependencies": {
|
|
66
|
+
"picocolors": "^1.1.1"
|
|
67
|
+
},
|
|
62
68
|
"devDependencies": {
|
|
63
69
|
"@base-ui/react": "^1.2.0",
|
|
64
70
|
"@eslint/js": "^9.39.1",
|