@androbinco/library-cli 0.1.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.
@@ -0,0 +1,68 @@
1
+ import * as p from '@clack/prompts';
2
+ import fs from 'fs-extra';
3
+ import path from 'path';
4
+
5
+ export async function isDirectoryEmpty(dirPath) {
6
+ try {
7
+ if (!(await fs.pathExists(dirPath))) {
8
+ return true;
9
+ }
10
+ const files = await fs.readdir(dirPath);
11
+ return files.length === 0;
12
+ } catch (error) {
13
+ return false;
14
+ }
15
+ }
16
+
17
+ export function isWithinProjectRoot(targetPath) {
18
+ const projectRoot = path.resolve(process.cwd());
19
+ const resolvedTarget = path.resolve(targetPath);
20
+ const relative = path.relative(projectRoot, resolvedTarget);
21
+ return !relative.startsWith('..') && !path.isAbsolute(relative);
22
+ }
23
+
24
+ export async function copyComponent(component, templatesDir) {
25
+ const sourcePath = path.join(templatesDir, component.sourceDir);
26
+ const destBasePath = path.resolve(process.cwd(), 'src', 'components', component.name);
27
+
28
+ if (!(await fs.pathExists(sourcePath))) {
29
+ p.log.error(`Template for component "${component.name}" not found at ${sourcePath}.`);
30
+ return false;
31
+ }
32
+
33
+ if (!isWithinProjectRoot(destBasePath)) {
34
+ p.log.error('Destination path resolves outside of the current project. Aborting to avoid writing files in the wrong place.');
35
+ return false;
36
+ }
37
+
38
+ // Check if destination exists and is not empty
39
+ if (await fs.pathExists(destBasePath)) {
40
+ const isEmpty = await isDirectoryEmpty(destBasePath);
41
+
42
+ if (!isEmpty) {
43
+ const shouldOverwrite = await p.confirm({
44
+ message: `Directory ${destBasePath} already exists and is not empty. Overwrite?`,
45
+ initialValue: false
46
+ });
47
+
48
+ if (p.isCancel(shouldOverwrite) || !shouldOverwrite) {
49
+ p.log.info('Skipped copying this component.');
50
+ return false;
51
+ }
52
+ }
53
+ }
54
+
55
+ try {
56
+ // Ensure destination directory exists
57
+ await fs.ensureDir(destBasePath);
58
+
59
+ // Copy all files from source to destination
60
+ await fs.copy(sourcePath, destBasePath, { overwrite: true });
61
+
62
+ return true;
63
+ } catch (error) {
64
+ p.log.error(`Failed to copy component: ${error.message}`);
65
+ return false;
66
+ }
67
+ }
68
+