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.
Files changed (2) hide show
  1. package/package.json +10 -0
  2. package/src/index.js +231 -0
package/package.json ADDED
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "toriya",
3
+ "version": "0.0.1",
4
+ "publishConfig": {
5
+ "access": "public"
6
+ },
7
+ "bin": {
8
+ "toriya": "src/index.js"
9
+ }
10
+ }
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();