react-apps-ui 1.0.4 → 1.0.6
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/dist/index.js +74 -0
- package/package.json +1 -1
- package/src/index.ts +120 -0
package/dist/index.js
CHANGED
|
@@ -111,4 +111,78 @@ program
|
|
|
111
111
|
console.error(error);
|
|
112
112
|
}
|
|
113
113
|
});
|
|
114
|
+
// --- THE ADD COMMAND ---
|
|
115
|
+
program
|
|
116
|
+
.command("add [components...]")
|
|
117
|
+
.description("Add components to your project")
|
|
118
|
+
.action(async (components) => {
|
|
119
|
+
if (!components || components.length === 0) {
|
|
120
|
+
console.log(chalk_1.default.red("Please specify at least one component to add. (e.g., npx react-apps-ui add action-button)"));
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
// 1. SMART AUTO-DETECT: Check if they are using NativeWind by looking for the preset or config
|
|
124
|
+
const hasTailwind = fs_1.default.existsSync(path_1.default.join(process.cwd(), "tailwind.config.js")) ||
|
|
125
|
+
fs_1.default.existsSync(path_1.default.join(process.cwd(), "theme/tailwind-preset.js")) ||
|
|
126
|
+
fs_1.default.existsSync(path_1.default.join(process.cwd(), "src/theme/tailwind-preset.js"));
|
|
127
|
+
const engine = hasTailwind ? "mobile-nativewind" : "mobile-stylesheet";
|
|
128
|
+
console.log(chalk_1.default.dim(`\nDetected engine: ${engine}`));
|
|
129
|
+
const manifestUrl = `${REGISTRY_URL}/${engine}.json`;
|
|
130
|
+
try {
|
|
131
|
+
// 2. Fetch the massive JSON database
|
|
132
|
+
const res = await fetch(manifestUrl);
|
|
133
|
+
if (!res.ok)
|
|
134
|
+
throw new Error(`Failed to fetch registry: ${res.statusText}`);
|
|
135
|
+
const registry = await res.json();
|
|
136
|
+
// 3. RECURSIVE DEPENDENCY RESOLUTION
|
|
137
|
+
// If action-button needs wave-dots-loader, this automatically grabs it!
|
|
138
|
+
const componentsToAdd = new Set();
|
|
139
|
+
const resolveDependencies = (compName) => {
|
|
140
|
+
if (componentsToAdd.has(compName))
|
|
141
|
+
return; // Prevent infinite loops
|
|
142
|
+
componentsToAdd.add(compName);
|
|
143
|
+
const compData = registry.find((c) => c.name === compName);
|
|
144
|
+
if (compData && compData.registryDependencies) {
|
|
145
|
+
compData.registryDependencies.forEach(resolveDependencies);
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
// Run the resolver for every component the user typed in the terminal
|
|
149
|
+
components.forEach(resolveDependencies);
|
|
150
|
+
// We don't need to reinstall the theme if it was pulled as a dependency
|
|
151
|
+
componentsToAdd.delete("theme");
|
|
152
|
+
console.log(chalk_1.default.blue(`\nInstalling: ${Array.from(componentsToAdd).join(", ")}...`));
|
|
153
|
+
const hasSrcDir = fs_1.default.existsSync(path_1.default.join(process.cwd(), "src"));
|
|
154
|
+
// 4. WRITE THE FILES
|
|
155
|
+
for (const compName of componentsToAdd) {
|
|
156
|
+
const compData = registry.find((c) => c.name === compName);
|
|
157
|
+
if (!compData) {
|
|
158
|
+
console.log(chalk_1.default.red(` ❌ Component '${compName}' not found in registry.`));
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
for (const file of compData.files) {
|
|
162
|
+
const safeTarget = String(file.target || file.name || "unknown-file");
|
|
163
|
+
let finalTargetPath = path_1.default.join(process.cwd(), safeTarget);
|
|
164
|
+
if (hasSrcDir) {
|
|
165
|
+
finalTargetPath = path_1.default.join(process.cwd(), "src", safeTarget);
|
|
166
|
+
}
|
|
167
|
+
// Ensure the folder exists
|
|
168
|
+
fs_1.default.mkdirSync(path_1.default.dirname(finalTargetPath), {
|
|
169
|
+
recursive: true,
|
|
170
|
+
});
|
|
171
|
+
// Safe Write
|
|
172
|
+
if (!fs_1.default.existsSync(finalTargetPath)) {
|
|
173
|
+
fs_1.default.writeFileSync(finalTargetPath, file.content || "", "utf-8");
|
|
174
|
+
console.log(chalk_1.default.green(` Created ${safeTarget}`));
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
console.log(chalk_1.default.yellow(` ⚠️ ${safeTarget} already exists. Skipping.`));
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
console.log(chalk_1.default.blue("\n🎉 Components installed successfully!"));
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
console.log(chalk_1.default.red(`\nFailed to add components:`));
|
|
185
|
+
console.error(error);
|
|
186
|
+
}
|
|
187
|
+
});
|
|
114
188
|
program.parse();
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -165,4 +165,124 @@ program
|
|
|
165
165
|
}
|
|
166
166
|
});
|
|
167
167
|
|
|
168
|
+
// --- THE ADD COMMAND ---
|
|
169
|
+
program
|
|
170
|
+
.command("add [components...]")
|
|
171
|
+
.description("Add components to your project")
|
|
172
|
+
.action(async (components: string[]) => {
|
|
173
|
+
if (!components || components.length === 0) {
|
|
174
|
+
console.log(
|
|
175
|
+
chalk.red(
|
|
176
|
+
"Please specify at least one component to add. (e.g., npx react-apps-ui add action-button)",
|
|
177
|
+
),
|
|
178
|
+
);
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// 1. SMART AUTO-DETECT: Check if they are using NativeWind by looking for the preset or config
|
|
183
|
+
const hasTailwind =
|
|
184
|
+
fs.existsSync(path.join(process.cwd(), "tailwind.config.js")) ||
|
|
185
|
+
fs.existsSync(
|
|
186
|
+
path.join(process.cwd(), "theme/tailwind-preset.js"),
|
|
187
|
+
) ||
|
|
188
|
+
fs.existsSync(
|
|
189
|
+
path.join(process.cwd(), "src/theme/tailwind-preset.js"),
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
const engine = hasTailwind ? "mobile-nativewind" : "mobile-stylesheet";
|
|
193
|
+
|
|
194
|
+
console.log(chalk.dim(`\nDetected engine: ${engine}`));
|
|
195
|
+
const manifestUrl = `${REGISTRY_URL}/${engine}.json`;
|
|
196
|
+
|
|
197
|
+
try {
|
|
198
|
+
// 2. Fetch the massive JSON database
|
|
199
|
+
const res = await fetch(manifestUrl);
|
|
200
|
+
if (!res.ok)
|
|
201
|
+
throw new Error(`Failed to fetch registry: ${res.statusText}`);
|
|
202
|
+
const registry = await res.json();
|
|
203
|
+
|
|
204
|
+
// 3. RECURSIVE DEPENDENCY RESOLUTION
|
|
205
|
+
// If action-button needs wave-dots-loader, this automatically grabs it!
|
|
206
|
+
const componentsToAdd = new Set<string>();
|
|
207
|
+
|
|
208
|
+
const resolveDependencies = (compName: string) => {
|
|
209
|
+
if (componentsToAdd.has(compName)) return; // Prevent infinite loops
|
|
210
|
+
componentsToAdd.add(compName);
|
|
211
|
+
|
|
212
|
+
const compData = registry.find((c: any) => c.name === compName);
|
|
213
|
+
if (compData && compData.registryDependencies) {
|
|
214
|
+
compData.registryDependencies.forEach(resolveDependencies);
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
// Run the resolver for every component the user typed in the terminal
|
|
219
|
+
components.forEach(resolveDependencies);
|
|
220
|
+
|
|
221
|
+
// We don't need to reinstall the theme if it was pulled as a dependency
|
|
222
|
+
componentsToAdd.delete("theme");
|
|
223
|
+
|
|
224
|
+
console.log(
|
|
225
|
+
chalk.blue(
|
|
226
|
+
`\nInstalling: ${Array.from(componentsToAdd).join(", ")}...`,
|
|
227
|
+
),
|
|
228
|
+
);
|
|
229
|
+
|
|
230
|
+
const hasSrcDir = fs.existsSync(path.join(process.cwd(), "src"));
|
|
231
|
+
|
|
232
|
+
// 4. WRITE THE FILES
|
|
233
|
+
for (const compName of componentsToAdd) {
|
|
234
|
+
const compData = registry.find((c: any) => c.name === compName);
|
|
235
|
+
if (!compData) {
|
|
236
|
+
console.log(
|
|
237
|
+
chalk.red(
|
|
238
|
+
` ❌ Component '${compName}' not found in registry.`,
|
|
239
|
+
),
|
|
240
|
+
);
|
|
241
|
+
continue;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
for (const file of compData.files) {
|
|
245
|
+
const safeTarget = String(
|
|
246
|
+
file.target || file.name || "unknown-file",
|
|
247
|
+
);
|
|
248
|
+
let finalTargetPath = path.join(process.cwd(), safeTarget);
|
|
249
|
+
|
|
250
|
+
if (hasSrcDir) {
|
|
251
|
+
finalTargetPath = path.join(
|
|
252
|
+
process.cwd(),
|
|
253
|
+
"src",
|
|
254
|
+
safeTarget,
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Ensure the folder exists
|
|
259
|
+
fs.mkdirSync(path.dirname(finalTargetPath), {
|
|
260
|
+
recursive: true,
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
// Safe Write
|
|
264
|
+
if (!fs.existsSync(finalTargetPath)) {
|
|
265
|
+
fs.writeFileSync(
|
|
266
|
+
finalTargetPath,
|
|
267
|
+
file.content || "",
|
|
268
|
+
"utf-8",
|
|
269
|
+
);
|
|
270
|
+
console.log(chalk.green(` Created ${safeTarget}`));
|
|
271
|
+
} else {
|
|
272
|
+
console.log(
|
|
273
|
+
chalk.yellow(
|
|
274
|
+
` ⚠️ ${safeTarget} already exists. Skipping.`,
|
|
275
|
+
),
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
console.log(chalk.blue("\n🎉 Components installed successfully!"));
|
|
282
|
+
} catch (error) {
|
|
283
|
+
console.log(chalk.red(`\nFailed to add components:`));
|
|
284
|
+
console.error(error);
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
|
|
168
288
|
program.parse();
|