blok0 0.1.1 → 0.1.3
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/handlers/add-block.js +29 -36
- package/dist/handlers/generate.js +18 -35
- package/dist/handlers/login.js +20 -29
- package/dist/index.js +25 -18
- package/dist/ui.d.ts +77 -0
- package/dist/ui.js +222 -0
- package/package.json +37 -33
- package/src/detectors.ts +22 -22
- package/src/handlers/add-block.ts +53 -40
- package/src/handlers/generate.ts +59 -62
- package/src/handlers/login.ts +40 -29
- package/src/index.ts +34 -18
- package/src/ui.ts +234 -0
- package/tsconfig.json +16 -16
package/src/handlers/login.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { isAuthenticated, clearCredentials, storeAccessToken, AuthCallback } from '../auth';
|
|
2
2
|
import { AuthServer } from '../auth/server';
|
|
3
3
|
import open from 'open';
|
|
4
|
+
import { withSpinner, log, showSection, EMOJIS } from '../ui';
|
|
4
5
|
|
|
5
6
|
// Add SIGINT handler for graceful cleanup
|
|
6
7
|
process.on('SIGINT', () => {
|
|
@@ -15,13 +16,15 @@ export async function handleLogin(token?: string, manual?: boolean): Promise<voi
|
|
|
15
16
|
// Direct token authentication (CI/CD)
|
|
16
17
|
if (token) {
|
|
17
18
|
try {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
await withSpinner(
|
|
20
|
+
'Saving authentication token',
|
|
21
|
+
() => storeAccessToken(token),
|
|
22
|
+
{ emoji: EMOJIS.LOCK, successText: 'Successfully authenticated!' }
|
|
23
|
+
);
|
|
21
24
|
console.log('');
|
|
22
|
-
|
|
25
|
+
log.info('You can now use blok0 commands that require authentication.');
|
|
23
26
|
} catch (error) {
|
|
24
|
-
|
|
27
|
+
log.error('Failed to save authentication token: ' + (error as Error).message);
|
|
25
28
|
process.exit(1);
|
|
26
29
|
}
|
|
27
30
|
return;
|
|
@@ -49,36 +52,40 @@ export async function handleLogin(token?: string, manual?: boolean): Promise<voi
|
|
|
49
52
|
* Handle browser-based authentication flow
|
|
50
53
|
*/
|
|
51
54
|
async function handleBrowserLogin(): Promise<void> {
|
|
52
|
-
|
|
53
|
-
console.log('======================');
|
|
54
|
-
console.log('');
|
|
55
|
+
showSection('🔐 Blok0 Authentication', EMOJIS.LOCK);
|
|
55
56
|
|
|
56
57
|
// Create authentication server
|
|
57
58
|
const authServer = new AuthServer();
|
|
58
59
|
|
|
59
60
|
try {
|
|
60
61
|
// Initialize server (find available port)
|
|
61
|
-
|
|
62
|
-
|
|
62
|
+
await withSpinner(
|
|
63
|
+
'Starting authentication server',
|
|
64
|
+
() => authServer.initialize(),
|
|
65
|
+
{ emoji: EMOJIS.ROCKET }
|
|
66
|
+
);
|
|
63
67
|
|
|
64
68
|
// Get the authorization URL (now port is available)
|
|
65
69
|
const authUrl = authServer.getAuthorizationUrl();
|
|
66
70
|
|
|
67
|
-
|
|
71
|
+
log.info('Opening browser for authentication...');
|
|
68
72
|
await open(authUrl);
|
|
69
73
|
|
|
70
|
-
|
|
71
|
-
|
|
74
|
+
log.info('Please complete authentication in your browser.');
|
|
75
|
+
log.plain('⏳ Waiting for authentication to complete...');
|
|
72
76
|
|
|
73
77
|
// Start server and wait for callback
|
|
74
78
|
const authCallback: AuthCallback = await authServer.start();
|
|
75
79
|
|
|
76
80
|
// Store the token
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
81
|
+
await withSpinner(
|
|
82
|
+
'Saving authentication token',
|
|
83
|
+
() => storeAccessToken(authCallback.token),
|
|
84
|
+
{ emoji: EMOJIS.LOCK, successText: 'Successfully authenticated!' }
|
|
85
|
+
);
|
|
86
|
+
|
|
80
87
|
console.log('');
|
|
81
|
-
|
|
88
|
+
log.info('You can now use blok0 commands that require authentication.');
|
|
82
89
|
|
|
83
90
|
} catch (error) {
|
|
84
91
|
authServer.stop();
|
|
@@ -90,23 +97,21 @@ async function handleBrowserLogin(): Promise<void> {
|
|
|
90
97
|
* Show manual authentication instructions
|
|
91
98
|
*/
|
|
92
99
|
function showManualInstructions(): void {
|
|
93
|
-
|
|
94
|
-
console.log('==============================');
|
|
95
|
-
console.log('');
|
|
100
|
+
showSection('🔐 Blok0 Manual Authentication', EMOJIS.LOCK);
|
|
96
101
|
console.log('To authenticate with the Blok0 API, make a POST request to:');
|
|
97
102
|
console.log('https://www.blok0.xyz/api/customers/login');
|
|
98
103
|
console.log('');
|
|
99
|
-
|
|
104
|
+
log.info('Example using curl:');
|
|
100
105
|
console.log('curl -X POST https://www.blok0.xyz/api/customers/login \\');
|
|
101
106
|
console.log(' -H "Content-Type: application/json" \\');
|
|
102
107
|
console.log(' -d \'{"email": "your-email@example.com", "password": "your-password"}\'');
|
|
103
108
|
console.log('');
|
|
104
|
-
|
|
109
|
+
log.info('Then copy the access token and run:');
|
|
105
110
|
console.log('blok0 login --token <your-token>');
|
|
106
111
|
console.log('');
|
|
107
|
-
|
|
112
|
+
log.info('For CI/CD environments, set the BLOK0_TOKEN environment variable.');
|
|
108
113
|
console.log('');
|
|
109
|
-
|
|
114
|
+
log.info('For browser-based login, run: blok0 login');
|
|
110
115
|
}
|
|
111
116
|
|
|
112
117
|
/**
|
|
@@ -114,17 +119,23 @@ function showManualInstructions(): void {
|
|
|
114
119
|
*/
|
|
115
120
|
export async function handleLogout(): Promise<void> {
|
|
116
121
|
try {
|
|
117
|
-
const wasAuthenticated = await
|
|
122
|
+
const wasAuthenticated = await withSpinner(
|
|
123
|
+
'Checking authentication status',
|
|
124
|
+
() => isAuthenticated()
|
|
125
|
+
);
|
|
118
126
|
|
|
119
127
|
if (!wasAuthenticated) {
|
|
120
|
-
|
|
128
|
+
log.warning('You are not currently logged in.');
|
|
121
129
|
return;
|
|
122
130
|
}
|
|
123
131
|
|
|
124
|
-
await
|
|
125
|
-
|
|
132
|
+
await withSpinner(
|
|
133
|
+
'Clearing stored credentials',
|
|
134
|
+
() => clearCredentials(),
|
|
135
|
+
{ emoji: EMOJIS.LOCK, successText: 'Successfully logged out and cleared stored credentials.' }
|
|
136
|
+
);
|
|
126
137
|
} catch (error) {
|
|
127
|
-
|
|
138
|
+
log.error('Failed to logout: ' + (error as Error).message);
|
|
128
139
|
process.exit(1);
|
|
129
140
|
}
|
|
130
141
|
}
|
package/src/index.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { generateStarter } from './handlers/generate';
|
|
|
7
7
|
import { handleLogin, handleLogout } from './handlers/login';
|
|
8
8
|
import { handleAddBlock } from './handlers/add-block';
|
|
9
9
|
import { createEmptyRegistry } from './registry';
|
|
10
|
+
import { setUIFlags } from './ui';
|
|
10
11
|
|
|
11
12
|
function prompt(question: string): Promise<string> {
|
|
12
13
|
return new Promise((resolve) => {
|
|
@@ -43,11 +44,14 @@ OPTIONS:
|
|
|
43
44
|
--version, -v Show version information
|
|
44
45
|
--verbose Enable verbose logging
|
|
45
46
|
--dry-run Preview changes without applying them
|
|
47
|
+
--no-animation Disable animations and spinners
|
|
48
|
+
--no-emoji Disable emoji in output
|
|
49
|
+
--ci Optimize for CI environments (implies --no-animation and --no-emoji)
|
|
46
50
|
|
|
47
51
|
EXAMPLES:
|
|
48
52
|
blok0 login
|
|
49
53
|
blok0 generate starter my-project
|
|
50
|
-
blok0 add block https://
|
|
54
|
+
blok0 add block https://www.blok0.com/api/cli/sections/123
|
|
51
55
|
|
|
52
56
|
For more information, visit: https://github.com/blok0-payload/cli
|
|
53
57
|
`);
|
|
@@ -56,18 +60,30 @@ For more information, visit: https://github.com/blok0-payload/cli
|
|
|
56
60
|
async function main() {
|
|
57
61
|
const args = process.argv.slice(2);
|
|
58
62
|
|
|
59
|
-
|
|
63
|
+
// Parse global UI flags
|
|
64
|
+
const noAnimation = args.includes('--no-animation');
|
|
65
|
+
const noEmoji = args.includes('--no-emoji');
|
|
66
|
+
const ciMode = args.includes('--ci');
|
|
67
|
+
|
|
68
|
+
setUIFlags({ noAnimation, noEmoji, ci: ciMode });
|
|
69
|
+
|
|
70
|
+
// Filter out global flags from args
|
|
71
|
+
const filteredArgs = args.filter(arg =>
|
|
72
|
+
!['--no-animation', '--no-emoji', '--ci'].includes(arg)
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
if (filteredArgs.length === 0 || filteredArgs.includes('--help') || filteredArgs.includes('-h')) {
|
|
60
76
|
showHelp();
|
|
61
77
|
process.exit(0);
|
|
62
78
|
}
|
|
63
79
|
|
|
64
|
-
if (
|
|
80
|
+
if (filteredArgs.includes('--version') || filteredArgs.includes('-v')) {
|
|
65
81
|
const pkg = require('../package.json');
|
|
66
82
|
console.log(`blok0 v${pkg.version}`);
|
|
67
83
|
process.exit(0);
|
|
68
84
|
}
|
|
69
85
|
|
|
70
|
-
const [command, ...restArgs] =
|
|
86
|
+
const [command, ...restArgs] = filteredArgs;
|
|
71
87
|
|
|
72
88
|
try {
|
|
73
89
|
switch (command) {
|
|
@@ -107,9 +123,9 @@ async function main() {
|
|
|
107
123
|
case 'add':
|
|
108
124
|
const [addSubcommand, ...addRestArgs] = restArgs;
|
|
109
125
|
if (addSubcommand === 'block') {
|
|
110
|
-
const blockUrl = addRestArgs[0]
|
|
126
|
+
const blockUrl = `https://www.blok0.com/api/cli/sections/${addRestArgs[0]}`;
|
|
111
127
|
if (!blockUrl) {
|
|
112
|
-
console.error('Error: Block
|
|
128
|
+
console.error('Error: Block Slug is required. Use: blok0 add block <slug>');
|
|
113
129
|
process.exit(1);
|
|
114
130
|
}
|
|
115
131
|
const options = {
|
|
@@ -118,7 +134,7 @@ async function main() {
|
|
|
118
134
|
};
|
|
119
135
|
await handleAddBlock(blockUrl, options);
|
|
120
136
|
} else {
|
|
121
|
-
console.error('Error: Invalid subcommand. Use: blok0 add block <
|
|
137
|
+
console.error('Error: Invalid subcommand. Use: blok0 add block <slug>');
|
|
122
138
|
process.exit(1);
|
|
123
139
|
}
|
|
124
140
|
break;
|
|
@@ -167,16 +183,16 @@ async function handleGenerateStarter(args: string[]) {
|
|
|
167
183
|
}
|
|
168
184
|
|
|
169
185
|
async function handleDebug() {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
186
|
+
const { showSection, log, withSpinner, EMOJIS } = await import('./ui');
|
|
187
|
+
|
|
188
|
+
showSection('🔍 Blok0 CLI Debug Information', EMOJIS.SEARCH);
|
|
173
189
|
|
|
174
190
|
// Check stored token
|
|
175
191
|
const { getAccessToken, isAuthenticated } = await import('./auth');
|
|
176
192
|
const token = await getAccessToken();
|
|
177
193
|
const isAuth = await isAuthenticated();
|
|
178
194
|
|
|
179
|
-
|
|
195
|
+
log.header('🔐 Authentication Status:');
|
|
180
196
|
console.log(` Authenticated: ${isAuth ? '✅ Yes' : '❌ No'}`);
|
|
181
197
|
console.log(` Token Stored: ${token ? '✅ Yes' : '❌ No'}`);
|
|
182
198
|
|
|
@@ -185,25 +201,25 @@ async function handleDebug() {
|
|
|
185
201
|
console.log(` Authorization Header: Bearer ${token}`);
|
|
186
202
|
}
|
|
187
203
|
|
|
188
|
-
|
|
189
|
-
console.log('🌐 API Configuration:');
|
|
204
|
+
log.header('🌐 API Configuration:');
|
|
190
205
|
console.log(' Base URL: https://www.blok0.xyz');
|
|
191
206
|
console.log(' User Agent: blok0-cli/1.0.0');
|
|
192
207
|
|
|
193
|
-
|
|
194
|
-
console.log('🧪 Test API Connection:');
|
|
208
|
+
log.header('🧪 Test API Connection:');
|
|
195
209
|
|
|
196
210
|
// Test API connection
|
|
197
211
|
const { apiClient } = await import('./api');
|
|
198
212
|
try {
|
|
199
|
-
const connectionTest = await
|
|
213
|
+
const connectionTest = await withSpinner(
|
|
214
|
+
'Testing API connection',
|
|
215
|
+
() => apiClient.testConnection()
|
|
216
|
+
);
|
|
200
217
|
console.log(` Connection Test: ${connectionTest ? '✅ Passed' : '❌ Failed'}`);
|
|
201
218
|
} catch (error) {
|
|
202
219
|
console.log(` Connection Test: ❌ Failed - ${(error as Error).message}`);
|
|
203
220
|
}
|
|
204
221
|
|
|
205
|
-
|
|
206
|
-
console.log('💡 Next Steps:');
|
|
222
|
+
log.header('💡 Next Steps:');
|
|
207
223
|
console.log(' 1. If no token, run: blok0 login');
|
|
208
224
|
console.log(' 2. Test API with: blok0 add block <url>');
|
|
209
225
|
console.log(' 3. Check server logs for detailed request info');
|
package/src/ui.ts
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import ora, { Ora } from 'ora';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { SingleBar } from 'cli-progress';
|
|
4
|
+
|
|
5
|
+
// Emoji constants for consistent usage
|
|
6
|
+
export const EMOJIS = {
|
|
7
|
+
SUCCESS: '✅',
|
|
8
|
+
ERROR: '❌',
|
|
9
|
+
WARNING: '⚠️',
|
|
10
|
+
INFO: 'ℹ️',
|
|
11
|
+
LOCK: '🔐',
|
|
12
|
+
PACKAGE: '📦',
|
|
13
|
+
FOLDER: '📁',
|
|
14
|
+
GEAR: '🔧',
|
|
15
|
+
SEARCH: '🔍',
|
|
16
|
+
ROCKET: '🚀',
|
|
17
|
+
DOWNLOAD: '📥',
|
|
18
|
+
PARTY: '🎉',
|
|
19
|
+
WRENCH: '🔧',
|
|
20
|
+
CHECK: '✅',
|
|
21
|
+
CROSS: '❌',
|
|
22
|
+
ARROW: '→',
|
|
23
|
+
} as const;
|
|
24
|
+
|
|
25
|
+
// Color utilities
|
|
26
|
+
export const colors = {
|
|
27
|
+
success: chalk.green,
|
|
28
|
+
error: chalk.red,
|
|
29
|
+
warning: chalk.yellow,
|
|
30
|
+
info: chalk.blue,
|
|
31
|
+
accent: chalk.cyan,
|
|
32
|
+
muted: chalk.gray,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// Check if we're in a TTY environment
|
|
36
|
+
export const isTTY = process.stdout.isTTY;
|
|
37
|
+
|
|
38
|
+
// Global flags for disabling features
|
|
39
|
+
export let noAnimation = false;
|
|
40
|
+
export let noEmoji = false;
|
|
41
|
+
export let ciMode = false;
|
|
42
|
+
|
|
43
|
+
// Set global flags
|
|
44
|
+
export function setUIFlags(flags: { noAnimation?: boolean; noEmoji?: boolean; ci?: boolean }) {
|
|
45
|
+
noAnimation = flags.noAnimation || ciMode;
|
|
46
|
+
noEmoji = flags.noEmoji || ciMode;
|
|
47
|
+
ciMode = flags.ci || false;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Apply emoji settings to text
|
|
51
|
+
function applyEmoji(text: string, emoji?: string): string {
|
|
52
|
+
if (noEmoji || !emoji) return text;
|
|
53
|
+
return `${emoji} ${text}`;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Spinner wrapper with TTY detection
|
|
57
|
+
export class Spinner {
|
|
58
|
+
private spinner: Ora | null = null;
|
|
59
|
+
private startTime: number = 0;
|
|
60
|
+
|
|
61
|
+
constructor(private text: string, private emoji?: string) {}
|
|
62
|
+
|
|
63
|
+
start(): this {
|
|
64
|
+
if (!isTTY || noAnimation) {
|
|
65
|
+
console.log(applyEmoji(this.text, this.emoji));
|
|
66
|
+
this.startTime = Date.now();
|
|
67
|
+
return this;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
this.spinner = ora({
|
|
71
|
+
text: applyEmoji(this.text, this.emoji),
|
|
72
|
+
spinner: 'dots',
|
|
73
|
+
}).start();
|
|
74
|
+
this.startTime = Date.now();
|
|
75
|
+
return this;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
update(text: string, emoji?: string): this {
|
|
79
|
+
if (!this.spinner) {
|
|
80
|
+
if (isTTY && !noAnimation) {
|
|
81
|
+
this.spinner = ora(applyEmoji(text, emoji)).start();
|
|
82
|
+
} else {
|
|
83
|
+
console.log(applyEmoji(text, emoji));
|
|
84
|
+
}
|
|
85
|
+
return this;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
this.spinner.text = applyEmoji(text, emoji || this.emoji);
|
|
89
|
+
return this;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
succeed(text?: string): this {
|
|
93
|
+
const duration = this.getDuration();
|
|
94
|
+
const successText = text || this.text;
|
|
95
|
+
const durationInfo = duration > 1000 ? ` (${duration}ms)` : '';
|
|
96
|
+
|
|
97
|
+
if (this.spinner) {
|
|
98
|
+
this.spinner.succeed(applyEmoji(successText, EMOJIS.SUCCESS) + durationInfo);
|
|
99
|
+
} else {
|
|
100
|
+
console.log(applyEmoji(successText + durationInfo, EMOJIS.SUCCESS));
|
|
101
|
+
}
|
|
102
|
+
return this;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
fail(text?: string): this {
|
|
106
|
+
const failText = text || this.text;
|
|
107
|
+
if (this.spinner) {
|
|
108
|
+
this.spinner.fail(applyEmoji(failText, EMOJIS.ERROR));
|
|
109
|
+
} else {
|
|
110
|
+
console.error(applyEmoji(failText, EMOJIS.ERROR));
|
|
111
|
+
}
|
|
112
|
+
return this;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
stop(): this {
|
|
116
|
+
if (this.spinner) {
|
|
117
|
+
this.spinner.stop();
|
|
118
|
+
}
|
|
119
|
+
return this;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
private getDuration(): number {
|
|
123
|
+
return Date.now() - this.startTime;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Utility function to wrap async operations with spinner
|
|
128
|
+
export async function withSpinner<T>(
|
|
129
|
+
text: string,
|
|
130
|
+
operation: () => Promise<T>,
|
|
131
|
+
options: { emoji?: string; successText?: string; failText?: string } = {}
|
|
132
|
+
): Promise<T> {
|
|
133
|
+
const spinner = new Spinner(text, options.emoji);
|
|
134
|
+
spinner.start();
|
|
135
|
+
|
|
136
|
+
try {
|
|
137
|
+
const result = await operation();
|
|
138
|
+
spinner.succeed(options.successText);
|
|
139
|
+
return result;
|
|
140
|
+
} catch (error) {
|
|
141
|
+
spinner.fail(options.failText);
|
|
142
|
+
throw error;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Progress bar utilities
|
|
147
|
+
export class ProgressBar {
|
|
148
|
+
private bar: SingleBar | null = null;
|
|
149
|
+
|
|
150
|
+
constructor(private options: {
|
|
151
|
+
title?: string;
|
|
152
|
+
total: number;
|
|
153
|
+
format?: string;
|
|
154
|
+
}) {}
|
|
155
|
+
|
|
156
|
+
start(): this {
|
|
157
|
+
if (!isTTY || noAnimation) {
|
|
158
|
+
if (this.options.title) {
|
|
159
|
+
console.log(this.options.title);
|
|
160
|
+
}
|
|
161
|
+
return this;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
this.bar = new SingleBar({
|
|
165
|
+
format: this.options.format || '{bar} {percentage}% | {value}/{total} | {eta}s',
|
|
166
|
+
barCompleteChar: '\u2588',
|
|
167
|
+
barIncompleteChar: '\u2591',
|
|
168
|
+
hideCursor: true,
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
if (this.options.title) {
|
|
172
|
+
console.log(this.options.title);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
this.bar.start(this.options.total, 0);
|
|
176
|
+
return this;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
update(current: number): this {
|
|
180
|
+
if (this.bar) {
|
|
181
|
+
this.bar.update(current);
|
|
182
|
+
} else if (isTTY && !noAnimation) {
|
|
183
|
+
// Fallback to simple progress if bar not initialized
|
|
184
|
+
const percent = Math.round((current / this.options.total) * 100);
|
|
185
|
+
process.stdout.write(`\r${this.options.title || 'Progress'}: ${percent}% (${current}/${this.options.total})`);
|
|
186
|
+
}
|
|
187
|
+
return this;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
increment(amount: number = 1): this {
|
|
191
|
+
if (this.bar) {
|
|
192
|
+
this.bar.increment(amount);
|
|
193
|
+
}
|
|
194
|
+
return this;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
stop(): this {
|
|
198
|
+
if (this.bar) {
|
|
199
|
+
this.bar.stop();
|
|
200
|
+
} else if (isTTY && !noAnimation) {
|
|
201
|
+
process.stdout.write('\n');
|
|
202
|
+
}
|
|
203
|
+
return this;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Enhanced console methods
|
|
208
|
+
export const log = {
|
|
209
|
+
success: (text: string) => console.log(colors.success(applyEmoji(text, EMOJIS.SUCCESS))),
|
|
210
|
+
error: (text: string) => console.error(colors.error(applyEmoji(text, EMOJIS.ERROR))),
|
|
211
|
+
warning: (text: string) => console.warn(colors.warning(applyEmoji(text, EMOJIS.WARNING))),
|
|
212
|
+
info: (text: string) => console.log(colors.info(applyEmoji(text, EMOJIS.INFO))),
|
|
213
|
+
plain: (text: string) => console.log(text),
|
|
214
|
+
header: (text: string) => console.log(colors.accent(`\n${text}\n`)),
|
|
215
|
+
step: (step: number, total: number, text: string) => {
|
|
216
|
+
const stepText = `${step}/${total}`;
|
|
217
|
+
console.log(colors.muted(`[${stepText}]`) + ' ' + text);
|
|
218
|
+
},
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
// Utility to show a section header
|
|
222
|
+
export function showSection(title: string, emoji?: string) {
|
|
223
|
+
console.log('\n' + colors.accent('='.repeat(50)));
|
|
224
|
+
console.log(applyEmoji(title, emoji));
|
|
225
|
+
console.log(colors.accent('='.repeat(50)) + '\n');
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Utility to show next steps
|
|
229
|
+
export function showNextSteps(steps: string[]) {
|
|
230
|
+
console.log(colors.accent('\nNext steps:'));
|
|
231
|
+
steps.forEach((step, index) => {
|
|
232
|
+
console.log(` ${index + 1}. ${step}`);
|
|
233
|
+
});
|
|
234
|
+
}
|
package/tsconfig.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2022",
|
|
4
|
-
"module": "commonjs",
|
|
5
|
-
"outDir": "./dist",
|
|
6
|
-
"rootDir": "./src",
|
|
7
|
-
"strict": true,
|
|
8
|
-
"esModuleInterop": true,
|
|
9
|
-
"skipLibCheck": true,
|
|
10
|
-
"forceConsistentCasingInFileNames": true,
|
|
11
|
-
"declaration": true,
|
|
12
|
-
"resolveJsonModule": true
|
|
13
|
-
},
|
|
14
|
-
"include": ["src/**/*.ts"],
|
|
15
|
-
"exclude": ["node_modules", "dist", "src/templates/**"]
|
|
16
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"outDir": "./dist",
|
|
6
|
+
"rootDir": "./src",
|
|
7
|
+
"strict": true,
|
|
8
|
+
"esModuleInterop": true,
|
|
9
|
+
"skipLibCheck": true,
|
|
10
|
+
"forceConsistentCasingInFileNames": true,
|
|
11
|
+
"declaration": true,
|
|
12
|
+
"resolveJsonModule": true
|
|
13
|
+
},
|
|
14
|
+
"include": ["src/**/*.ts"],
|
|
15
|
+
"exclude": ["node_modules", "dist", "src/templates/**"]
|
|
16
|
+
}
|