tiktok-live-api 1.2.4 → 1.2.6
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/bin/demo.mjs +167 -67
- package/package.json +1 -1
package/bin/demo.mjs
CHANGED
|
@@ -10,36 +10,72 @@ import path from 'path';
|
|
|
10
10
|
|
|
11
11
|
const REACT_TEMPLATE = [
|
|
12
12
|
'"use client";',
|
|
13
|
-
"import React, { useEffect, useState } from 'react';",
|
|
13
|
+
"import React, { useEffect, useState, useRef } from 'react';",
|
|
14
14
|
"import { TikTokLive } from 'tiktok-live-api';",
|
|
15
15
|
"",
|
|
16
16
|
"export default function TikTokLiveComponent() {",
|
|
17
17
|
" const [events, setEvents] = useState([]);",
|
|
18
18
|
" const [username, setUsername] = useState('aljazeeraenglish');",
|
|
19
|
+
" const [apiKey, setApiKey] = useState('demo_tiktokliveapi_public_2026');",
|
|
20
|
+
" const [inputUsername, setInputUsername] = useState('aljazeeraenglish');",
|
|
19
21
|
" const [connected, setConnected] = useState(false);",
|
|
20
|
-
" ",
|
|
22
|
+
" const clientRef = useRef(null);",
|
|
23
|
+
"",
|
|
21
24
|
" useEffect(() => {",
|
|
22
|
-
"
|
|
25
|
+
" if (!username) return;",
|
|
26
|
+
" if (clientRef.current) { clientRef.current.disconnect(); }",
|
|
27
|
+
" setEvents([]);",
|
|
28
|
+
" setConnected(false);",
|
|
29
|
+
" ",
|
|
30
|
+
" const client = new TikTokLive(username, { apiKey });",
|
|
31
|
+
" clientRef.current = client;",
|
|
23
32
|
" ",
|
|
24
|
-
|
|
25
|
-
|
|
33
|
+
" client.on('chat', (e) => setEvents(prev => [...prev.slice(-40), \"💬 \" + e.user.uniqueId + \": \" + e.comment]));",
|
|
34
|
+
" client.on('gift', (e) => setEvents(prev => [...prev.slice(-40), \"🎁 \" + e.user.uniqueId + \" sent \" + e.giftName]));",
|
|
35
|
+
" client.on('member', (e) => setEvents(prev => [...prev.slice(-40), \"👋 \" + e.user.uniqueId + \" joined\"]));",
|
|
36
|
+
" client.on('like', (e) => setEvents(prev => [...prev.slice(-40), \"❤️ \" + e.user.uniqueId + \" liked\"]));",
|
|
26
37
|
" client.on('connected', () => setConnected(true));",
|
|
27
38
|
" client.on('disconnected', () => setConnected(false));",
|
|
28
39
|
" ",
|
|
29
|
-
" client.connect();",
|
|
30
|
-
"
|
|
31
|
-
"
|
|
40
|
+
" client.connect().catch(() => setConnected(false));",
|
|
41
|
+
" ",
|
|
42
|
+
" return () => { if (clientRef.current) { clientRef.current.disconnect(); } };",
|
|
43
|
+
" }, [username, apiKey]);",
|
|
44
|
+
"",
|
|
45
|
+
" const handleConnect = (e) => {",
|
|
46
|
+
" e.preventDefault();",
|
|
47
|
+
" setUsername(inputUsername);",
|
|
48
|
+
" };",
|
|
32
49
|
"",
|
|
33
50
|
" return (",
|
|
34
|
-
" <div style={{ fontFamily: 'sans-serif', maxWidth:
|
|
35
|
-
" <
|
|
36
|
-
"
|
|
37
|
-
" <
|
|
38
|
-
"
|
|
51
|
+
" <div style={{ fontFamily: 'system-ui, sans-serif', maxWidth: 600, margin: '40px auto', border: '1px solid #e5e7eb', borderRadius: '12px', boxShadow: '0 10px 15px -3px rgba(0, 0, 0, 0.1)', background: '#fff' }}>",
|
|
52
|
+
" <div style={{ padding: '24px', borderBottom: '1px solid #e5e7eb' }}>",
|
|
53
|
+
" <h2 style={{ margin: '0 0 8px 0', fontSize: '1.5rem', fontWeight: 600 }}>TikTok Live SDK</h2>",
|
|
54
|
+
" <p style={{ margin: 0, fontSize: '0.875rem', color: '#6b7280' }}>",
|
|
55
|
+
" Get your own API key and unlock unlimited connections at <a href=\"https://tik.tools\" target=\"_blank\" style={{ color: '#3b82f6', textDecoration: 'none' }}>tik.tools</a>",
|
|
56
|
+
" </p>",
|
|
39
57
|
" </div>",
|
|
40
|
-
" <div style={{
|
|
41
|
-
"
|
|
42
|
-
"
|
|
58
|
+
" <div style={{ padding: '24px' }}>",
|
|
59
|
+
" <form onSubmit={handleConnect} style={{ display: 'flex', flexDirection: 'column', gap: '16px', marginBottom: '24px' }}>",
|
|
60
|
+
" <div>",
|
|
61
|
+
" <label style={{ display: 'block', fontSize: '0.875rem', fontWeight: 500, marginBottom: '6px' }}>TikTok Username</label>",
|
|
62
|
+
" <input type=\"text\" value={inputUsername} onChange={(e) => setInputUsername(e.target.value)} style={{ width: '100%', padding: '8px 12px', borderRadius: '6px', border: '1px solid #d1d5db', boxSizing: 'border-box' }} placeholder=\"e.g. aljazeeraenglish\" />",
|
|
63
|
+
" </div>",
|
|
64
|
+
" <div>",
|
|
65
|
+
" <label style={{ display: 'block', fontSize: '0.875rem', fontWeight: 500, marginBottom: '6px' }}>API Key</label>",
|
|
66
|
+
" <input type=\"text\" value={apiKey} onChange={(e) => setApiKey(e.target.value)} style={{ width: '100%', padding: '8px 12px', borderRadius: '6px', border: '1px solid #d1d5db', boxSizing: 'border-box', fontFamily: 'monospace' }} />",
|
|
67
|
+
" <p style={{ margin: '4px 0 0 0', fontSize: '0.75rem', color: '#9ca3af' }}>The demo key is rate-limited. Replace with your own key for production.</p>",
|
|
68
|
+
" </div>",
|
|
69
|
+
" <button type=\"submit\" style={{ background: '#000', color: '#fff', padding: '10px 16px', borderRadius: '6px', border: 'none', fontWeight: 500, cursor: 'pointer' }}>Connect Stream</button>",
|
|
70
|
+
" </form>",
|
|
71
|
+
" <div style={{ marginBottom: '16px', display: 'flex', alignItems: 'center', gap: '8px' }}>",
|
|
72
|
+
" <div style={{ width: 10, height: 10, borderRadius: '50%', background: connected ? '#10b981' : '#ef4444', transition: 'background 0.3s' }}></div>",
|
|
73
|
+
" <span style={{ fontSize: '0.875rem', color: '#374151', fontWeight: 500 }}>{connected ? 'Connected to @' + username : 'Disconnected'}</span>",
|
|
74
|
+
" </div>",
|
|
75
|
+
" <div style={{ height: 350, overflowY: 'auto', background: '#f9fafb', padding: '12px', borderRadius: '8px', border: '1px solid #e5e7eb', fontSize: '0.875rem', display: 'flex', flexDirection: 'column' }}>",
|
|
76
|
+
" {events.map((e, i) => <div key={i} style={{ padding: '6px 0', borderBottom: '1px solid #f3f4f6', wordBreak: 'break-word' }}>{e}</div>)}",
|
|
77
|
+
" {events.length === 0 && <div style={{ color: '#9ca3af', textAlign: 'center', margin: 'auto 0' }}>{connected ? 'Waiting for events...' : 'Connect to a valid stream to see events'}</div>}",
|
|
78
|
+
" </div>",
|
|
43
79
|
" </div>",
|
|
44
80
|
" </div>",
|
|
45
81
|
" );",
|
|
@@ -48,17 +84,36 @@ const REACT_TEMPLATE = [
|
|
|
48
84
|
|
|
49
85
|
const VUE_TEMPLATE = [
|
|
50
86
|
"<template>",
|
|
51
|
-
' <div style="font-family: sans-serif; max-width:
|
|
52
|
-
' <
|
|
53
|
-
'
|
|
54
|
-
|
|
55
|
-
|
|
87
|
+
' <div style="font-family: system-ui, sans-serif; max-width: 600px; margin: 40px auto; border: 1px solid #e5e7eb; border-radius: 12px; box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1); background: #fff">',
|
|
88
|
+
' <div style="padding: 24px; border-bottom: 1px solid #e5e7eb">',
|
|
89
|
+
' <h2 style="margin: 0 0 8px 0; font-size: 1.5rem; font-weight: 600">TikTok Live SDK</h2>',
|
|
90
|
+
' <p style="margin: 0; font-size: 0.875rem; color: #6b7280">',
|
|
91
|
+
' Get your own API key and unlock unlimited connections at <a href="https://tik.tools" target="_blank" style="color: #3b82f6; text-decoration: none">tik.tools</a>',
|
|
92
|
+
" </p>",
|
|
56
93
|
" </div>",
|
|
57
|
-
' <div style="
|
|
58
|
-
' <
|
|
59
|
-
"
|
|
94
|
+
' <div style="padding: 24px">',
|
|
95
|
+
' <form @submit.prevent="handleConnect" style="display: flex; flex-direction: column; gap: 16px; margin-bottom: 24px">',
|
|
96
|
+
" <div>",
|
|
97
|
+
' <label style="display: block; font-size: 0.875rem; font-weight: 500; margin-bottom: 6px">TikTok Username</label>',
|
|
98
|
+
' <input type="text" v-model="inputUsername" style="width: 100%; padding: 8px 12px; border-radius: 6px; border: 1px solid #d1d5db; box-sizing: border-box" placeholder="e.g. aljazeeraenglish" />',
|
|
99
|
+
" </div>",
|
|
100
|
+
" <div>",
|
|
101
|
+
' <label style="display: block; font-size: 0.875rem; font-weight: 500; margin-bottom: 6px">API Key</label>',
|
|
102
|
+
' <input type="text" v-model="apiKey" style="width: 100%; padding: 8px 12px; border-radius: 6px; border: 1px solid #d1d5db; box-sizing: border-box; font-family: monospace" />',
|
|
103
|
+
' <p style="margin: 4px 0 0 0; font-size: 0.75rem; color: #9ca3af">The demo key is rate-limited. Replace with your own key for production.</p>',
|
|
104
|
+
" </div>",
|
|
105
|
+
' <button type="submit" style="background: #000; color: #fff; padding: 10px 16px; border-radius: 6px; border: none; font-weight: 500; cursor: pointer">Connect Stream</button>',
|
|
106
|
+
" </form>",
|
|
107
|
+
' <div style="margin-bottom: 16px; display: flex; align-items: center; gap: 8px">',
|
|
108
|
+
" <div :style=\"{ width: '10px', height: '10px', borderRadius: '50%', background: connected ? '#10b981' : '#ef4444', transition: 'background 0.3s' }\"></div>",
|
|
109
|
+
" <span style=\"font-size: 0.875rem; color: '#374151'; font-weight: 500\">{{ connected ? 'Connected to @' + activeUsername : 'Disconnected' }}</span>",
|
|
110
|
+
" </div>",
|
|
111
|
+
' <div style="height: 350px; overflow-y: auto; background: #f9fafb; padding: 12px; border-radius: 8px; border: 1px solid #e5e7eb; font-size: 0.875rem; display: flex; flex-direction: column">',
|
|
112
|
+
' <div v-for="(e, i) in events" :key="i" style="padding: 6px 0; border-bottom: 1px solid #f3f4f6; word-break: break-word">',
|
|
113
|
+
" {{ e }}",
|
|
114
|
+
" </div>",
|
|
115
|
+
' <div v-if="events.length === 0" style="color: #9ca3af; text-align: center; margin: auto 0">{{ connected ? "Waiting for events..." : "Connect to a valid stream to see events" }}</div>',
|
|
60
116
|
" </div>",
|
|
61
|
-
' <div v-if="events.length === 0" style="color: #9ca3af; text-align: center; margin-top: 120px">Waiting for events...</div>',
|
|
62
117
|
" </div>",
|
|
63
118
|
" </div>",
|
|
64
119
|
"</template>",
|
|
@@ -67,28 +122,55 @@ const VUE_TEMPLATE = [
|
|
|
67
122
|
"import { ref, onMounted, onUnmounted } from 'vue'",
|
|
68
123
|
"import { TikTokLive } from 'tiktok-live-api'",
|
|
69
124
|
"",
|
|
70
|
-
"const
|
|
125
|
+
"const inputUsername = ref('aljazeeraenglish')",
|
|
126
|
+
"const activeUsername = ref('aljazeeraenglish')",
|
|
127
|
+
"const apiKey = ref('demo_tiktokliveapi_public_2026')",
|
|
71
128
|
"const connected = ref(false)",
|
|
72
129
|
"const events = ref([])",
|
|
73
130
|
"let client = null",
|
|
74
131
|
"",
|
|
75
|
-
"
|
|
76
|
-
" client
|
|
132
|
+
"const connectClient = () => {",
|
|
133
|
+
" if (client) client.disconnect()",
|
|
134
|
+
" events.value = []",
|
|
135
|
+
" connected.value = false",
|
|
136
|
+
" activeUsername.value = inputUsername.value",
|
|
137
|
+
" ",
|
|
138
|
+
" if (!activeUsername.value) return",
|
|
139
|
+
" ",
|
|
140
|
+
" client = new TikTokLive(activeUsername.value, { apiKey: apiKey.value })",
|
|
77
141
|
" ",
|
|
78
142
|
" client.on('chat', (e) => {",
|
|
79
143
|
' events.value.push("💬 " + e.user.uniqueId + ": " + e.comment)',
|
|
80
|
-
" if (events.value.length >
|
|
144
|
+
" if (events.value.length > 40) events.value.shift()",
|
|
81
145
|
" })",
|
|
82
146
|
" ",
|
|
83
147
|
" client.on('gift', (e) => {",
|
|
84
148
|
' events.value.push("🎁 " + e.user.uniqueId + " sent " + e.giftName)',
|
|
85
|
-
" if (events.value.length >
|
|
149
|
+
" if (events.value.length > 40) events.value.shift()",
|
|
150
|
+
" })",
|
|
151
|
+
"",
|
|
152
|
+
" client.on('member', (e) => {",
|
|
153
|
+
' events.value.push("👋 " + e.user.uniqueId + " joined")',
|
|
154
|
+
" if (events.value.length > 40) events.value.shift()",
|
|
155
|
+
" })",
|
|
156
|
+
" ",
|
|
157
|
+
" client.on('like', (e) => {",
|
|
158
|
+
' events.value.push("❤️ " + e.user.uniqueId + " liked")',
|
|
159
|
+
" if (events.value.length > 40) events.value.shift()",
|
|
86
160
|
" })",
|
|
87
161
|
"",
|
|
88
162
|
" client.on('connected', () => connected.value = true)",
|
|
89
163
|
" client.on('disconnected', () => connected.value = false)",
|
|
90
164
|
" ",
|
|
91
|
-
" client.connect()",
|
|
165
|
+
" client.connect().catch(() => connected.value = false)",
|
|
166
|
+
"}",
|
|
167
|
+
"",
|
|
168
|
+
"const handleConnect = () => {",
|
|
169
|
+
" connectClient()",
|
|
170
|
+
"}",
|
|
171
|
+
"",
|
|
172
|
+
"onMounted(() => {",
|
|
173
|
+
" connectClient()",
|
|
92
174
|
"})",
|
|
93
175
|
"",
|
|
94
176
|
"onUnmounted(() => {",
|
|
@@ -119,21 +201,16 @@ if (!isInteractive) {
|
|
|
119
201
|
|
|
120
202
|
console.log("\n " + B + "tiktok-live-api" + R + "\n Unofficial TikTok LIVE SDK by TikTool\n");
|
|
121
203
|
console.log(" What would you like to do?");
|
|
122
|
-
console.log(" 1) " + C.cyan + "Watch Live Terminal Demo" + R
|
|
204
|
+
console.log(" 1) " + C.cyan + "Watch Live Terminal Demo" + R);
|
|
123
205
|
console.log(" 2) " + C.green + "Scaffold a Nuxt 3 (Vue) App" + R);
|
|
124
206
|
console.log(" 3) " + C.blue + "Scaffold a Next.js (React) App" + R);
|
|
125
207
|
console.log(" 4) " + C.yellow + "Scaffold a Vite (React) App" + R + "\n");
|
|
126
208
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
rl.question(" Choose [1-4]: ", (answer) => {
|
|
134
|
-
clearTimeout(timeoutId);
|
|
135
|
-
handleMenu(answer.trim() || '1');
|
|
136
|
-
});
|
|
209
|
+
function promptAction() {
|
|
210
|
+
rl.question(" Choose [1-4]: ", (answer) => {
|
|
211
|
+
handleMenu(answer.trim());
|
|
212
|
+
});
|
|
213
|
+
}
|
|
137
214
|
|
|
138
215
|
function handleMenu(choice) {
|
|
139
216
|
if (choice === '1') {
|
|
@@ -143,55 +220,75 @@ if (!isInteractive) {
|
|
|
143
220
|
|
|
144
221
|
if (!['2', '3', '4'].includes(choice)) {
|
|
145
222
|
console.log(" " + C.red + "Invalid choice." + R);
|
|
146
|
-
|
|
147
|
-
process.exit(1);
|
|
223
|
+
return promptAction();
|
|
148
224
|
}
|
|
149
225
|
|
|
150
226
|
rl.question("\n Target directory (e.g. ./my-app) [./tiktok-live-project]: ", (dir) => {
|
|
151
227
|
dir = dir.trim() || './tiktok-live-project';
|
|
152
|
-
|
|
153
|
-
|
|
228
|
+
|
|
229
|
+
console.log("\n Select Package Manager:");
|
|
230
|
+
console.log(" 1) npm " + D + "(Default)" + R);
|
|
231
|
+
console.log(" 2) yarn");
|
|
232
|
+
console.log(" 3) pnpm");
|
|
233
|
+
console.log(" 4) bun");
|
|
234
|
+
|
|
235
|
+
rl.question("\n Choose [1-4]: ", (pmAnswer) => {
|
|
236
|
+
const pmChoice = pmAnswer.trim() || '1';
|
|
237
|
+
const pmMap = { '1': 'npm', '2': 'yarn', '3': 'pnpm', '4': 'bun' };
|
|
238
|
+
const pm = pmMap[pmChoice] || 'npm';
|
|
239
|
+
|
|
240
|
+
rl.close();
|
|
241
|
+
runScaffold(choice, dir, pm);
|
|
242
|
+
});
|
|
154
243
|
});
|
|
155
244
|
}
|
|
245
|
+
|
|
246
|
+
promptAction();
|
|
156
247
|
}
|
|
157
248
|
|
|
158
249
|
// ── Scaffolding Logic ───────────────────────────────────────────────────
|
|
159
250
|
|
|
160
|
-
function runScaffold(choice, targetDir) {
|
|
251
|
+
function runScaffold(choice, targetDir, pm) {
|
|
161
252
|
const isNuxt = choice === '2';
|
|
162
253
|
const isNext = choice === '3';
|
|
163
254
|
const isVite = choice === '4';
|
|
164
255
|
const fullPath = path.resolve(process.cwd(), targetDir);
|
|
165
256
|
|
|
166
|
-
|
|
257
|
+
const npxCmd = pm === 'bun' ? 'bunx' : (pm === 'pnpm' ? 'pnpm dlx' : 'npx');
|
|
258
|
+
const installCmd = pm === 'npm' ? 'npm install tiktok-live-api' : pm === 'yarn' ? 'yarn add tiktok-live-api' : pm === 'pnpm' ? 'pnpm add tiktok-live-api' : 'bun add tiktok-live-api';
|
|
259
|
+
const devCmd = pm === 'npm' ? 'npm run dev' : pm === 'yarn' ? 'yarn dev' : pm === 'pnpm' ? 'pnpm dev' : 'bun run dev';
|
|
260
|
+
|
|
261
|
+
console.log("\n " + B + "🚀 Scaffolding project into " + targetDir + " using " + pm + "..." + R + "\n");
|
|
167
262
|
|
|
168
263
|
try {
|
|
169
264
|
if (isNuxt) {
|
|
170
|
-
execSync('
|
|
265
|
+
execSync(npxCmd + ' nuxi@latest init "' + targetDir + '" --packageManager ' + pm, { stdio: 'inherit' });
|
|
171
266
|
} else if (isNext) {
|
|
172
|
-
execSync('
|
|
267
|
+
execSync(npxCmd + ' create-next-app@latest "' + targetDir + '" --js --eslint --tailwind --app --src-dir --import-alias "@/*" --use-' + pm, { stdio: 'inherit' });
|
|
173
268
|
} else if (isVite) {
|
|
174
|
-
|
|
269
|
+
const createCmd = pm === 'npm' ? 'npm create vite@latest' : pm === 'yarn' ? 'yarn create vite' : pm === 'pnpm' ? 'pnpm create vite' : 'bun create vite';
|
|
270
|
+
execSync(createCmd + ' "' + targetDir + '" -- --template react', { stdio: 'inherit' });
|
|
175
271
|
}
|
|
176
272
|
|
|
177
273
|
console.log("\n " + B + "📦 Installing " + C.cyan + "tiktok-live-api" + B + " SDK..." + R + "\n");
|
|
178
|
-
execSync(
|
|
274
|
+
execSync(installCmd, { cwd: fullPath, stdio: 'inherit' });
|
|
179
275
|
|
|
180
276
|
if (isNuxt) {
|
|
181
|
-
const
|
|
277
|
+
const isNuxt4 = fs.existsSync(path.join(fullPath, 'app', 'app.vue')) || !fs.existsSync(path.join(fullPath, 'app.vue'));
|
|
278
|
+
const baseApp = isNuxt4 ? path.join(fullPath, 'app') : fullPath;
|
|
279
|
+
|
|
280
|
+
const compDir = path.join(baseApp, 'components');
|
|
182
281
|
if (!fs.existsSync(compDir)) fs.mkdirSync(compDir, { recursive: true });
|
|
183
282
|
fs.writeFileSync(path.join(compDir, 'TikTokLive.vue'), VUE_TEMPLATE);
|
|
184
283
|
|
|
185
|
-
const appVue = path.join(
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
].join('\n') + '\n');
|
|
194
|
-
}
|
|
284
|
+
const appVue = path.join(baseApp, 'app.vue');
|
|
285
|
+
fs.writeFileSync(appVue, [
|
|
286
|
+
'<template>',
|
|
287
|
+
' <main style="min-height: 100vh; background: #f9fafb; padding-top: 40px;">',
|
|
288
|
+
' <TikTokLive />',
|
|
289
|
+
' </main>',
|
|
290
|
+
'</template>'
|
|
291
|
+
].join('\\n') + '\\n');
|
|
195
292
|
} else if (isNext) {
|
|
196
293
|
const compDir = path.join(fullPath, 'src', 'components');
|
|
197
294
|
if (!fs.existsSync(compDir)) fs.mkdirSync(compDir, { recursive: true });
|
|
@@ -204,7 +301,7 @@ function runScaffold(choice, targetDir) {
|
|
|
204
301
|
"",
|
|
205
302
|
"export default function Home() {",
|
|
206
303
|
" return (",
|
|
207
|
-
' <main
|
|
304
|
+
' <main style={{ minHeight: "100vh", background: "#f9fafb", paddingTop: "40px" }}>',
|
|
208
305
|
" <TikTokLive />",
|
|
209
306
|
" </main>",
|
|
210
307
|
" );",
|
|
@@ -223,9 +320,9 @@ function runScaffold(choice, targetDir) {
|
|
|
223
320
|
"",
|
|
224
321
|
"export default function App() {",
|
|
225
322
|
" return (",
|
|
226
|
-
|
|
323
|
+
' <main style={{ minHeight: "100vh", background: "#f9fafb", paddingTop: "40px" }}>',
|
|
227
324
|
" <TikTokLive />",
|
|
228
|
-
" </
|
|
325
|
+
" </main>",
|
|
229
326
|
" );",
|
|
230
327
|
"}"
|
|
231
328
|
].join('\n') + '\n');
|
|
@@ -235,7 +332,10 @@ function runScaffold(choice, targetDir) {
|
|
|
235
332
|
console.log("\n " + C.green + "✔ Project successfully scaffolded!" + R + "\n");
|
|
236
333
|
console.log(" " + B + "Next steps:" + R);
|
|
237
334
|
console.log(" cd " + targetDir);
|
|
238
|
-
|
|
335
|
+
if (isVite && pm !== 'bun') {
|
|
336
|
+
console.log(" " + pm + " install");
|
|
337
|
+
}
|
|
338
|
+
console.log(" " + devCmd + "\n");
|
|
239
339
|
|
|
240
340
|
} catch (err) {
|
|
241
341
|
console.error("\n " + C.red + "Error during scaffolding:" + R, err.message);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tiktok-live-api",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.6",
|
|
4
4
|
"description": "Unofficial TikTok LIVE API Client — Real-time chat, gifts, viewers, battles, and AI live captions from any TikTok livestream. Managed WebSocket API with 99.9% uptime.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|