create-letswhim 2.0.3 → 2.0.5
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/index.js +327 -71
- package/package.json +19 -10
package/index.js
CHANGED
|
@@ -2,103 +2,359 @@
|
|
|
2
2
|
import { execSync } from 'child_process';
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import fs from 'fs';
|
|
5
|
-
import pc from 'picocolors';
|
|
6
|
-
import prompts from 'prompts';
|
|
7
|
-
|
|
8
|
-
//
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
5
|
+
import pc from 'picocolors';
|
|
6
|
+
import prompts from 'prompts';
|
|
7
|
+
|
|
8
|
+
// ==================== CONFIGURATION ====================
|
|
9
|
+
const CONFIG = {
|
|
10
|
+
repoUrl: "https://github.com/ripkiiii/letswhim-starter.git",
|
|
11
|
+
version: "2.0.5",
|
|
12
|
+
colors: {
|
|
13
|
+
primary: pc.cyan,
|
|
14
|
+
secondary: pc.blue,
|
|
15
|
+
success: pc.green,
|
|
16
|
+
warning: pc.yellow,
|
|
17
|
+
error: pc.red,
|
|
18
|
+
muted: pc.gray,
|
|
19
|
+
highlight: pc.white
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// ==================== ASCII ART LIBRARY ====================
|
|
24
|
+
const ASCII = {
|
|
25
|
+
// Loading frames dengan lebih banyak variasi
|
|
26
|
+
walkingFrames: [
|
|
27
|
+
// Frame 1 - Normal walk
|
|
28
|
+
[
|
|
29
|
+
` ${pc.cyan(' ╭┴┴╮ ')}`,
|
|
30
|
+
` ${pc.cyan(' │• •│ ')}`,
|
|
31
|
+
` ${pc.cyan(' │ ─ │ ')}`,
|
|
32
|
+
` ${pc.cyan(' ╰┬┬┬╯ ')}`,
|
|
33
|
+
` ${pc.blue('░░░░░░░░░░')}`
|
|
34
|
+
].join('\n'),
|
|
35
|
+
|
|
36
|
+
// Frame 2 - Right foot forward
|
|
37
|
+
[
|
|
38
|
+
` ${pc.cyan(' ╭┴┴╮ ')}`,
|
|
39
|
+
` ${pc.cyan(' │• •│ ')}`,
|
|
40
|
+
` ${pc.cyan(' │┌─┘ ')}`,
|
|
41
|
+
` ${pc.cyan(' ╰┬┴┐ ')}`,
|
|
42
|
+
` ${pc.blue('░░░░░░░░░░')}`
|
|
43
|
+
].join('\n'),
|
|
44
|
+
|
|
45
|
+
// Frame 3 - Left foot forward
|
|
46
|
+
[
|
|
47
|
+
` ${pc.cyan(' ╭┴┴╮ ')}`,
|
|
48
|
+
` ${pc.cyan(' │• •│ ')}`,
|
|
49
|
+
` ${pc.cyan(' │└─┐ ')}`,
|
|
50
|
+
` ${pc.cyan(' ╰┴┬┘ ')}`,
|
|
51
|
+
` ${pc.blue('░░░░░░░░░░')}`
|
|
52
|
+
].join('\n'),
|
|
53
|
+
|
|
54
|
+
// Frame 4 - Carrying board
|
|
55
|
+
[
|
|
56
|
+
` ${pc.cyan(' ╭┴┴╮ ')} ${pc.white('__')}`,
|
|
57
|
+
` ${pc.cyan(' │• •│ ') + pc.white('_/ \\_')}`,
|
|
58
|
+
` ${pc.cyan(' │ _ │') + pc.white('/ \\')}`,
|
|
59
|
+
` ${pc.cyan(' ╰─┬─╯') + pc.white('\\______/')}`,
|
|
60
|
+
` ${pc.blue('░░░░░░░░░░░░░░░')}`
|
|
61
|
+
].join('\n')
|
|
62
|
+
],
|
|
63
|
+
|
|
64
|
+
// Surfing animation frames
|
|
65
|
+
surfingFrames: [
|
|
66
|
+
// Frame 1 - Start surfing
|
|
67
|
+
[
|
|
68
|
+
` ${pc.cyan(' ╭┴┴╮ ')}`,
|
|
69
|
+
` ${pc.cyan(' │• •│ ')}`,
|
|
70
|
+
` ${pc.cyan(' ╰─┬─╯ ')}`,
|
|
71
|
+
` ${pc.cyan(' _/')} ${pc.white('|')} ${pc.cyan('\\_ ')}`,
|
|
72
|
+
` ${pc.blue('~~')} ${pc.white('( )')} ${pc.white('Catching waves...')}`,
|
|
73
|
+
` ${pc.blue('~~~~~')}${pc.white('/| |\\')}`,
|
|
74
|
+
`${pc.blue('~~~~~~~~~~~')}`,
|
|
75
|
+
`${pc.blue('~~~~~~~~~~~~~~~~~~~~~~')}`
|
|
76
|
+
].join('\n'),
|
|
77
|
+
|
|
78
|
+
// Frame 2 - Riding wave
|
|
79
|
+
[
|
|
80
|
+
` ${pc.cyan(' ╭┴┴╮ ')}`,
|
|
81
|
+
` ${pc.cyan(' │• •│ 🏄')}`,
|
|
82
|
+
` ${pc.cyan(' ╰─┬─╯ ')}`,
|
|
83
|
+
` ${pc.cyan(' __/')}${pc.white('|')}${pc.cyan('\\__ ')}`,
|
|
84
|
+
` ${pc.blue('~~~')} ${pc.white('( )')} ${pc.white('Riding the wave!')}`,
|
|
85
|
+
`${pc.blue('~~~~~~')}${pc.white('/| |\\')}`,
|
|
86
|
+
`${pc.blue('~~~~~~~~~~~~')}`,
|
|
87
|
+
`${pc.blue('~~~~~~~~~~~~~~~~~~~~~~~')}`
|
|
88
|
+
].join('\n'),
|
|
89
|
+
|
|
90
|
+
// Frame 3 - Big wave
|
|
91
|
+
[
|
|
92
|
+
` ${pc.cyan(' ╭┴┴╮ ')}`,
|
|
93
|
+
` ${pc.cyan(' │• •│ 🌊')}`,
|
|
94
|
+
` ${pc.cyan(' ╰─┬─╯ ')}`,
|
|
95
|
+
` ${pc.cyan(' ___/')}${pc.white('|')}${pc.cyan('\\___')}`,
|
|
96
|
+
` ${pc.blue('~~~~')}${pc.white('( )')} ${pc.white('Big one coming!')}`,
|
|
97
|
+
`${pc.blue('~~~~~~~')}${pc.white('/| |\\')}`,
|
|
98
|
+
`${pc.blue('~~~~~~~~~~~~~~')}`,
|
|
99
|
+
`${pc.blue('~~~~~~~~~~~~~~~~~~~~~~~~')}`
|
|
100
|
+
].join('\n')
|
|
101
|
+
],
|
|
102
|
+
|
|
103
|
+
// Success screen dengan efek 3D
|
|
104
|
+
successArt: [
|
|
105
|
+
`${pc.cyan('╔═══════════════════════════════════════╗')}`,
|
|
106
|
+
`${pc.cyan('║')} ${pc.green('✨ PROJECT READY TO SURF! ✨')} ${pc.cyan('║')}`,
|
|
107
|
+
`${pc.cyan('╠═══════════════════════════════════════╣')}`,
|
|
108
|
+
` `,
|
|
109
|
+
` ${pc.cyan('\\')} ${pc.cyan('/')} `,
|
|
110
|
+
` ${pc.cyan('\\')} ${pc.white('O')} ${pc.cyan('/')} `,
|
|
111
|
+
` ${pc.cyan('\\')} ${pc.white('K')} ${pc.cyan('/')} `,
|
|
112
|
+
` ${pc.cyan('╲')}${pc.white('!')}${pc.cyan('╱')} `,
|
|
113
|
+
` ${pc.cyan('●')} `,
|
|
114
|
+
` ${pc.blue('/')} ${pc.white('|')} ${pc.blue('\\')} `,
|
|
115
|
+
` ${pc.blue('/')} ${pc.white('|')} ${pc.blue('\\')} `,
|
|
116
|
+
` ${pc.blue('/')} ${pc.white('|')} ${pc.blue('\\')} `,
|
|
117
|
+
`${pc.blue('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━')}`,
|
|
118
|
+
` `,
|
|
119
|
+
`${pc.cyan('╚═══════════════════════════════════════╝')}`
|
|
120
|
+
].join('\n')
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
// ==================== ANIMATION ENGINE ====================
|
|
124
|
+
class AnimationEngine {
|
|
125
|
+
constructor() {
|
|
126
|
+
this.spinnerIndex = 0;
|
|
127
|
+
this.progress = 0;
|
|
128
|
+
this.isAnimating = false;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
clearLines(count = 1) {
|
|
132
|
+
process.stdout.write('\u001b[1A\u001b[2K'.repeat(count));
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
createProgressBar(percent, width = 40) {
|
|
136
|
+
const filled = Math.floor((percent / 100) * width);
|
|
137
|
+
const empty = width - filled;
|
|
138
|
+
|
|
139
|
+
// Gradient warna berdasarkan progress
|
|
140
|
+
let bar = '';
|
|
141
|
+
for (let i = 0; i < filled; i++) {
|
|
142
|
+
const hue = Math.floor(i / width * 180) + 60; // Cyan to blue
|
|
143
|
+
bar += `\x1b[38;5;${hue}m█\x1b[0m`;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
for (let i = 0; i < empty; i++) {
|
|
147
|
+
bar += pc.gray('░');
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return bar;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
async typewriter(text, speed = 30) {
|
|
154
|
+
process.stdout.write(pc.cyan('▸ ') + pc.gray(''));
|
|
155
|
+
for (let char of text) {
|
|
156
|
+
process.stdout.write(char);
|
|
157
|
+
await new Promise(resolve => setTimeout(resolve, speed));
|
|
158
|
+
}
|
|
159
|
+
console.log();
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
async loadingSequence(steps) {
|
|
163
|
+
console.log('\n');
|
|
164
|
+
|
|
165
|
+
for (let i = 0; i < steps.length; i++) {
|
|
166
|
+
const step = steps[i];
|
|
167
|
+
const isLast = i === steps.length - 1;
|
|
168
|
+
|
|
169
|
+
// Progress bar animation
|
|
170
|
+
for (let p = this.progress; p <= ((i + 1) * 100 / steps.length); p++) {
|
|
171
|
+
this.progress = p;
|
|
40
172
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
console.log(`${pc.cyan('▹')} ${pc.white(message)}`);
|
|
44
|
-
process.stdout.write(` ${bar} ${pc.cyan(percent + '%')}\r`);
|
|
173
|
+
// Clear previous frame
|
|
174
|
+
this.clearLines(8);
|
|
45
175
|
|
|
46
|
-
|
|
47
|
-
|
|
176
|
+
// Show current step
|
|
177
|
+
const stepText = pc.white(step.title);
|
|
178
|
+
console.log(`${pc.cyan('🛠️ ')} ${stepText}`);
|
|
179
|
+
|
|
180
|
+
// Show animation frame
|
|
181
|
+
const frameIndex = Math.floor(p / 10) % ASCII.walkingFrames.length;
|
|
182
|
+
console.log(ASCII.walkingFrames[frameIndex]);
|
|
183
|
+
|
|
184
|
+
// Show progress bar with percentage
|
|
185
|
+
const bar = this.createProgressBar(p, 50);
|
|
186
|
+
console.log(`\n${bar} ${pc.cyan(p.toFixed(0) + '%')}`);
|
|
187
|
+
|
|
188
|
+
// Show status message with spinner
|
|
189
|
+
const spinner = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'][Math.floor(Date.now() / 100) % 10];
|
|
190
|
+
console.log(`${pc.cyan(spinner)} ${pc.gray(step.message)}`);
|
|
191
|
+
|
|
192
|
+
await new Promise(resolve => setTimeout(resolve, step.delay || 50));
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Mark step as complete
|
|
196
|
+
this.clearLines(8);
|
|
197
|
+
console.log(`${pc.green('✓')} ${pc.white(step.title)} ${pc.gray('(completed)')}`);
|
|
198
|
+
|
|
199
|
+
if (!isLast) {
|
|
200
|
+
await new Promise(resolve => setTimeout(resolve, 300));
|
|
201
|
+
}
|
|
48
202
|
}
|
|
49
|
-
|
|
203
|
+
|
|
204
|
+
console.log();
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
async surfingCelebration() {
|
|
208
|
+
console.log('\n' + ' '.repeat(20) + pc.green('🏄 SURF\'S UP! 🏄') + '\n');
|
|
209
|
+
|
|
210
|
+
for (let i = 0; i < 15; i++) {
|
|
211
|
+
this.clearLines(12);
|
|
212
|
+
const frame = ASCII.surfingFrames[i % ASCII.surfingFrames.length];
|
|
213
|
+
console.log(frame);
|
|
214
|
+
|
|
215
|
+
// Tambahkan efek partikel
|
|
216
|
+
const particles = ['✨', '🌟', '💫', '⭐', '🌊'];
|
|
217
|
+
const particle = particles[Math.floor(Math.random() * particles.length)];
|
|
218
|
+
console.log(' '.repeat(30) + pc.yellow(particle));
|
|
219
|
+
|
|
220
|
+
await new Promise(resolve => setTimeout(resolve, 200));
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Final success screen
|
|
224
|
+
this.clearLines(12);
|
|
225
|
+
console.log(ASCII.successArt);
|
|
226
|
+
}
|
|
50
227
|
}
|
|
51
228
|
|
|
229
|
+
// ==================== MAIN APPLICATION ====================
|
|
52
230
|
async function init() {
|
|
53
|
-
|
|
231
|
+
const animator = new AnimationEngine();
|
|
232
|
+
|
|
233
|
+
// Clear screen dengan style
|
|
234
|
+
console.log('\x1B[2J\x1B[0f');
|
|
235
|
+
|
|
236
|
+
// Header dengan gradient
|
|
237
|
+
console.log(pc.cyan(`
|
|
238
|
+
╔═══════════════════════════════════════════════╗
|
|
239
|
+
║ ║
|
|
240
|
+
║ ${pc.white('🌊 LETSWHIM CREATOR v' + CONFIG.version)} ║
|
|
241
|
+
║ ${pc.gray('The Ultralight Web Engine')} ║
|
|
242
|
+
║ ║
|
|
243
|
+
╚═══════════════════════════════════════════════╝
|
|
244
|
+
`));
|
|
245
|
+
|
|
246
|
+
console.log();
|
|
54
247
|
|
|
55
|
-
|
|
56
|
-
|
|
248
|
+
// Support npm create letswhim@latest my-project langsung
|
|
249
|
+
let projectName = process.argv[2];
|
|
57
250
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
251
|
+
if (!projectName) {
|
|
252
|
+
const response = await prompts({
|
|
253
|
+
type: 'text',
|
|
254
|
+
name: 'projectName',
|
|
255
|
+
message: pc.cyan('?') + ' ' + pc.white('Project name:'),
|
|
256
|
+
initial: 'my-whim-project',
|
|
257
|
+
validate: value => value.trim() === '' ? 'Project name cannot be empty' : true
|
|
258
|
+
});
|
|
259
|
+
projectName = response.projectName?.trim();
|
|
260
|
+
}
|
|
64
261
|
|
|
65
|
-
|
|
262
|
+
// Fallback jika masih kosong
|
|
263
|
+
projectName = projectName || 'my-whim-project';
|
|
66
264
|
const targetDir = path.join(process.cwd(), projectName);
|
|
67
|
-
const repoUrl = "https://github.com/ripkiiii/letswhim-starter.git";
|
|
68
265
|
|
|
266
|
+
// Check if directory exists
|
|
69
267
|
if (fs.existsSync(targetDir)) {
|
|
70
|
-
console.log(`\n${pc.red('✖')}
|
|
268
|
+
console.log(`\n${pc.red('✖')} Directory ${pc.cyan(projectName)} already exists.`);
|
|
269
|
+
console.log(pc.gray('Try a different name or remove the existing directory.'));
|
|
71
270
|
process.exit(1);
|
|
72
271
|
}
|
|
73
272
|
|
|
74
|
-
|
|
273
|
+
// Loading animation sequence
|
|
274
|
+
const loadingSteps = [
|
|
275
|
+
{ title: 'Preparing workspace', message: 'Setting up your coding beach...', delay: 80 },
|
|
276
|
+
{ title: 'Catching waves', message: 'Cloning the starter template...', delay: 120 },
|
|
277
|
+
{ title: 'Waxing the board', message: 'Cleaning up repository...', delay: 60 },
|
|
278
|
+
{ title: 'Checking conditions', message: 'Verifying project structure...', delay: 40 },
|
|
279
|
+
{ title: 'Final preparations', message: 'Almost ready to surf...', delay: 30 }
|
|
280
|
+
];
|
|
75
281
|
|
|
282
|
+
await animator.loadingSequence(loadingSteps);
|
|
283
|
+
|
|
284
|
+
// Actual processing
|
|
76
285
|
try {
|
|
77
|
-
|
|
78
|
-
|
|
286
|
+
// Clone repository
|
|
287
|
+
process.stdout.write(`${pc.cyan('⏳')} ${pc.gray('Cloning repository...')}`);
|
|
288
|
+
execSync(`git clone --depth 1 ${CONFIG.repoUrl} "${projectName}"`, { stdio: 'ignore' });
|
|
289
|
+
console.log(`\r${pc.green('✓')} ${pc.white('Repository cloned')}`);
|
|
79
290
|
|
|
80
|
-
//
|
|
291
|
+
// Remove .git folder
|
|
81
292
|
const gitFolder = path.join(targetDir, '.git');
|
|
82
293
|
if (fs.existsSync(gitFolder)) {
|
|
83
|
-
|
|
84
|
-
|
|
294
|
+
fs.rmSync(gitFolder, { recursive: true, force: true });
|
|
295
|
+
console.log(`${pc.green('✓')} ${pc.white('Git history cleared')}`);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// Remove unnecessary files
|
|
299
|
+
const readmePath = path.join(targetDir, 'README.md');
|
|
300
|
+
if (fs.existsSync(readmePath)) {
|
|
301
|
+
const newReadme = `# ${projectName}\n\nA LetsWhim project created with create-letswhim@${CONFIG.version}\n\nHappy surfing! 🏄♂️`;
|
|
302
|
+
fs.writeFileSync(readmePath, newReadme);
|
|
85
303
|
}
|
|
86
304
|
|
|
87
|
-
|
|
88
|
-
|
|
305
|
+
// Celebration animation
|
|
306
|
+
await animator.surfingCelebration();
|
|
89
307
|
|
|
90
|
-
|
|
308
|
+
// Success message
|
|
309
|
+
console.log(`\n${pc.green('🎉 SUCCESS!')} ${pc.white('Project created successfully!')}\n`);
|
|
91
310
|
|
|
92
|
-
console.log(
|
|
93
|
-
console.log(` ${pc.
|
|
94
|
-
|
|
95
|
-
console.log(
|
|
96
|
-
|
|
97
|
-
console.log(
|
|
311
|
+
console.log(pc.cyan('📁 Project location:'));
|
|
312
|
+
console.log(` ${pc.white(`./${projectName}`)}\n`);
|
|
313
|
+
|
|
314
|
+
console.log(pc.cyan('🚀 Next steps to start surfing:'));
|
|
315
|
+
console.log(`${pc.green(' cd')} ${pc.white(projectName)}`);
|
|
316
|
+
console.log(`${pc.green(' npm install')} ${pc.gray('# or pnpm install / yarn')}`);
|
|
317
|
+
console.log(`${pc.green(' npm run dev')} ${pc.gray('# Start development server')}\n`);
|
|
318
|
+
|
|
319
|
+
console.log(pc.cyan('📚 Documentation:'));
|
|
320
|
+
console.log(` ${pc.gray('https://letswhim.pages.dev')}\n`);
|
|
321
|
+
|
|
322
|
+
console.log(pc.gray('💡 Tip: Run ') + pc.white('npm run help') + pc.gray(' to see all available commands'));
|
|
323
|
+
|
|
324
|
+
// Fun ASCII footer
|
|
325
|
+
console.log(pc.blue(`
|
|
326
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
327
|
+
H A P P Y S U R F I N G ! 🏄♂️
|
|
328
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
329
|
+
`));
|
|
98
330
|
|
|
99
331
|
} catch (error) {
|
|
100
|
-
console.log(`\n${pc.red('
|
|
332
|
+
console.log(`\n${pc.red('💥 WIPEOUT!')} Something went wrong:`);
|
|
333
|
+
console.log(pc.gray(error.message));
|
|
334
|
+
|
|
335
|
+
// Clean up on error
|
|
336
|
+
if (fs.existsSync(targetDir)) {
|
|
337
|
+
try {
|
|
338
|
+
fs.rmSync(targetDir, { recursive: true });
|
|
339
|
+
console.log(pc.gray('\nCleaned up partial installation.'));
|
|
340
|
+
} catch (e) {
|
|
341
|
+
console.log(pc.gray('\nCould not clean up directory.'));
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
process.exit(1);
|
|
101
346
|
}
|
|
102
347
|
}
|
|
103
348
|
|
|
104
|
-
|
|
349
|
+
// Handle Ctrl+C gracefully
|
|
350
|
+
process.on('SIGINT', () => {
|
|
351
|
+
console.log(`\n\n${pc.gray('👋 Catch you on the next wave!')}\n`);
|
|
352
|
+
process.exit(0);
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
// Run the application
|
|
356
|
+
init().catch(error => {
|
|
357
|
+
console.error(`\n${pc.red('💥 UNEXPECTED WIPEOUT!')}`);
|
|
358
|
+
console.error(pc.gray(error.stack || error.message));
|
|
359
|
+
process.exit(1);
|
|
360
|
+
});
|
package/package.json
CHANGED
|
@@ -1,33 +1,42 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-letswhim",
|
|
3
|
-
"version": "2.0.
|
|
4
|
-
"description": "The official ultralight CLI to initialize your LetsWhim project
|
|
3
|
+
"version": "2.0.5",
|
|
4
|
+
"description": "The official ultralight CLI to initialize your LetsWhim project with surfing-style animations",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"bin": {
|
|
8
|
-
"create-letswhim": "index.js"
|
|
8
|
+
"create-letswhim": "./index.js",
|
|
9
|
+
"create-letswhim-surf": "./index.js"
|
|
9
10
|
},
|
|
10
11
|
"keywords": [
|
|
11
12
|
"letswhim",
|
|
12
13
|
"ssg",
|
|
13
|
-
"
|
|
14
|
-
"terminal
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
14
|
+
"cli",
|
|
15
|
+
"terminal",
|
|
16
|
+
"animation",
|
|
17
|
+
"surfing",
|
|
18
|
+
"minimalist",
|
|
19
|
+
"framework",
|
|
20
|
+
"create-app"
|
|
18
21
|
],
|
|
19
22
|
"author": "Rifky <rifky@keemail.me>",
|
|
20
23
|
"license": "MIT",
|
|
21
24
|
"repository": {
|
|
22
25
|
"type": "git",
|
|
23
|
-
"url": "git+https://github.com/ripkiiii/letswhim
|
|
26
|
+
"url": "git+https://github.com/ripkiiii/create-letswhim.git"
|
|
24
27
|
},
|
|
25
28
|
"bugs": {
|
|
26
|
-
"url": "https://github.com/ripkiiii/letswhim
|
|
29
|
+
"url": "https://github.com/ripkiiii/create-letswhim/"
|
|
27
30
|
},
|
|
28
31
|
"homepage": "https://letswhim.pages.dev",
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=14.0.0"
|
|
34
|
+
},
|
|
29
35
|
"dependencies": {
|
|
30
36
|
"picocolors": "^1.0.0",
|
|
31
37
|
"prompts": "^2.4.2"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/node": "^20.0.0"
|
|
32
41
|
}
|
|
33
42
|
}
|