@archon-research/uikit-cli 0.3.0-rohit-improve-cli.2 → 0.3.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/README.md +84 -32
- package/dist/cli.js +151 -443
- package/dist/cli.sh +10 -0
- package/dist/command-executor.js +41 -0
- package/dist/commands/format.js +36 -0
- package/dist/commands/link.js +162 -0
- package/dist/commands/lint.js +14 -0
- package/dist/commands/register.js +35 -0
- package/dist/commands/unlink.js +64 -0
- package/dist/fs-utils.js +56 -0
- package/dist/link-validator.js +80 -0
- package/dist/logger.js +43 -0
- package/dist/package-discovery.js +168 -0
- package/dist/shell-utils.js +9 -0
- package/dist/types.js +1 -0
- package/package.json +4 -3
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
/**
|
|
3
|
+
* Package and workspace discovery for monorepos
|
|
4
|
+
*/
|
|
5
|
+
export class PackageDiscovery {
|
|
6
|
+
fs;
|
|
7
|
+
constructor(fs) {
|
|
8
|
+
this.fs = fs;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Find consumer workspace root by walking up looking for package.json with workspaces
|
|
12
|
+
*/
|
|
13
|
+
findConsumerRoot(startDir) {
|
|
14
|
+
let current = startDir;
|
|
15
|
+
while (true) {
|
|
16
|
+
const pkgPath = path.join(current, 'package.json');
|
|
17
|
+
if (this.fs.exists(pkgPath)) {
|
|
18
|
+
try {
|
|
19
|
+
const pkg = this.fs.readJson(pkgPath);
|
|
20
|
+
if (pkg.workspaces) {
|
|
21
|
+
return current;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
// Continue searching if parse fails
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const parent = path.dirname(current);
|
|
29
|
+
if (parent === current) {
|
|
30
|
+
throw new Error(`Could not find consumer workspace root (no package.json with workspaces field)\n` +
|
|
31
|
+
`Searched from: ${startDir}\n` +
|
|
32
|
+
`Suggestion: Run from inside a workspace-based monorepo`);
|
|
33
|
+
}
|
|
34
|
+
current = parent;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Find uikit root by walking up looking for valid uikit monorepo structure
|
|
39
|
+
*/
|
|
40
|
+
findUIKitRoot(startDir) {
|
|
41
|
+
let current = startDir;
|
|
42
|
+
while (true) {
|
|
43
|
+
if (this.isValidUIKitRoot(current)) {
|
|
44
|
+
return current;
|
|
45
|
+
}
|
|
46
|
+
const parent = path.dirname(current);
|
|
47
|
+
if (parent === current) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
current = parent;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Find uikit root from consumer by looking for sibling "uikit" directory
|
|
55
|
+
*/
|
|
56
|
+
findUIKitRootFromConsumer(consumerRoot) {
|
|
57
|
+
const candidateNames = ['uikit'];
|
|
58
|
+
let current = consumerRoot;
|
|
59
|
+
while (true) {
|
|
60
|
+
for (const candidateName of candidateNames) {
|
|
61
|
+
const candidate = path.join(current, candidateName);
|
|
62
|
+
if (this.isValidUIKitRoot(candidate)) {
|
|
63
|
+
return candidate;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const parent = path.dirname(current);
|
|
67
|
+
if (parent === current) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
current = parent;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Check if directory is a valid uikit root (has design-system package)
|
|
75
|
+
*/
|
|
76
|
+
isValidUIKitRoot(rootDir) {
|
|
77
|
+
if (!this.fs.exists(rootDir)) {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
try {
|
|
81
|
+
const workspaces = this.loadWorkspaces(rootDir);
|
|
82
|
+
return workspaces.some((ws) => ws.name === '@archon-research/design-system');
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Load all workspaces from a monorepo root
|
|
90
|
+
*/
|
|
91
|
+
loadWorkspaces(rootDir) {
|
|
92
|
+
const patterns = this.getWorkspacePatterns(rootDir);
|
|
93
|
+
const workspaces = [];
|
|
94
|
+
if (process.env.UIKIT_DEBUG) {
|
|
95
|
+
console.log('[DEBUG loadWorkspaces] rootDir:', rootDir, 'patterns:', patterns);
|
|
96
|
+
}
|
|
97
|
+
for (const pattern of patterns) {
|
|
98
|
+
const resolved = this.resolveWorkspacePattern(rootDir, pattern);
|
|
99
|
+
if (process.env.UIKIT_DEBUG) {
|
|
100
|
+
console.log('[DEBUG loadWorkspaces] pattern:', pattern, 'resolved to:', resolved);
|
|
101
|
+
}
|
|
102
|
+
for (const dir of resolved) {
|
|
103
|
+
const pkgPath = path.join(dir, 'package.json');
|
|
104
|
+
if (!this.fs.exists(pkgPath)) {
|
|
105
|
+
if (process.env.UIKIT_DEBUG) {
|
|
106
|
+
console.log('[DEBUG loadWorkspaces] Skipping (no package.json):', dir);
|
|
107
|
+
}
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
try {
|
|
111
|
+
const pkg = this.fs.readJson(pkgPath);
|
|
112
|
+
workspaces.push({
|
|
113
|
+
name: pkg.name ?? null,
|
|
114
|
+
location: path.relative(rootDir, dir),
|
|
115
|
+
path: dir,
|
|
116
|
+
dependencies: pkg.dependencies ?? {},
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
// Skip invalid package.json
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return workspaces.filter((ws) => Boolean(ws.name));
|
|
125
|
+
}
|
|
126
|
+
getWorkspacePatterns(rootDir) {
|
|
127
|
+
const pkgPath = path.join(rootDir, 'package.json');
|
|
128
|
+
if (!this.fs.exists(pkgPath)) {
|
|
129
|
+
return [];
|
|
130
|
+
}
|
|
131
|
+
try {
|
|
132
|
+
const pkg = this.fs.readJson(pkgPath);
|
|
133
|
+
if (Array.isArray(pkg.workspaces)) {
|
|
134
|
+
return pkg.workspaces;
|
|
135
|
+
}
|
|
136
|
+
if (pkg.workspaces && Array.isArray(pkg.workspaces.packages)) {
|
|
137
|
+
return pkg.workspaces.packages;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
// Return empty if parse fails
|
|
142
|
+
}
|
|
143
|
+
return [];
|
|
144
|
+
}
|
|
145
|
+
resolveWorkspacePattern(rootDir, pattern) {
|
|
146
|
+
// Handle simple glob patterns like "packages/*"
|
|
147
|
+
if (pattern.includes('*')) {
|
|
148
|
+
// Only support "dir/*" pattern for now
|
|
149
|
+
if (pattern.endsWith('/*')) {
|
|
150
|
+
const baseDir = pattern.slice(0, -2);
|
|
151
|
+
const basePath = path.join(rootDir, baseDir);
|
|
152
|
+
if (!this.fs.exists(basePath) || !this.fs.isDirectory(basePath)) {
|
|
153
|
+
return [];
|
|
154
|
+
}
|
|
155
|
+
const entries = this.fs.readDir(basePath);
|
|
156
|
+
return entries
|
|
157
|
+
.filter((entry) => !entry.startsWith('.') && entry !== 'node_modules')
|
|
158
|
+
.map((entry) => path.join(basePath, entry))
|
|
159
|
+
.filter((p) => this.fs.isDirectory(p));
|
|
160
|
+
}
|
|
161
|
+
// Unsupported pattern
|
|
162
|
+
return [];
|
|
163
|
+
}
|
|
164
|
+
// Static pattern, return as-is if it's a directory
|
|
165
|
+
const fullPath = path.join(rootDir, pattern);
|
|
166
|
+
return this.fs.isDirectory(fullPath) ? [fullPath] : [];
|
|
167
|
+
}
|
|
168
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@archon-research/uikit-cli",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "CLI for managing local uikit package linking in consumer workspaces",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"build": "
|
|
7
|
+
"build": "tsgo -b && npm run wrapper",
|
|
8
|
+
"wrapper": "./scripts/create-wrapper.sh",
|
|
8
9
|
"clean": "rm -rf dist",
|
|
9
10
|
"type:check": "tsgo -p tsconfig.json --noEmit",
|
|
10
11
|
"prepare": "npm run build"
|
|
11
12
|
},
|
|
12
13
|
"bin": {
|
|
13
|
-
"uikit-cli": "./dist/cli.
|
|
14
|
+
"uikit-cli": "./dist/cli.sh"
|
|
14
15
|
},
|
|
15
16
|
"publishConfig": {
|
|
16
17
|
"access": "public"
|