@jatinmourya/ng-init 1.0.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,247 @@
1
+ import { execa } from 'execa';
2
+ import ora from 'ora';
3
+ import chalk from 'chalk';
4
+ import { platform } from 'os';
5
+
6
+ /**
7
+ * Install Node.js using winget (Windows)
8
+ */
9
+ export async function installNodeWithWinget(version = 'LTS') {
10
+ const spinner = ora('Installing Node.js with winget...').start();
11
+
12
+ try {
13
+ const packageId = version === 'LTS' ? 'OpenJS.NodeJS.LTS' : 'OpenJS.NodeJS';
14
+ await execa('winget', ['install', packageId], { stdio: 'inherit' });
15
+
16
+ spinner.succeed('Node.js installed successfully');
17
+ return true;
18
+ } catch (error) {
19
+ spinner.fail('Failed to install Node.js');
20
+ console.error(chalk.red(error.message));
21
+ return false;
22
+ }
23
+ }
24
+
25
+ /**
26
+ * Get nvm installation instructions based on OS
27
+ */
28
+ export function getNvmInstallInstructions() {
29
+ const os = platform();
30
+
31
+ if (os === 'win32') {
32
+ return {
33
+ os: 'Windows',
34
+ method: 'Download and install',
35
+ url: 'https://github.com/coreybutler/nvm-windows/releases',
36
+ command: null,
37
+ description: 'Download the nvm-setup.zip file from the releases page and run the installer.'
38
+ };
39
+ } else if (os === 'darwin') {
40
+ return {
41
+ os: 'macOS',
42
+ method: 'Using curl',
43
+ url: 'https://github.com/nvm-sh/nvm',
44
+ command: 'curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash',
45
+ description: 'Run the curl command in your terminal to install nvm.'
46
+ };
47
+ } else {
48
+ return {
49
+ os: 'Linux',
50
+ method: 'Using curl or wget',
51
+ url: 'https://github.com/nvm-sh/nvm',
52
+ command: 'curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash',
53
+ alternativeCommand: 'wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash',
54
+ description: 'Run either the curl or wget command in your terminal to install nvm.'
55
+ };
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Display nvm installation guide
61
+ */
62
+ export function displayNvmInstallGuide() {
63
+ const instructions = getNvmInstallInstructions();
64
+
65
+ console.log(chalk.bold.yellow('\nšŸ“š nvm Installation Guide\n'));
66
+ console.log(chalk.gray('━'.repeat(50)));
67
+ console.log(chalk.white('Operating System: ') + chalk.cyan(instructions.os));
68
+ console.log(chalk.white('Method: ') + chalk.cyan(instructions.method));
69
+ console.log(chalk.white('URL: ') + chalk.blue(instructions.url));
70
+
71
+ if (instructions.command) {
72
+ console.log(chalk.white('\nCommand:'));
73
+ console.log(chalk.green(` ${instructions.command}`));
74
+
75
+ if (instructions.alternativeCommand) {
76
+ console.log(chalk.white('\nAlternative:'));
77
+ console.log(chalk.green(` ${instructions.alternativeCommand}`));
78
+ }
79
+ }
80
+
81
+ console.log(chalk.white('\nDescription:'));
82
+ console.log(chalk.gray(` ${instructions.description}`));
83
+ console.log(chalk.gray('━'.repeat(50)) + '\n');
84
+
85
+ console.log(chalk.yellow('šŸ’” Benefits of using nvm:'));
86
+ console.log(chalk.gray(' • Manage multiple Node.js versions'));
87
+ console.log(chalk.gray(' • Switch between versions easily'));
88
+ console.log(chalk.gray(' • No admin/sudo required for installations'));
89
+ console.log(chalk.gray(' • Project-specific Node versions\n'));
90
+ }
91
+
92
+ /**
93
+ * Install npm package globally
94
+ */
95
+ export async function installGlobalPackage(packageName, version = 'latest') {
96
+ const spinner = ora(`Installing ${packageName}@${version}...`).start();
97
+
98
+ try {
99
+ const packageSpec = version === 'latest' ? packageName : `${packageName}@${version}`;
100
+ await execa('npm', ['install', '-g', packageSpec], { stdio: 'inherit' });
101
+
102
+ spinner.succeed(`${packageName} installed successfully`);
103
+ return true;
104
+ } catch (error) {
105
+ spinner.fail(`Failed to install ${packageName}`);
106
+ console.error(chalk.red(error.message));
107
+ return false;
108
+ }
109
+ }
110
+
111
+ /**
112
+ * Install npm packages in project
113
+ */
114
+ export async function installPackages(packages, projectPath, dev = false) {
115
+ const spinner = ora(`Installing ${packages.length} package(s)...`).start();
116
+
117
+ try {
118
+ const args = ['install'];
119
+ if (dev) args.push('--save-dev');
120
+ args.push(...packages);
121
+
122
+ await execa('npm', args, {
123
+ cwd: projectPath,
124
+ stdio: 'inherit'
125
+ });
126
+
127
+ spinner.succeed('Packages installed successfully');
128
+ return true;
129
+ } catch (error) {
130
+ spinner.warn('Failed with strict dependencies, retrying with --legacy-peer-deps...');
131
+
132
+ // Retry with --legacy-peer-deps flag
133
+ try {
134
+ const args = ['install', '--legacy-peer-deps'];
135
+ if (dev) args.push('--save-dev');
136
+ args.push(...packages);
137
+
138
+ await execa('npm', args, {
139
+ cwd: projectPath,
140
+ stdio: 'inherit'
141
+ });
142
+
143
+ spinner.succeed('Packages installed successfully with --legacy-peer-deps');
144
+ console.log(chalk.yellow('āš ļø Note: Installed with --legacy-peer-deps flag due to peer dependency conflicts'));
145
+ return true;
146
+ } catch (retryError) {
147
+ spinner.fail('Failed to install packages');
148
+ console.error(chalk.red(retryError.message));
149
+ console.log(chalk.yellow('\nšŸ’” Tip: You can try installing manually with:'));
150
+ console.log(chalk.cyan(` cd ${projectPath}`));
151
+ console.log(chalk.cyan(` npm install ${packages.join(' ')} --force`));
152
+ return false;
153
+ }
154
+ }
155
+ }
156
+
157
+ /**
158
+ * Initialize npm project
159
+ */
160
+ export async function initNpmProject(projectPath) {
161
+ try {
162
+ await execa('npm', ['init', '-y'], {
163
+ cwd: projectPath,
164
+ stdio: 'inherit'
165
+ });
166
+ return true;
167
+ } catch (error) {
168
+ console.error(chalk.red('Failed to initialize npm project'));
169
+ return false;
170
+ }
171
+ }
172
+
173
+ /**
174
+ * Run npm install in project
175
+ */
176
+ export async function runNpmInstall(projectPath) {
177
+ const spinner = ora('Installing dependencies...').start();
178
+
179
+ try {
180
+ await execa('npm', ['install'], {
181
+ cwd: projectPath,
182
+ stdio: 'inherit'
183
+ });
184
+
185
+ spinner.succeed('Dependencies installed successfully');
186
+ return true;
187
+ } catch (error) {
188
+ spinner.warn('Failed with strict dependencies, retrying with --legacy-peer-deps...');
189
+
190
+ // Retry with --legacy-peer-deps flag
191
+ try {
192
+ await execa('npm', ['install', '--legacy-peer-deps'], {
193
+ cwd: projectPath,
194
+ stdio: 'inherit'
195
+ });
196
+
197
+ spinner.succeed('Dependencies installed successfully with --legacy-peer-deps');
198
+ console.log(chalk.yellow('āš ļø Note: Installed with --legacy-peer-deps flag due to peer dependency conflicts'));
199
+ return true;
200
+ } catch (retryError) {
201
+ spinner.fail('Failed to install dependencies');
202
+ console.error(chalk.red(retryError.message));
203
+ console.log(chalk.yellow('\nšŸ’” Tip: You can try installing manually with:'));
204
+ console.log(chalk.cyan(` cd ${projectPath}`));
205
+ console.log(chalk.cyan(` npm install --force`));
206
+ return false;
207
+ }
208
+ }
209
+ }
210
+
211
+ /**
212
+ * Install Angular CLI globally
213
+ */
214
+ export async function installAngularCli(version = 'latest') {
215
+ return installGlobalPackage('@angular/cli', version);
216
+ }
217
+
218
+ /**
219
+ * Create Angular project using CLI
220
+ */
221
+ export async function createAngularProject(projectName, angularVersion, options = {}) {
222
+ const spinner = ora(`Creating Angular project: ${projectName}...`).start();
223
+
224
+ try {
225
+ const args = ['new', projectName];
226
+
227
+ // Add options
228
+ if (options.skipInstall) args.push('--skip-install');
229
+ if (options.routing !== undefined) args.push(`--routing=${options.routing}`);
230
+ if (options.style) args.push(`--style=${options.style}`);
231
+ if (options.strict !== undefined) args.push(`--strict=${options.strict}`);
232
+ if (options.standalone !== undefined) args.push(`--standalone=${options.standalone}`);
233
+
234
+ const cliCommand = angularVersion ? `@angular/cli@${angularVersion}` : '@angular/cli';
235
+
236
+ await execa('npx', [cliCommand, ...args], {
237
+ stdio: 'inherit'
238
+ });
239
+
240
+ spinner.succeed(`Angular project ${projectName} created successfully`);
241
+ return true;
242
+ } catch (error) {
243
+ spinner.fail('Failed to create Angular project');
244
+ console.error(chalk.red(error.message));
245
+ return false;
246
+ }
247
+ }
@@ -0,0 +1,354 @@
1
+ import axios from 'axios';
2
+ import debounce from 'lodash.debounce';
3
+
4
+ const NPM_REGISTRY_URL = 'https://registry.npmjs.org';
5
+ const NPM_SEARCH_URL = 'https://registry.npmjs.org/-/v1/search';
6
+ const NPM_DOWNLOADS_URL = 'https://api.npmjs.org/downloads/point/last-week';
7
+
8
+ /**
9
+ * Search npm packages
10
+ */
11
+ export async function searchNpmPackages(query, size = 10) {
12
+ try {
13
+ const response = await axios.get(NPM_SEARCH_URL, {
14
+ params: {
15
+ text: query,
16
+ size: size
17
+ },
18
+ timeout: 5000
19
+ });
20
+
21
+ return response.data.objects.map(obj => ({
22
+ name: obj.package.name,
23
+ version: obj.package.version,
24
+ description: obj.package.description || 'No description',
25
+ author: obj.package.publisher?.username || 'Unknown',
26
+ date: obj.package.date,
27
+ verified: obj.package.publisher?.verified || false
28
+ }));
29
+ } catch (error) {
30
+ console.error('Error searching npm packages:', error.message);
31
+ return [];
32
+ }
33
+ }
34
+
35
+ /**
36
+ * Get package details from npm registry
37
+ */
38
+ export async function getPackageDetails(packageName) {
39
+ try {
40
+ const response = await axios.get(`${NPM_REGISTRY_URL}/${packageName}`, {
41
+ timeout: 5000
42
+ });
43
+
44
+ const latestVersion = response.data['dist-tags']?.latest;
45
+ const versions = Object.keys(response.data.versions || {});
46
+
47
+ return {
48
+ name: response.data.name,
49
+ description: response.data.description || 'No description',
50
+ latestVersion: latestVersion,
51
+ versions: versions,
52
+ homepage: response.data.homepage,
53
+ repository: response.data.repository,
54
+ license: response.data.license,
55
+ keywords: response.data.keywords || []
56
+ };
57
+ } catch (error) {
58
+ if (error.response?.status === 404) {
59
+ return null;
60
+ }
61
+ throw error;
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Get package download statistics
67
+ */
68
+ export async function getPackageDownloads(packageName) {
69
+ try {
70
+ const response = await axios.get(`${NPM_DOWNLOADS_URL}/${packageName}`, {
71
+ timeout: 5000
72
+ });
73
+
74
+ return response.data.downloads;
75
+ } catch (error) {
76
+ return 0;
77
+ }
78
+ }
79
+
80
+ /**
81
+ * Validate if a package exists on npm
82
+ */
83
+ export async function validatePackage(packageName) {
84
+ const details = await getPackageDetails(packageName);
85
+ return details !== null;
86
+ }
87
+
88
+ /**
89
+ * Get enhanced package info (details + downloads)
90
+ */
91
+ export async function getEnhancedPackageInfo(packageName) {
92
+ try {
93
+ const [details, downloads] = await Promise.all([
94
+ getPackageDetails(packageName),
95
+ getPackageDownloads(packageName)
96
+ ]);
97
+
98
+ if (!details) {
99
+ return null;
100
+ }
101
+
102
+ return {
103
+ ...details,
104
+ weeklyDownloads: downloads
105
+ };
106
+ } catch (error) {
107
+ console.error(`Error getting package info for ${packageName}:`, error.message);
108
+ return null;
109
+ }
110
+ }
111
+
112
+ /**
113
+ * Format download count for display
114
+ */
115
+ export function formatDownloads(downloads) {
116
+ if (downloads >= 1000000) {
117
+ return `${(downloads / 1000000).toFixed(1)}M`;
118
+ } else if (downloads >= 1000) {
119
+ return `${(downloads / 1000).toFixed(1)}K`;
120
+ }
121
+ return downloads.toString();
122
+ }
123
+
124
+ /**
125
+ * Debounced search function for autocomplete
126
+ */
127
+ export const debouncedSearch = debounce(async (query, callback) => {
128
+ if (!query || query.length < 2) {
129
+ callback([]);
130
+ return;
131
+ }
132
+
133
+ const results = await searchNpmPackages(query, 10);
134
+ callback(results);
135
+ }, 300);
136
+
137
+ /**
138
+ * Get all versions of Angular CLI
139
+ */
140
+ export async function getAngularVersions() {
141
+ try {
142
+ const response = await axios.get(`${NPM_REGISTRY_URL}/@angular/cli`, {
143
+ timeout: 10000
144
+ });
145
+
146
+ const versions = Object.keys(response.data.versions || {})
147
+ .filter(v => !v.includes('rc') && !v.includes('beta') && !v.includes('next'))
148
+ .sort((a, b) => {
149
+ // Sort in descending order (newest first)
150
+ const aParts = a.split('.').map(Number);
151
+ const bParts = b.split('.').map(Number);
152
+
153
+ for (let i = 0; i < Math.max(aParts.length, bParts.length); i++) {
154
+ const aVal = aParts[i] || 0;
155
+ const bVal = bParts[i] || 0;
156
+ if (aVal !== bVal) return bVal - aVal;
157
+ }
158
+ return 0;
159
+ });
160
+
161
+ const distTags = response.data['dist-tags'] || {};
162
+
163
+ return {
164
+ versions: versions,
165
+ latest: distTags.latest,
166
+ lts: distTags.lts
167
+ };
168
+ } catch (error) {
169
+ console.error('Error fetching Angular versions:', error.message);
170
+ return { versions: [], latest: null, lts: null };
171
+ }
172
+ }
173
+
174
+ /**
175
+ * Get unique major versions from all Angular versions
176
+ */
177
+ export function getMajorVersions(versions) {
178
+ const majorVersions = new Set();
179
+
180
+ versions.forEach(version => {
181
+ const major = version.split('.')[0];
182
+ majorVersions.add(major);
183
+ });
184
+
185
+ return Array.from(majorVersions).sort((a, b) => Number(b) - Number(a));
186
+ }
187
+
188
+ /**
189
+ * Get minor versions for a specific major version
190
+ */
191
+ export function getMinorVersionsForMajor(versions, major) {
192
+ const minorVersions = new Set();
193
+
194
+ versions
195
+ .filter(v => v.startsWith(`${major}.`))
196
+ .forEach(version => {
197
+ const parts = version.split('.');
198
+ const minorVersion = `${parts[0]}.${parts[1]}`;
199
+ minorVersions.add(minorVersion);
200
+ });
201
+
202
+ return Array.from(minorVersions).sort((a, b) => {
203
+ const aParts = a.split('.').map(Number);
204
+ const bParts = b.split('.').map(Number);
205
+ for (let i = 0; i < Math.max(aParts.length, bParts.length); i++) {
206
+ const aVal = aParts[i] || 0;
207
+ const bVal = bParts[i] || 0;
208
+ if (aVal !== bVal) return bVal - aVal;
209
+ }
210
+ return 0;
211
+ });
212
+ }
213
+
214
+ /**
215
+ * Get patch versions for a specific major.minor version
216
+ */
217
+ export function getPatchVersionsForMinor(versions, majorMinor) {
218
+ return versions
219
+ .filter(v => v.startsWith(`${majorMinor}.`))
220
+ .sort((a, b) => {
221
+ const aParts = a.split('.').map(Number);
222
+ const bParts = b.split('.').map(Number);
223
+ for (let i = 0; i < Math.max(aParts.length, bParts.length); i++) {
224
+ const aVal = aParts[i] || 0;
225
+ const bVal = bParts[i] || 0;
226
+ if (aVal !== bVal) return bVal - aVal;
227
+ }
228
+ return 0;
229
+ });
230
+ }
231
+
232
+ /**
233
+ * Get all versions of a specific npm package
234
+ */
235
+ export async function getPackageVersions(packageName) {
236
+ try {
237
+ const response = await axios.get(`${NPM_REGISTRY_URL}/${packageName}`, {
238
+ timeout: 10000
239
+ });
240
+
241
+ const versions = Object.keys(response.data.versions || {})
242
+ .filter(v => !v.includes('rc') && !v.includes('beta') && !v.includes('next') && !v.includes('alpha'))
243
+ .sort((a, b) => {
244
+ // Sort in descending order (newest first)
245
+ const aParts = a.split('.').map(Number);
246
+ const bParts = b.split('.').map(Number);
247
+
248
+ for (let i = 0; i < Math.max(aParts.length, bParts.length); i++) {
249
+ const aVal = aParts[i] || 0;
250
+ const bVal = bParts[i] || 0;
251
+ if (aVal !== bVal) return bVal - aVal;
252
+ }
253
+ return 0;
254
+ });
255
+
256
+ const distTags = response.data['dist-tags'] || {};
257
+
258
+ return {
259
+ versions: versions,
260
+ latest: distTags.latest,
261
+ lts: distTags.lts
262
+ };
263
+ } catch (error) {
264
+ console.error(`Error fetching versions for ${packageName}:`, error.message);
265
+ return { versions: [], latest: null, lts: null };
266
+ }
267
+ }
268
+
269
+ /**
270
+ * Get Node.js version requirements for Angular version
271
+ */
272
+ export async function getNodeRequirementsForAngular(angularVersion) {
273
+ try {
274
+ const response = await axios.get(`${NPM_REGISTRY_URL}/@angular/cli/${angularVersion}`, {
275
+ timeout: 5000
276
+ });
277
+
278
+ const engines = response.data.engines || {};
279
+ const nodeRequirement = engines.node || '^18.13.0 || ^20.9.0';
280
+
281
+ return nodeRequirement;
282
+ } catch (error) {
283
+ // Default Node requirements if we can't fetch
284
+ const majorVersion = parseInt(angularVersion.split('.')[0]);
285
+
286
+ if (majorVersion >= 17) return '^18.13.0 || ^20.9.0';
287
+ if (majorVersion >= 16) return '^16.14.0 || ^18.10.0';
288
+ if (majorVersion >= 15) return '^14.20.0 || ^16.13.0 || ^18.10.0';
289
+ if (majorVersion >= 14) return '^14.15.0 || ^16.10.0';
290
+
291
+ return '^14.0.0 || ^16.0.0 || ^18.0.0';
292
+ }
293
+ }
294
+
295
+ /**
296
+ * Get peer dependencies for a specific package version
297
+ */
298
+ export async function getPackagePeerDependencies(packageName, version) {
299
+ try {
300
+ const response = await axios.get(`${NPM_REGISTRY_URL}/${packageName}/${version}`, {
301
+ timeout: 5000
302
+ });
303
+
304
+ return response.data.peerDependencies || {};
305
+ } catch (error) {
306
+ console.error(`Error fetching peer dependencies for ${packageName}@${version}:`, error.message);
307
+ return {};
308
+ }
309
+ }
310
+
311
+ /**
312
+ * Find compatible versions of a package for given Angular version
313
+ */
314
+ export async function findCompatiblePackageVersions(packageName, angularVersion, maxResults = 5) {
315
+ try {
316
+ const packageData = await getPackageVersions(packageName);
317
+ const angularMajor = angularVersion.split('.')[0];
318
+ const compatibleVersions = [];
319
+
320
+ // Check versions from newest to oldest
321
+ for (const version of packageData.versions) {
322
+ if (compatibleVersions.length >= maxResults) break;
323
+
324
+ const peerDeps = await getPackagePeerDependencies(packageName, version);
325
+
326
+ // Check if this version is compatible with the Angular version
327
+ if (peerDeps['@angular/core'] || peerDeps['@angular/common']) {
328
+ const angularDep = peerDeps['@angular/core'] || peerDeps['@angular/common'];
329
+
330
+ // Simple check: see if the Angular major version is mentioned in the peer dependency
331
+ if (angularDep.includes(`^${angularMajor}.`) ||
332
+ angularDep.includes(`~${angularMajor}.`) ||
333
+ angularDep.includes(`>=${angularMajor}.`) ||
334
+ angularDep.includes(`${angularMajor}.x`)) {
335
+ compatibleVersions.push({
336
+ version: version,
337
+ peerDependency: angularDep
338
+ });
339
+ }
340
+ } else {
341
+ // Package doesn't have Angular peer dependencies, it's likely compatible
342
+ compatibleVersions.push({
343
+ version: version,
344
+ peerDependency: 'No Angular peer dependency'
345
+ });
346
+ }
347
+ }
348
+
349
+ return compatibleVersions;
350
+ } catch (error) {
351
+ console.error(`Error finding compatible versions for ${packageName}:`, error.message);
352
+ return [];
353
+ }
354
+ }