toriya 0.0.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/package.json +10 -0
- package/src/index.js +231 -0
package/package.json
ADDED
package/src/index.js
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const https = require("https");
|
|
6
|
+
const { execSync } = require("child_process");
|
|
7
|
+
|
|
8
|
+
// TODO: UPDATE THIS URL TO YOUR REPO
|
|
9
|
+
const BASE_URL = "https://raw.githubusercontent.com/kranthik10/toriyaui/main";
|
|
10
|
+
|
|
11
|
+
function log(message) {
|
|
12
|
+
console.log(message);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function error(message) {
|
|
16
|
+
console.error("Error:", message);
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function ensureDir(dirPath) {
|
|
21
|
+
if (!fs.existsSync(dirPath)) {
|
|
22
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function fetchUrl(url) {
|
|
27
|
+
return new Promise((resolve, reject) => {
|
|
28
|
+
https.get(url, (res) => {
|
|
29
|
+
if (res.statusCode !== 200) {
|
|
30
|
+
// Consume response data to free up memory
|
|
31
|
+
res.resume();
|
|
32
|
+
reject(new Error(`Request Failed. Status Code: ${res.statusCode} (${url})`));
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
let data = "";
|
|
37
|
+
res.setEncoding("utf8");
|
|
38
|
+
res.on("data", (chunk) => {
|
|
39
|
+
data += chunk;
|
|
40
|
+
});
|
|
41
|
+
res.on("end", () => {
|
|
42
|
+
resolve(data);
|
|
43
|
+
});
|
|
44
|
+
}).on("error", (e) => {
|
|
45
|
+
reject(e);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async function loadRegistry() {
|
|
51
|
+
try {
|
|
52
|
+
const url = `${BASE_URL}/registry.json`;
|
|
53
|
+
log(`Fetching registry from ${url}...`);
|
|
54
|
+
const data = await fetchUrl(url);
|
|
55
|
+
return JSON.parse(data);
|
|
56
|
+
} catch (e) {
|
|
57
|
+
error(`Failed to fetch registry.json: ${e.message}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function getComponentFromRegistry(registry, name) {
|
|
62
|
+
const component = registry.find((c) => c.name === name);
|
|
63
|
+
if (!component) {
|
|
64
|
+
error(`Component '${name}' not found in registry.`);
|
|
65
|
+
}
|
|
66
|
+
return component;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function installDependencies(dependencies) {
|
|
70
|
+
if (!dependencies || dependencies.length === 0) return;
|
|
71
|
+
|
|
72
|
+
log(`Installing dependencies: ${dependencies.join(", ")}...`);
|
|
73
|
+
try {
|
|
74
|
+
const userAgent = process.env.npm_config_user_agent;
|
|
75
|
+
let command = "npm install";
|
|
76
|
+
if (userAgent) {
|
|
77
|
+
if (userAgent.startsWith("yarn")) {
|
|
78
|
+
command = "yarn add";
|
|
79
|
+
} else if (userAgent.startsWith("pnpm")) {
|
|
80
|
+
command = "pnpm add";
|
|
81
|
+
} else if (userAgent.startsWith("bun")) {
|
|
82
|
+
command = "bun add";
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
execSync(`${command} ${dependencies.join(" ")}`, { stdio: "inherit" });
|
|
87
|
+
} catch (e) {
|
|
88
|
+
error(`Failed to install dependencies: ${e.message}`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async function init(cwd) {
|
|
93
|
+
log("Initializing configuration...");
|
|
94
|
+
|
|
95
|
+
// 1. Create lib/utils.ts
|
|
96
|
+
const libDir = path.join(cwd, "lib");
|
|
97
|
+
ensureDir(libDir);
|
|
98
|
+
|
|
99
|
+
const utilsPath = path.join(libDir, "utils.ts");
|
|
100
|
+
if (!fs.existsSync(utilsPath)) {
|
|
101
|
+
const utilsContent = `import { type ClassValue, clsx } from 'clsx';
|
|
102
|
+
import { twMerge } from 'tailwind-merge';
|
|
103
|
+
|
|
104
|
+
export function cn(...inputs: ClassValue[]) {
|
|
105
|
+
return twMerge(clsx(inputs));
|
|
106
|
+
}
|
|
107
|
+
`;
|
|
108
|
+
// Check if we want to write utils. For now, let's skip unless specific requirement.
|
|
109
|
+
// Keeping it simple.
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// 2. Create components/ui dir and theme
|
|
113
|
+
const uiDir = path.join(cwd, "components", "ui");
|
|
114
|
+
ensureDir(uiDir);
|
|
115
|
+
|
|
116
|
+
const themeTarget = path.join(uiDir, "theme.ts");
|
|
117
|
+
if (!fs.existsSync(themeTarget)) {
|
|
118
|
+
try {
|
|
119
|
+
const themeContent = await fetchUrl(`${BASE_URL}/templates/base/theme.ts`);
|
|
120
|
+
fs.writeFileSync(themeTarget, themeContent);
|
|
121
|
+
log("Created components/ui/theme.ts");
|
|
122
|
+
} catch (e) {
|
|
123
|
+
error(`Failed to fetch default theme: ${e.message}`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const indexTarget = path.join(uiDir, "index.ts");
|
|
128
|
+
if (!fs.existsSync(indexTarget)) {
|
|
129
|
+
fs.writeFileSync(indexTarget, "export * from \"./theme\";\n");
|
|
130
|
+
log("Created components/ui/index.ts");
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
log("Initialization complete.");
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
async function add(cwd, componentName) {
|
|
137
|
+
const registry = await loadRegistry();
|
|
138
|
+
const component = getComponentFromRegistry(registry, componentName);
|
|
139
|
+
|
|
140
|
+
// 1. Install dependencies
|
|
141
|
+
installDependencies(component.dependencies);
|
|
142
|
+
|
|
143
|
+
// 2. Install details (sub-components)
|
|
144
|
+
if (component.registryDependencies) {
|
|
145
|
+
for (const dep of component.registryDependencies) {
|
|
146
|
+
log(`Installing dependency component: ${dep}`);
|
|
147
|
+
await add(cwd, dep);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// 3. Create component files
|
|
152
|
+
const uiDir = path.join(cwd, "components", "ui");
|
|
153
|
+
ensureDir(uiDir);
|
|
154
|
+
|
|
155
|
+
for (const file of component.files) {
|
|
156
|
+
try {
|
|
157
|
+
const content = await fetchUrl(`${BASE_URL}/${file.path}`);
|
|
158
|
+
const targetPath = path.join(cwd, file.target);
|
|
159
|
+
ensureDir(path.dirname(targetPath));
|
|
160
|
+
|
|
161
|
+
if (!fs.existsSync(targetPath)) {
|
|
162
|
+
fs.writeFileSync(targetPath, content);
|
|
163
|
+
log(`Created ${file.target}`);
|
|
164
|
+
} else {
|
|
165
|
+
log(`Skipped ${file.target} (already exists)`);
|
|
166
|
+
}
|
|
167
|
+
} catch (e) {
|
|
168
|
+
error(`Failed to write file ${file.target}: ${e.message}`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// 4. Update index.ts export
|
|
173
|
+
const indexTarget = path.join(uiDir, "index.ts");
|
|
174
|
+
if (fs.existsSync(indexTarget)) {
|
|
175
|
+
const exportLine = `export * from "./${componentName}";`;
|
|
176
|
+
const indexContent = fs.readFileSync(indexTarget, "utf8");
|
|
177
|
+
if (!indexContent.includes(exportLine)) {
|
|
178
|
+
fs.appendFileSync(indexTarget, exportLine + "\n");
|
|
179
|
+
log(`Updated index.ts`);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
async function list() {
|
|
185
|
+
const registry = await loadRegistry();
|
|
186
|
+
log("Available components:");
|
|
187
|
+
registry.forEach(c => log(`- ${c.name}`));
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// --- Main ---
|
|
191
|
+
|
|
192
|
+
async function main() {
|
|
193
|
+
const [command, arg] = process.argv.slice(2);
|
|
194
|
+
const cwd = process.cwd();
|
|
195
|
+
|
|
196
|
+
try {
|
|
197
|
+
switch (command) {
|
|
198
|
+
case "init":
|
|
199
|
+
await init(cwd);
|
|
200
|
+
break;
|
|
201
|
+
case "add":
|
|
202
|
+
if (!arg) {
|
|
203
|
+
error("Please specify a component name");
|
|
204
|
+
}
|
|
205
|
+
const components = process.argv.slice(3);
|
|
206
|
+
if (components.length === 0 && arg) {
|
|
207
|
+
await add(cwd, arg);
|
|
208
|
+
} else {
|
|
209
|
+
// Serial execution to avoid race conditions on dependencies
|
|
210
|
+
await add(cwd, arg);
|
|
211
|
+
for (const c of components) {
|
|
212
|
+
await add(cwd, c);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
break;
|
|
216
|
+
case "list":
|
|
217
|
+
await list();
|
|
218
|
+
break;
|
|
219
|
+
default:
|
|
220
|
+
log("Usage:");
|
|
221
|
+
log(" npx toriya init");
|
|
222
|
+
log(" npx toriya add <component>");
|
|
223
|
+
log(" npx toriya list");
|
|
224
|
+
break;
|
|
225
|
+
}
|
|
226
|
+
} catch (e) {
|
|
227
|
+
error(e.message);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
main();
|