@ng-shangjc/cli 1.0.0 → 1.0.2-beta
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/commands/install.js +152 -22
- package/package.json +3 -2
- package/src/commands/install.ts +178 -23
package/dist/commands/install.js
CHANGED
|
@@ -56,7 +56,7 @@ const AVAILABLE_COMPONENTS = [
|
|
|
56
56
|
'alert'
|
|
57
57
|
];
|
|
58
58
|
const COMPONENT_DEPENDENCIES = {
|
|
59
|
-
button: ['utils'],
|
|
59
|
+
button: ['utils', 'class-variance-authority'],
|
|
60
60
|
input: ['utils'],
|
|
61
61
|
card: ['utils'],
|
|
62
62
|
switch: ['utils'],
|
|
@@ -71,30 +71,24 @@ const COMPONENT_DEPENDENCIES = {
|
|
|
71
71
|
};
|
|
72
72
|
const COMPONENT_FILES = {
|
|
73
73
|
button: [
|
|
74
|
-
'button.component.ts'
|
|
75
|
-
'button.metadata.ts'
|
|
74
|
+
'button.component.ts'
|
|
76
75
|
],
|
|
77
76
|
input: [
|
|
78
|
-
'input.component.ts'
|
|
79
|
-
'input.metadata.ts'
|
|
77
|
+
'input.component.ts'
|
|
80
78
|
],
|
|
81
79
|
card: [
|
|
82
|
-
'card.component.ts'
|
|
83
|
-
'card.metadata.ts'
|
|
80
|
+
'card.component.ts'
|
|
84
81
|
],
|
|
85
82
|
switch: [
|
|
86
|
-
'switch.component.ts'
|
|
87
|
-
'switch.metadata.ts'
|
|
83
|
+
'switch.component.ts'
|
|
88
84
|
],
|
|
89
85
|
dialog: [
|
|
90
86
|
'dialog.component.ts',
|
|
91
|
-
'dialog.service.ts'
|
|
92
|
-
'dialog.metadata.ts'
|
|
87
|
+
'dialog.service.ts'
|
|
93
88
|
],
|
|
94
89
|
tooltip: [
|
|
95
90
|
'tooltip.component.ts',
|
|
96
|
-
'tooltip.directive.ts'
|
|
97
|
-
'tooltip.metadata.ts'
|
|
91
|
+
'tooltip.directive.ts'
|
|
98
92
|
],
|
|
99
93
|
select: [
|
|
100
94
|
'select.component.ts'
|
|
@@ -181,11 +175,18 @@ async function installComponent(componentName, options) {
|
|
|
181
175
|
if (dependencies.includes('utils')) {
|
|
182
176
|
await installUtils();
|
|
183
177
|
}
|
|
178
|
+
// Install external dependencies (non-utils)
|
|
179
|
+
const externalDeps = dependencies.filter(dep => dep !== 'utils');
|
|
180
|
+
if (externalDeps.length > 0) {
|
|
181
|
+
await installExternalDependencies(externalDeps, componentName);
|
|
182
|
+
}
|
|
183
|
+
// Install the component package itself
|
|
184
|
+
await installComponentPackage(componentName);
|
|
184
185
|
// Create destination directory
|
|
185
186
|
const destDir = path.join(process.cwd(), componentsPath, componentName);
|
|
186
187
|
await fs.ensureDir(destDir);
|
|
187
|
-
// Get source directory
|
|
188
|
-
const sourceDir = path.join(
|
|
188
|
+
// Get source directory from installed npm package
|
|
189
|
+
const sourceDir = path.join(process.cwd(), 'node_modules', '@ng-shangjc', componentName, 'src', 'lib');
|
|
189
190
|
// Copy component files
|
|
190
191
|
const files = COMPONENT_FILES[componentName];
|
|
191
192
|
for (const file of files) {
|
|
@@ -203,22 +204,21 @@ async function installComponent(componentName, options) {
|
|
|
203
204
|
const indexContent = generateIndexFile(componentName, files, config.componentType);
|
|
204
205
|
await fs.writeFile(path.join(destDir, 'index.ts'), indexContent);
|
|
205
206
|
console.log(`✅ Created index.ts`);
|
|
206
|
-
// Copy README
|
|
207
|
-
const readmePath = path.join(__dirname, '..', '..', '..', 'packages', componentName, 'README.md');
|
|
208
|
-
if (await fs.pathExists(readmePath)) {
|
|
209
|
-
await fs.copy(readmePath, path.join(destDir, 'README.md'));
|
|
210
|
-
console.log(`✅ Copied README.md`);
|
|
211
|
-
}
|
|
212
207
|
// Update configuration
|
|
213
208
|
if (!config.installedComponents.includes(componentName)) {
|
|
214
209
|
config.installedComponents.push(componentName);
|
|
215
210
|
await fs.writeJson(configPath, config, { spaces: 2 });
|
|
216
211
|
console.log(`✅ Updated shangjc.config.json`);
|
|
217
212
|
}
|
|
213
|
+
// Create/update barrel index.ts in the main ui/shangjc folder
|
|
214
|
+
await createOrUpdateBarrelIndex(config.componentsPath, config.installedComponents);
|
|
218
215
|
console.log(`🎉 Successfully installed ${componentName} component!`);
|
|
219
216
|
console.log(`\n📁 Files installed to: ${destDir}`);
|
|
220
217
|
console.log(`\n📖 Usage:`);
|
|
218
|
+
console.log(`// Individual import:`);
|
|
221
219
|
console.log(`import { ${getComponentClassName(componentName)} } from './${componentsPath}/${componentName}';`);
|
|
220
|
+
console.log(`// Or barrel import (if multiple components):`);
|
|
221
|
+
console.log(`import { ${getComponentClassName(componentName)} } from './${componentsPath}';`);
|
|
222
222
|
}
|
|
223
223
|
catch (error) {
|
|
224
224
|
console.error('❌ Installation failed:', error);
|
|
@@ -232,7 +232,7 @@ async function installUtils() {
|
|
|
232
232
|
const utilsPath = path.join(process.cwd(), 'node_modules', '@ng-shangjc', 'utils');
|
|
233
233
|
if (!fs.existsSync(utilsPath)) {
|
|
234
234
|
console.log('Installing @ng-shangjc/utils...');
|
|
235
|
-
(0, child_process_1.execSync)('npm install @ng-shangjc/utils', { stdio: 'inherit' });
|
|
235
|
+
(0, child_process_1.execSync)('npm install --save-dev @ng-shangjc/utils', { stdio: 'inherit' });
|
|
236
236
|
}
|
|
237
237
|
else {
|
|
238
238
|
console.log('✅ @ng-shangjc/utils already installed');
|
|
@@ -243,6 +243,115 @@ async function installUtils() {
|
|
|
243
243
|
throw error;
|
|
244
244
|
}
|
|
245
245
|
}
|
|
246
|
+
async function installExternalDependencies(dependencies, componentName) {
|
|
247
|
+
// Read the component's package.json to get exact versions
|
|
248
|
+
const componentPackagePath = path.join(process.cwd(), 'node_modules', '@ng-shangjc', componentName, 'package.json');
|
|
249
|
+
let componentPackage;
|
|
250
|
+
try {
|
|
251
|
+
componentPackage = await fs.readJson(componentPackagePath);
|
|
252
|
+
}
|
|
253
|
+
catch (error) {
|
|
254
|
+
console.error(`❌ Failed to read component package.json:`, error);
|
|
255
|
+
throw error;
|
|
256
|
+
}
|
|
257
|
+
for (const dependency of dependencies) {
|
|
258
|
+
console.log(`📦 Installing ${dependency} dependency...`);
|
|
259
|
+
try {
|
|
260
|
+
// Get the exact version from component's peerDependencies or dependencies
|
|
261
|
+
const version = componentPackage.peerDependencies?.[dependency] || componentPackage.dependencies?.[dependency];
|
|
262
|
+
if (!version) {
|
|
263
|
+
console.warn(`⚠️ Could not find version for ${dependency} in component package.json, installing latest...`);
|
|
264
|
+
}
|
|
265
|
+
// Check if dependency is already installed in node_modules
|
|
266
|
+
const depPath = path.join(process.cwd(), 'node_modules', dependency);
|
|
267
|
+
if (!fs.existsSync(depPath)) {
|
|
268
|
+
const installSpec = version ? `${dependency}@${version}` : dependency;
|
|
269
|
+
console.log(`Installing ${installSpec}...`);
|
|
270
|
+
(0, child_process_1.execSync)(`npm install ${installSpec}`, { stdio: 'inherit' });
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
console.log(`✅ ${dependency} already installed`);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
catch (error) {
|
|
277
|
+
console.error(`❌ Failed to install ${dependency}:`, error);
|
|
278
|
+
throw error;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
async function installComponentPackage(componentName) {
|
|
283
|
+
console.log(`📦 Installing ${componentName} package...`);
|
|
284
|
+
try {
|
|
285
|
+
// Check if component is already installed in node_modules
|
|
286
|
+
const componentPath = path.join(process.cwd(), 'node_modules', '@ng-shangjc', componentName);
|
|
287
|
+
if (!fs.existsSync(componentPath)) {
|
|
288
|
+
console.log(`Installing @ng-shangjc/${componentName}...`);
|
|
289
|
+
(0, child_process_1.execSync)(`npm install --save-dev @ng-shangjc/${componentName}`, { stdio: 'inherit' });
|
|
290
|
+
}
|
|
291
|
+
else {
|
|
292
|
+
console.log(`✅ @ng-shangjc/${componentName} already installed`);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
catch (error) {
|
|
296
|
+
console.error(`❌ Failed to install ${componentName} package:`, error);
|
|
297
|
+
console.log(`🔄 Attempting to download files directly...`);
|
|
298
|
+
// Fallback: try to download files directly from npm registry
|
|
299
|
+
try {
|
|
300
|
+
await downloadComponentFiles(componentName);
|
|
301
|
+
console.log(`✅ Successfully downloaded ${componentName} files directly`);
|
|
302
|
+
}
|
|
303
|
+
catch (downloadError) {
|
|
304
|
+
console.error(`❌ Failed to download ${componentName} files:`, downloadError);
|
|
305
|
+
throw new Error(`Failed to install ${componentName}: Package installation and direct download both failed`);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
async function downloadComponentFiles(componentName) {
|
|
310
|
+
const https = require('https');
|
|
311
|
+
const tar = require('tar');
|
|
312
|
+
return new Promise((resolve, reject) => {
|
|
313
|
+
const packageUrl = `https://registry.npmjs.org/@ng-shangjc/${componentName}/-/${componentName}-1.0.0.tgz`;
|
|
314
|
+
const tempDir = path.join(process.cwd(), '.ng-shangjc-temp');
|
|
315
|
+
// Ensure temp directory exists
|
|
316
|
+
fs.ensureDirSync(tempDir);
|
|
317
|
+
const file = fs.createWriteStream(path.join(tempDir, `${componentName}.tgz`));
|
|
318
|
+
https.get(packageUrl, (response) => {
|
|
319
|
+
if (response.statusCode !== 200) {
|
|
320
|
+
reject(new Error(`Failed to download package: ${response.statusCode}`));
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
response.pipe(file);
|
|
324
|
+
file.on('finish', () => {
|
|
325
|
+
file.close();
|
|
326
|
+
// Extract the tarball
|
|
327
|
+
fs.createReadStream(path.join(tempDir, `${componentName}.tgz`))
|
|
328
|
+
.pipe(tar.extract({
|
|
329
|
+
cwd: tempDir,
|
|
330
|
+
strip: 1 // Remove the package folder
|
|
331
|
+
}))
|
|
332
|
+
.on('finish', () => {
|
|
333
|
+
// Copy the extracted files to node_modules structure
|
|
334
|
+
const sourceDir = path.join(tempDir, 'src', 'lib');
|
|
335
|
+
const targetDir = path.join(process.cwd(), 'node_modules', '@ng-shangjc', componentName, 'src', 'lib');
|
|
336
|
+
fs.ensureDirSync(path.dirname(targetDir));
|
|
337
|
+
if (fs.existsSync(sourceDir)) {
|
|
338
|
+
fs.copySync(sourceDir, targetDir);
|
|
339
|
+
}
|
|
340
|
+
// Copy package.json to node_modules structure
|
|
341
|
+
const packageSource = path.join(tempDir, 'package.json');
|
|
342
|
+
const packageTarget = path.join(process.cwd(), 'node_modules', '@ng-shangjc', componentName, 'package.json');
|
|
343
|
+
if (fs.existsSync(packageSource)) {
|
|
344
|
+
fs.copySync(packageSource, packageTarget);
|
|
345
|
+
}
|
|
346
|
+
// Clean up temp files
|
|
347
|
+
fs.removeSync(tempDir);
|
|
348
|
+
resolve();
|
|
349
|
+
})
|
|
350
|
+
.on('error', reject);
|
|
351
|
+
});
|
|
352
|
+
}).on('error', reject);
|
|
353
|
+
});
|
|
354
|
+
}
|
|
246
355
|
function generateIndexFile(componentName, files, mode) {
|
|
247
356
|
const exports = files
|
|
248
357
|
.filter(file => file.endsWith('.ts'))
|
|
@@ -261,3 +370,24 @@ ${exports}
|
|
|
261
370
|
function getComponentClassName(componentName) {
|
|
262
371
|
return componentName.charAt(0).toUpperCase() + componentName.slice(1) + 'Component';
|
|
263
372
|
}
|
|
373
|
+
async function createOrUpdateBarrelIndex(componentsPath, installedComponents) {
|
|
374
|
+
const barrelDir = path.join(process.cwd(), componentsPath);
|
|
375
|
+
const barrelPath = path.join(barrelDir, 'index.ts');
|
|
376
|
+
// Ensure the directory exists
|
|
377
|
+
await fs.ensureDir(barrelDir);
|
|
378
|
+
// Generate barrel content
|
|
379
|
+
const exports = installedComponents
|
|
380
|
+
.sort() // Sort for consistent ordering
|
|
381
|
+
.map(component => {
|
|
382
|
+
const className = getComponentClassName(component);
|
|
383
|
+
return `export { ${className} } from './${component}';`;
|
|
384
|
+
})
|
|
385
|
+
.join('\n');
|
|
386
|
+
const barrelContent = `// Generated by ng-shangjc CLI
|
|
387
|
+
// Barrel exports for all installed components
|
|
388
|
+
|
|
389
|
+
${exports}
|
|
390
|
+
`;
|
|
391
|
+
await fs.writeFile(barrelPath, barrelContent);
|
|
392
|
+
console.log(`✅ Updated barrel index.ts at ${componentsPath}`);
|
|
393
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ng-shangjc/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2-beta",
|
|
4
4
|
"bin": {
|
|
5
5
|
"ng-shangjc": "./dist/index.js"
|
|
6
6
|
},
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"commander": "^11.0.0",
|
|
13
13
|
"fs-extra": "^11.0.0",
|
|
14
|
-
"inquirer": "^9.0.0"
|
|
14
|
+
"inquirer": "^9.0.0",
|
|
15
|
+
"tar": "^6.0.0"
|
|
15
16
|
},
|
|
16
17
|
"devDependencies": {
|
|
17
18
|
"@types/fs-extra": "^11.0.0",
|
package/src/commands/install.ts
CHANGED
|
@@ -33,7 +33,7 @@ const AVAILABLE_COMPONENTS = [
|
|
|
33
33
|
];
|
|
34
34
|
|
|
35
35
|
const COMPONENT_DEPENDENCIES = {
|
|
36
|
-
button: ['utils'],
|
|
36
|
+
button: ['utils', 'class-variance-authority'],
|
|
37
37
|
input: ['utils'],
|
|
38
38
|
card: ['utils'],
|
|
39
39
|
switch: ['utils'],
|
|
@@ -49,30 +49,24 @@ const COMPONENT_DEPENDENCIES = {
|
|
|
49
49
|
|
|
50
50
|
const COMPONENT_FILES = {
|
|
51
51
|
button: [
|
|
52
|
-
'button.component.ts'
|
|
53
|
-
'button.metadata.ts'
|
|
52
|
+
'button.component.ts'
|
|
54
53
|
],
|
|
55
54
|
input: [
|
|
56
|
-
'input.component.ts'
|
|
57
|
-
'input.metadata.ts'
|
|
55
|
+
'input.component.ts'
|
|
58
56
|
],
|
|
59
57
|
card: [
|
|
60
|
-
'card.component.ts'
|
|
61
|
-
'card.metadata.ts'
|
|
58
|
+
'card.component.ts'
|
|
62
59
|
],
|
|
63
60
|
switch: [
|
|
64
|
-
'switch.component.ts'
|
|
65
|
-
'switch.metadata.ts'
|
|
61
|
+
'switch.component.ts'
|
|
66
62
|
],
|
|
67
63
|
dialog: [
|
|
68
64
|
'dialog.component.ts',
|
|
69
|
-
'dialog.service.ts'
|
|
70
|
-
'dialog.metadata.ts'
|
|
65
|
+
'dialog.service.ts'
|
|
71
66
|
],
|
|
72
67
|
tooltip: [
|
|
73
68
|
'tooltip.component.ts',
|
|
74
|
-
'tooltip.directive.ts'
|
|
75
|
-
'tooltip.metadata.ts'
|
|
69
|
+
'tooltip.directive.ts'
|
|
76
70
|
],
|
|
77
71
|
select: [
|
|
78
72
|
'select.component.ts'
|
|
@@ -174,12 +168,21 @@ export async function installComponent(
|
|
|
174
168
|
await installUtils();
|
|
175
169
|
}
|
|
176
170
|
|
|
171
|
+
// Install external dependencies (non-utils)
|
|
172
|
+
const externalDeps = dependencies.filter(dep => dep !== 'utils');
|
|
173
|
+
if (externalDeps.length > 0) {
|
|
174
|
+
await installExternalDependencies(externalDeps, componentName);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Install the component package itself
|
|
178
|
+
await installComponentPackage(componentName);
|
|
179
|
+
|
|
177
180
|
// Create destination directory
|
|
178
181
|
const destDir = path.join(process.cwd(), componentsPath, componentName);
|
|
179
182
|
await fs.ensureDir(destDir);
|
|
180
183
|
|
|
181
|
-
// Get source directory
|
|
182
|
-
const sourceDir = path.join(
|
|
184
|
+
// Get source directory from installed npm package
|
|
185
|
+
const sourceDir = path.join(process.cwd(), 'node_modules', '@ng-shangjc', componentName, 'src', 'lib');
|
|
183
186
|
|
|
184
187
|
// Copy component files
|
|
185
188
|
const files = COMPONENT_FILES[componentName as keyof typeof COMPONENT_FILES];
|
|
@@ -201,13 +204,6 @@ export async function installComponent(
|
|
|
201
204
|
await fs.writeFile(path.join(destDir, 'index.ts'), indexContent);
|
|
202
205
|
console.log(`✅ Created index.ts`);
|
|
203
206
|
|
|
204
|
-
// Copy README
|
|
205
|
-
const readmePath = path.join(__dirname, '..', '..', '..', 'packages', componentName, 'README.md');
|
|
206
|
-
if (await fs.pathExists(readmePath)) {
|
|
207
|
-
await fs.copy(readmePath, path.join(destDir, 'README.md'));
|
|
208
|
-
console.log(`✅ Copied README.md`);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
207
|
// Update configuration
|
|
212
208
|
if (!config.installedComponents.includes(componentName)) {
|
|
213
209
|
config.installedComponents.push(componentName);
|
|
@@ -215,10 +211,16 @@ export async function installComponent(
|
|
|
215
211
|
console.log(`✅ Updated shangjc.config.json`);
|
|
216
212
|
}
|
|
217
213
|
|
|
214
|
+
// Create/update barrel index.ts in the main ui/shangjc folder
|
|
215
|
+
await createOrUpdateBarrelIndex(config.componentsPath, config.installedComponents);
|
|
216
|
+
|
|
218
217
|
console.log(`🎉 Successfully installed ${componentName} component!`);
|
|
219
218
|
console.log(`\n📁 Files installed to: ${destDir}`);
|
|
220
219
|
console.log(`\n📖 Usage:`);
|
|
220
|
+
console.log(`// Individual import:`);
|
|
221
221
|
console.log(`import { ${getComponentClassName(componentName)} } from './${componentsPath}/${componentName}';`);
|
|
222
|
+
console.log(`// Or barrel import (if multiple components):`);
|
|
223
|
+
console.log(`import { ${getComponentClassName(componentName)} } from './${componentsPath}';`);
|
|
222
224
|
|
|
223
225
|
} catch (error) {
|
|
224
226
|
console.error('❌ Installation failed:', error);
|
|
@@ -235,7 +237,7 @@ async function installUtils() {
|
|
|
235
237
|
|
|
236
238
|
if (!fs.existsSync(utilsPath)) {
|
|
237
239
|
console.log('Installing @ng-shangjc/utils...');
|
|
238
|
-
execSync('npm install @ng-shangjc/utils', { stdio: 'inherit' });
|
|
240
|
+
execSync('npm install --save-dev @ng-shangjc/utils', { stdio: 'inherit' });
|
|
239
241
|
} else {
|
|
240
242
|
console.log('✅ @ng-shangjc/utils already installed');
|
|
241
243
|
}
|
|
@@ -245,6 +247,133 @@ async function installUtils() {
|
|
|
245
247
|
}
|
|
246
248
|
}
|
|
247
249
|
|
|
250
|
+
async function installExternalDependencies(dependencies: string[], componentName: string) {
|
|
251
|
+
// Read the component's package.json to get exact versions
|
|
252
|
+
const componentPackagePath = path.join(process.cwd(), 'node_modules', '@ng-shangjc', componentName, 'package.json');
|
|
253
|
+
let componentPackage: any;
|
|
254
|
+
|
|
255
|
+
try {
|
|
256
|
+
componentPackage = await fs.readJson(componentPackagePath);
|
|
257
|
+
} catch (error) {
|
|
258
|
+
console.error(`❌ Failed to read component package.json:`, error);
|
|
259
|
+
throw error;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
for (const dependency of dependencies) {
|
|
263
|
+
console.log(`📦 Installing ${dependency} dependency...`);
|
|
264
|
+
|
|
265
|
+
try {
|
|
266
|
+
// Get the exact version from component's peerDependencies or dependencies
|
|
267
|
+
const version = componentPackage.peerDependencies?.[dependency] || componentPackage.dependencies?.[dependency];
|
|
268
|
+
if (!version) {
|
|
269
|
+
console.warn(`⚠️ Could not find version for ${dependency} in component package.json, installing latest...`);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Check if dependency is already installed in node_modules
|
|
273
|
+
const depPath = path.join(process.cwd(), 'node_modules', dependency);
|
|
274
|
+
|
|
275
|
+
if (!fs.existsSync(depPath)) {
|
|
276
|
+
const installSpec = version ? `${dependency}@${version}` : dependency;
|
|
277
|
+
console.log(`Installing ${installSpec}...`);
|
|
278
|
+
execSync(`npm install ${installSpec}`, { stdio: 'inherit' });
|
|
279
|
+
} else {
|
|
280
|
+
console.log(`✅ ${dependency} already installed`);
|
|
281
|
+
}
|
|
282
|
+
} catch (error) {
|
|
283
|
+
console.error(`❌ Failed to install ${dependency}:`, error);
|
|
284
|
+
throw error;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
async function installComponentPackage(componentName: string) {
|
|
290
|
+
console.log(`📦 Installing ${componentName} package...`);
|
|
291
|
+
|
|
292
|
+
try {
|
|
293
|
+
// Check if component is already installed in node_modules
|
|
294
|
+
const componentPath = path.join(process.cwd(), 'node_modules', '@ng-shangjc', componentName);
|
|
295
|
+
|
|
296
|
+
if (!fs.existsSync(componentPath)) {
|
|
297
|
+
console.log(`Installing @ng-shangjc/${componentName}...`);
|
|
298
|
+
execSync(`npm install --save-dev @ng-shangjc/${componentName}`, { stdio: 'inherit' });
|
|
299
|
+
} else {
|
|
300
|
+
console.log(`✅ @ng-shangjc/${componentName} already installed`);
|
|
301
|
+
}
|
|
302
|
+
} catch (error) {
|
|
303
|
+
console.error(`❌ Failed to install ${componentName} package:`, error);
|
|
304
|
+
console.log(`🔄 Attempting to download files directly...`);
|
|
305
|
+
|
|
306
|
+
// Fallback: try to download files directly from npm registry
|
|
307
|
+
try {
|
|
308
|
+
await downloadComponentFiles(componentName);
|
|
309
|
+
console.log(`✅ Successfully downloaded ${componentName} files directly`);
|
|
310
|
+
} catch (downloadError) {
|
|
311
|
+
console.error(`❌ Failed to download ${componentName} files:`, downloadError);
|
|
312
|
+
throw new Error(`Failed to install ${componentName}: Package installation and direct download both failed`);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
async function downloadComponentFiles(componentName: string) {
|
|
318
|
+
const https = require('https');
|
|
319
|
+
const tar = require('tar');
|
|
320
|
+
|
|
321
|
+
return new Promise<void>((resolve, reject) => {
|
|
322
|
+
const packageUrl = `https://registry.npmjs.org/@ng-shangjc/${componentName}/-/${componentName}-1.0.0.tgz`;
|
|
323
|
+
const tempDir = path.join(process.cwd(), '.ng-shangjc-temp');
|
|
324
|
+
|
|
325
|
+
// Ensure temp directory exists
|
|
326
|
+
fs.ensureDirSync(tempDir);
|
|
327
|
+
|
|
328
|
+
const file = fs.createWriteStream(path.join(tempDir, `${componentName}.tgz`));
|
|
329
|
+
|
|
330
|
+
https.get(packageUrl, (response: any) => {
|
|
331
|
+
if (response.statusCode !== 200) {
|
|
332
|
+
reject(new Error(`Failed to download package: ${response.statusCode}`));
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
response.pipe(file);
|
|
337
|
+
|
|
338
|
+
file.on('finish', () => {
|
|
339
|
+
file.close();
|
|
340
|
+
|
|
341
|
+
// Extract the tarball
|
|
342
|
+
fs.createReadStream(path.join(tempDir, `${componentName}.tgz`))
|
|
343
|
+
.pipe(tar.extract({
|
|
344
|
+
cwd: tempDir,
|
|
345
|
+
strip: 1 // Remove the package folder
|
|
346
|
+
}))
|
|
347
|
+
.on('finish', () => {
|
|
348
|
+
// Copy the extracted files to node_modules structure
|
|
349
|
+
const sourceDir = path.join(tempDir, 'src', 'lib');
|
|
350
|
+
const targetDir = path.join(process.cwd(), 'node_modules', '@ng-shangjc', componentName, 'src', 'lib');
|
|
351
|
+
|
|
352
|
+
fs.ensureDirSync(path.dirname(targetDir));
|
|
353
|
+
|
|
354
|
+
if (fs.existsSync(sourceDir)) {
|
|
355
|
+
fs.copySync(sourceDir, targetDir);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// Copy package.json to node_modules structure
|
|
359
|
+
const packageSource = path.join(tempDir, 'package.json');
|
|
360
|
+
const packageTarget = path.join(process.cwd(), 'node_modules', '@ng-shangjc', componentName, 'package.json');
|
|
361
|
+
|
|
362
|
+
if (fs.existsSync(packageSource)) {
|
|
363
|
+
fs.copySync(packageSource, packageTarget);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// Clean up temp files
|
|
367
|
+
fs.removeSync(tempDir);
|
|
368
|
+
|
|
369
|
+
resolve();
|
|
370
|
+
})
|
|
371
|
+
.on('error', reject);
|
|
372
|
+
});
|
|
373
|
+
}).on('error', reject);
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
|
|
248
377
|
function generateIndexFile(componentName: string, files: string[], mode: string): string {
|
|
249
378
|
const exports = files
|
|
250
379
|
.filter(file => file.endsWith('.ts'))
|
|
@@ -264,4 +393,30 @@ ${exports}
|
|
|
264
393
|
|
|
265
394
|
function getComponentClassName(componentName: string): string {
|
|
266
395
|
return componentName.charAt(0).toUpperCase() + componentName.slice(1) + 'Component';
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
async function createOrUpdateBarrelIndex(componentsPath: string, installedComponents: string[]) {
|
|
399
|
+
const barrelDir = path.join(process.cwd(), componentsPath);
|
|
400
|
+
const barrelPath = path.join(barrelDir, 'index.ts');
|
|
401
|
+
|
|
402
|
+
// Ensure the directory exists
|
|
403
|
+
await fs.ensureDir(barrelDir);
|
|
404
|
+
|
|
405
|
+
// Generate barrel content
|
|
406
|
+
const exports = installedComponents
|
|
407
|
+
.sort() // Sort for consistent ordering
|
|
408
|
+
.map(component => {
|
|
409
|
+
const className = getComponentClassName(component);
|
|
410
|
+
return `export { ${className} } from './${component}';`;
|
|
411
|
+
})
|
|
412
|
+
.join('\n');
|
|
413
|
+
|
|
414
|
+
const barrelContent = `// Generated by ng-shangjc CLI
|
|
415
|
+
// Barrel exports for all installed components
|
|
416
|
+
|
|
417
|
+
${exports}
|
|
418
|
+
`;
|
|
419
|
+
|
|
420
|
+
await fs.writeFile(barrelPath, barrelContent);
|
|
421
|
+
console.log(`✅ Updated barrel index.ts at ${componentsPath}`);
|
|
267
422
|
}
|