fwdcast 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,623 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateDirectoryHtml = generateDirectoryHtml;
4
+ exports.sortEntries = sortEntries;
5
+ exports.generateHref = generateHref;
6
+ exports.escapeHtml = escapeHtml;
7
+ exports.getDirectChildren = getDirectChildren;
8
+ const validator_1 = require("./validator");
9
+ /**
10
+ * Gets the file icon based on file extension
11
+ */
12
+ function getFileIcon(name, isDirectory) {
13
+ if (isDirectory)
14
+ return '📁';
15
+ const ext = name.split('.').pop()?.toLowerCase() || '';
16
+ const iconMap = {
17
+ 'js': '🟨', 'ts': '🔷', 'jsx': '⚛️', 'tsx': '⚛️',
18
+ 'py': '🐍', 'go': '🔵', 'rs': '🦀', 'java': '☕',
19
+ 'html': '🌐', 'css': '🎨', 'scss': '🎨',
20
+ 'json': '📋', 'xml': '📋', 'yaml': '📋', 'yml': '📋',
21
+ 'md': '📝', 'txt': '📄', 'pdf': '📕',
22
+ 'png': '🖼️', 'jpg': '🖼️', 'jpeg': '🖼️', 'gif': '🖼️', 'svg': '🖼️',
23
+ 'zip': '📦', 'tar': '📦', 'gz': '📦',
24
+ 'sh': '💻', 'bash': '💻',
25
+ };
26
+ return iconMap[ext] || '📄';
27
+ }
28
+ /**
29
+ * Check if file is previewable as text
30
+ */
31
+ function isTextFile(name) {
32
+ const ext = name.split('.').pop()?.toLowerCase() || '';
33
+ const textExts = ['txt', 'md', 'json', 'js', 'ts', 'jsx', 'tsx', 'py', 'go', 'rs',
34
+ 'java', 'html', 'css', 'scss', 'xml', 'yaml', 'yml', 'sh', 'bash', 'c', 'cpp',
35
+ 'h', 'hpp', 'rb', 'php', 'swift', 'kt', 'toml', 'ini', 'cfg', 'conf', 'log',
36
+ 'gitignore', 'env', 'dockerfile'];
37
+ return textExts.includes(ext) || name.startsWith('.');
38
+ }
39
+ /**
40
+ * Check if file is an image
41
+ */
42
+ function isImageFile(name) {
43
+ const ext = name.split('.').pop()?.toLowerCase() || '';
44
+ return ['png', 'jpg', 'jpeg', 'gif', 'svg', 'webp', 'ico', 'bmp'].includes(ext);
45
+ }
46
+ /**
47
+ * Generates an HTML directory listing page with VS Code-style UI.
48
+ */
49
+ function generateDirectoryHtml(entries, currentPath, sessionId) {
50
+ const sortedEntries = sortEntries(entries);
51
+ const fileListItems = sortedEntries.map(entry => generateFileListItem(entry, currentPath, sessionId)).join('\n');
52
+ const breadcrumb = generateBreadcrumb(currentPath, sessionId);
53
+ const displayPath = currentPath || '/';
54
+ const baseUrl = sessionId ? `/${sessionId}` : '';
55
+ return `<!DOCTYPE html>
56
+ <html lang="en">
57
+ <head>
58
+ <meta charset="UTF-8">
59
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
60
+ <title>fwdcast - ${escapeHtml(displayPath)}</title>
61
+ <style>
62
+ * { box-sizing: border-box; margin: 0; padding: 0; }
63
+
64
+ :root {
65
+ --bg-primary: #1e1e1e;
66
+ --bg-secondary: #252526;
67
+ --bg-tertiary: #2d2d2d;
68
+ --bg-hover: #37373d;
69
+ --bg-active: #094771;
70
+ --text-primary: #cccccc;
71
+ --text-secondary: #858585;
72
+ --text-accent: #4fc1ff;
73
+ --border-color: #3c3c3c;
74
+ }
75
+
76
+ body {
77
+ font-family: 'Segoe UI', -apple-system, BlinkMacSystemFont, Roboto, sans-serif;
78
+ background: var(--bg-primary);
79
+ color: var(--text-primary);
80
+ height: 100vh;
81
+ overflow: hidden;
82
+ font-size: 13px;
83
+ }
84
+
85
+ .app {
86
+ display: flex;
87
+ flex-direction: column;
88
+ height: 100vh;
89
+ }
90
+
91
+ /* Title Bar */
92
+ .titlebar {
93
+ height: 30px;
94
+ background: var(--bg-tertiary);
95
+ display: flex;
96
+ align-items: center;
97
+ padding: 0 12px;
98
+ font-size: 12px;
99
+ color: var(--text-secondary);
100
+ border-bottom: 1px solid var(--border-color);
101
+ }
102
+
103
+ .titlebar-title {
104
+ flex: 1;
105
+ text-align: center;
106
+ }
107
+
108
+ /* Main Layout */
109
+ .main {
110
+ display: flex;
111
+ flex: 1;
112
+ overflow: hidden;
113
+ }
114
+
115
+ /* Activity Bar */
116
+ .activitybar {
117
+ width: 48px;
118
+ background: var(--bg-secondary);
119
+ display: flex;
120
+ flex-direction: column;
121
+ align-items: center;
122
+ padding-top: 8px;
123
+ border-right: 1px solid var(--border-color);
124
+ }
125
+
126
+ .activity-icon {
127
+ width: 48px;
128
+ height: 48px;
129
+ display: flex;
130
+ align-items: center;
131
+ justify-content: center;
132
+ font-size: 24px;
133
+ cursor: pointer;
134
+ opacity: 0.6;
135
+ border-left: 2px solid transparent;
136
+ }
137
+
138
+ .activity-icon.active {
139
+ opacity: 1;
140
+ border-left-color: var(--text-accent);
141
+ }
142
+
143
+ /* Sidebar */
144
+ .sidebar {
145
+ width: 240px;
146
+ background: var(--bg-secondary);
147
+ display: flex;
148
+ flex-direction: column;
149
+ border-right: 1px solid var(--border-color);
150
+ }
151
+
152
+ .sidebar-header {
153
+ padding: 10px 20px;
154
+ font-size: 11px;
155
+ font-weight: 600;
156
+ text-transform: uppercase;
157
+ letter-spacing: 1px;
158
+ color: var(--text-secondary);
159
+ display: flex;
160
+ justify-content: space-between;
161
+ align-items: center;
162
+ }
163
+
164
+ .download-all-btn {
165
+ font-size: 16px;
166
+ text-decoration: none;
167
+ opacity: 0.7;
168
+ cursor: pointer;
169
+ transition: opacity 0.2s;
170
+ }
171
+
172
+ .download-all-btn:hover {
173
+ opacity: 1;
174
+ }
175
+
176
+ .file-tree {
177
+ flex: 1;
178
+ overflow-y: auto;
179
+ overflow-x: hidden;
180
+ }
181
+
182
+ .tree-item {
183
+ display: flex;
184
+ align-items: center;
185
+ padding: 4px 8px 4px 20px;
186
+ cursor: pointer;
187
+ text-decoration: none;
188
+ color: var(--text-primary);
189
+ white-space: nowrap;
190
+ overflow: hidden;
191
+ }
192
+
193
+ .tree-item:hover {
194
+ background: var(--bg-hover);
195
+ }
196
+
197
+ .tree-item.active {
198
+ background: var(--bg-active);
199
+ }
200
+
201
+ .tree-icon {
202
+ width: 16px;
203
+ margin-right: 6px;
204
+ flex-shrink: 0;
205
+ font-size: 14px;
206
+ }
207
+
208
+ .tree-name {
209
+ overflow: hidden;
210
+ text-overflow: ellipsis;
211
+ flex: 1;
212
+ }
213
+
214
+ .tree-size {
215
+ font-size: 11px;
216
+ color: var(--text-secondary);
217
+ margin-left: 8px;
218
+ }
219
+
220
+ /* Editor Area */
221
+ .editor-area {
222
+ flex: 1;
223
+ display: flex;
224
+ flex-direction: column;
225
+ background: var(--bg-primary);
226
+ overflow: hidden;
227
+ }
228
+
229
+ /* Tabs */
230
+ .tabs {
231
+ display: flex;
232
+ background: var(--bg-tertiary);
233
+ border-bottom: 1px solid var(--border-color);
234
+ min-height: 35px;
235
+ }
236
+
237
+ .tab {
238
+ padding: 8px 16px;
239
+ background: var(--bg-secondary);
240
+ border-right: 1px solid var(--border-color);
241
+ cursor: pointer;
242
+ display: flex;
243
+ align-items: center;
244
+ gap: 6px;
245
+ font-size: 12px;
246
+ }
247
+
248
+ .tab.active {
249
+ background: var(--bg-primary);
250
+ }
251
+
252
+ .tab-icon {
253
+ font-size: 14px;
254
+ }
255
+
256
+ /* Breadcrumb */
257
+ .breadcrumb-bar {
258
+ padding: 4px 12px;
259
+ background: var(--bg-primary);
260
+ border-bottom: 1px solid var(--border-color);
261
+ font-size: 12px;
262
+ color: var(--text-secondary);
263
+ }
264
+
265
+ .breadcrumb-bar a {
266
+ color: var(--text-secondary);
267
+ text-decoration: none;
268
+ }
269
+
270
+ .breadcrumb-bar a:hover {
271
+ color: var(--text-accent);
272
+ }
273
+
274
+ /* Content */
275
+ .content {
276
+ flex: 1;
277
+ overflow: auto;
278
+ padding: 0;
279
+ }
280
+
281
+ .welcome {
282
+ padding: 40px;
283
+ text-align: center;
284
+ color: var(--text-secondary);
285
+ }
286
+
287
+ .welcome h2 {
288
+ font-size: 24px;
289
+ font-weight: 300;
290
+ margin-bottom: 16px;
291
+ color: var(--text-primary);
292
+ }
293
+
294
+ .welcome p {
295
+ font-size: 14px;
296
+ margin-bottom: 8px;
297
+ }
298
+
299
+ /* File Preview */
300
+ .preview {
301
+ height: 100%;
302
+ overflow: auto;
303
+ }
304
+
305
+ .preview-text {
306
+ padding: 16px;
307
+ font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
308
+ font-size: 13px;
309
+ line-height: 1.5;
310
+ white-space: pre-wrap;
311
+ word-wrap: break-word;
312
+ background: var(--bg-primary);
313
+ }
314
+
315
+ .preview-image {
316
+ display: flex;
317
+ align-items: center;
318
+ justify-content: center;
319
+ height: 100%;
320
+ padding: 20px;
321
+ }
322
+
323
+ .preview-image img {
324
+ max-width: 100%;
325
+ max-height: 100%;
326
+ object-fit: contain;
327
+ }
328
+
329
+ .preview-download {
330
+ display: flex;
331
+ flex-direction: column;
332
+ align-items: center;
333
+ justify-content: center;
334
+ height: 100%;
335
+ gap: 16px;
336
+ }
337
+
338
+ .preview-download .icon {
339
+ font-size: 64px;
340
+ }
341
+
342
+ .download-btn {
343
+ padding: 10px 24px;
344
+ background: var(--text-accent);
345
+ color: var(--bg-primary);
346
+ border: none;
347
+ border-radius: 4px;
348
+ cursor: pointer;
349
+ font-size: 14px;
350
+ text-decoration: none;
351
+ }
352
+
353
+ .download-btn:hover {
354
+ opacity: 0.9;
355
+ }
356
+
357
+ /* Loading */
358
+ .loading {
359
+ display: flex;
360
+ align-items: center;
361
+ justify-content: center;
362
+ height: 100%;
363
+ color: var(--text-secondary);
364
+ }
365
+
366
+ /* Status Bar */
367
+ .statusbar {
368
+ height: 22px;
369
+ background: #007acc;
370
+ display: flex;
371
+ align-items: center;
372
+ padding: 0 12px;
373
+ font-size: 12px;
374
+ color: white;
375
+ }
376
+
377
+ .statusbar-item {
378
+ margin-right: 16px;
379
+ }
380
+
381
+ /* Scrollbar */
382
+ ::-webkit-scrollbar { width: 10px; height: 10px; }
383
+ ::-webkit-scrollbar-track { background: var(--bg-primary); }
384
+ ::-webkit-scrollbar-thumb { background: #424242; border-radius: 5px; }
385
+ ::-webkit-scrollbar-thumb:hover { background: #555; }
386
+
387
+ @media (max-width: 768px) {
388
+ .activitybar, .sidebar { display: none; }
389
+ }
390
+ </style>
391
+ </head>
392
+ <body>
393
+ <div class="app">
394
+ <div class="titlebar">
395
+ <span class="titlebar-title">fwdcast - ${escapeHtml(displayPath)}</span>
396
+ </div>
397
+
398
+ <div class="main">
399
+ <div class="activitybar">
400
+ <div class="activity-icon active" title="Explorer">📁</div>
401
+ </div>
402
+
403
+ <div class="sidebar">
404
+ <div class="sidebar-header">
405
+ Explorer
406
+ <a href="${baseUrl}${currentPath ? '/' + currentPath : ''}/__download__.zip" class="download-all-btn" title="Download all as ZIP">📥</a>
407
+ </div>
408
+ <div class="file-tree" id="fileTree">
409
+ ${fileListItems}
410
+ </div>
411
+ </div>
412
+
413
+ <div class="editor-area">
414
+ <div class="tabs" id="tabs">
415
+ <div class="tab active">
416
+ <span class="tab-icon">📁</span>
417
+ <span>Welcome</span>
418
+ </div>
419
+ </div>
420
+
421
+ <div class="breadcrumb-bar">${breadcrumb}</div>
422
+
423
+ <div class="content" id="content">
424
+ <div class="welcome">
425
+ <h2>📡 fwdcast</h2>
426
+ <p>Select a file from the explorer to preview</p>
427
+ <p style="font-size: 12px; margin-top: 20px;">
428
+ ${sortedEntries.length} item${sortedEntries.length !== 1 ? 's' : ''} in this directory
429
+ </p>
430
+ </div>
431
+ </div>
432
+ </div>
433
+ </div>
434
+
435
+ <div class="statusbar">
436
+ <span class="statusbar-item">📡 Connected</span>
437
+ <span class="statusbar-item">${sortedEntries.filter(e => !e.isDirectory).length} files</span>
438
+ </div>
439
+ </div>
440
+
441
+ <script>
442
+ const baseUrl = '${baseUrl}';
443
+ const currentPath = '${escapeHtml(currentPath)}';
444
+ let activeFile = null;
445
+
446
+ // File data for preview decisions
447
+ const files = ${JSON.stringify(sortedEntries.map(e => ({
448
+ name: e.name,
449
+ isDirectory: e.isDirectory,
450
+ size: e.size,
451
+ href: generateHref(e, currentPath, sessionId)
452
+ })))};
453
+
454
+ function isTextFile(name) {
455
+ const ext = name.split('.').pop()?.toLowerCase() || '';
456
+ const textExts = ['txt', 'md', 'json', 'js', 'ts', 'jsx', 'tsx', 'py', 'go', 'rs',
457
+ 'java', 'html', 'css', 'scss', 'xml', 'yaml', 'yml', 'sh', 'bash', 'c', 'cpp',
458
+ 'h', 'hpp', 'rb', 'php', 'swift', 'kt', 'toml', 'ini', 'cfg', 'conf', 'log',
459
+ 'gitignore', 'env', 'dockerfile'];
460
+ return textExts.includes(ext) || name.startsWith('.');
461
+ }
462
+
463
+ function isImageFile(name) {
464
+ const ext = name.split('.').pop()?.toLowerCase() || '';
465
+ return ['png', 'jpg', 'jpeg', 'gif', 'svg', 'webp', 'ico', 'bmp'].includes(ext);
466
+ }
467
+
468
+ function getFileIcon(name, isDir) {
469
+ if (isDir) return '📁';
470
+ const ext = name.split('.').pop()?.toLowerCase() || '';
471
+ const icons = {
472
+ 'js': '🟨', 'ts': '🔷', 'py': '🐍', 'go': '🔵',
473
+ 'html': '🌐', 'css': '🎨', 'json': '📋', 'md': '📝',
474
+ 'txt': '📄', 'png': '🖼️', 'jpg': '🖼️', 'jpeg': '🖼️', 'gif': '🖼️', 'svg': '🖼️'
475
+ };
476
+ return icons[ext] || '📄';
477
+ }
478
+
479
+ document.querySelectorAll('.tree-item').forEach(item => {
480
+ item.addEventListener('click', async (e) => {
481
+ const href = item.getAttribute('href');
482
+ const name = item.dataset.name;
483
+ const isDir = item.dataset.isdir === 'true';
484
+
485
+ if (isDir) {
486
+ // Navigate to directory
487
+ window.location.href = href;
488
+ return;
489
+ }
490
+
491
+ e.preventDefault();
492
+
493
+ // Update active state
494
+ document.querySelectorAll('.tree-item').forEach(i => i.classList.remove('active'));
495
+ item.classList.add('active');
496
+
497
+ // Update tab
498
+ document.getElementById('tabs').innerHTML = \`
499
+ <div class="tab active">
500
+ <span class="tab-icon">\${getFileIcon(name, false)}</span>
501
+ <span>\${name}</span>
502
+ </div>
503
+ \`;
504
+
505
+ const content = document.getElementById('content');
506
+
507
+ if (isImageFile(name)) {
508
+ content.innerHTML = \`
509
+ <div class="preview-image">
510
+ <img src="\${href}" alt="\${name}">
511
+ </div>
512
+ \`;
513
+ } else if (isTextFile(name)) {
514
+ content.innerHTML = '<div class="loading">Loading...</div>';
515
+ try {
516
+ const res = await fetch(href);
517
+ const text = await res.text();
518
+ content.innerHTML = \`<div class="preview"><pre class="preview-text">\${escapeHtml(text)}</pre></div>\`;
519
+ } catch (err) {
520
+ content.innerHTML = '<div class="loading">Failed to load file</div>';
521
+ }
522
+ } else {
523
+ content.innerHTML = \`
524
+ <div class="preview-download">
525
+ <span class="icon">\${getFileIcon(name, false)}</span>
526
+ <span>\${name}</span>
527
+ <a href="\${href}" download class="download-btn">Download File</a>
528
+ </div>
529
+ \`;
530
+ }
531
+ });
532
+ });
533
+
534
+ function escapeHtml(str) {
535
+ const div = document.createElement('div');
536
+ div.textContent = str;
537
+ return div.innerHTML;
538
+ }
539
+ </script>
540
+ </body>
541
+ </html>`;
542
+ }
543
+ /**
544
+ * Generates breadcrumb navigation
545
+ */
546
+ function generateBreadcrumb(currentPath, sessionId) {
547
+ const parts = currentPath.split('/').filter(p => p);
548
+ const baseHref = sessionId ? `/${sessionId}/` : '/';
549
+ let html = `<a href="${baseHref}">~</a>`;
550
+ let pathSoFar = '';
551
+ for (const part of parts) {
552
+ pathSoFar += part + '/';
553
+ const href = sessionId ? `/${sessionId}/${pathSoFar}` : `/${pathSoFar}`;
554
+ html += ` / <a href="${escapeHtml(href)}">${escapeHtml(part)}</a>`;
555
+ }
556
+ return html;
557
+ }
558
+ /**
559
+ * Generates a file list item for the sidebar
560
+ */
561
+ function generateFileListItem(entry, currentPath, sessionId) {
562
+ const href = generateHref(entry, currentPath, sessionId);
563
+ const icon = getFileIcon(entry.name, entry.isDirectory);
564
+ const sizeDisplay = entry.isDirectory ? '' : (0, validator_1.formatSize)(entry.size);
565
+ return ` <a href="${escapeHtml(href)}" class="tree-item" data-name="${escapeHtml(entry.name)}" data-isdir="${entry.isDirectory}">
566
+ <span class="tree-icon">${icon}</span>
567
+ <span class="tree-name">${escapeHtml(entry.name)}${entry.isDirectory ? '/' : ''}</span>
568
+ ${sizeDisplay ? `<span class="tree-size">${sizeDisplay}</span>` : ''}
569
+ </a>`;
570
+ }
571
+ /**
572
+ * Sorts entries with directories first, then files, alphabetically within each group.
573
+ */
574
+ function sortEntries(entries) {
575
+ return [...entries].sort((a, b) => {
576
+ if (a.isDirectory && !b.isDirectory)
577
+ return -1;
578
+ if (!a.isDirectory && b.isDirectory)
579
+ return 1;
580
+ return a.name.toLowerCase().localeCompare(b.name.toLowerCase());
581
+ });
582
+ }
583
+ /**
584
+ * Generates the href link for an entry.
585
+ */
586
+ function generateHref(entry, currentPath, sessionId) {
587
+ const normalizedCurrent = currentPath.replace(/^\/+|\/+$/g, '');
588
+ let pathPart;
589
+ if (normalizedCurrent) {
590
+ pathPart = `${normalizedCurrent}/${entry.name}${entry.isDirectory ? '/' : ''}`;
591
+ }
592
+ else {
593
+ pathPart = `${entry.name}${entry.isDirectory ? '/' : ''}`;
594
+ }
595
+ if (sessionId) {
596
+ return `/${sessionId}/${pathPart}`;
597
+ }
598
+ return `/${pathPart}`;
599
+ }
600
+ /**
601
+ * Escapes HTML special characters to prevent XSS.
602
+ */
603
+ function escapeHtml(str) {
604
+ return str
605
+ .replace(/&/g, '&amp;')
606
+ .replace(/</g, '&lt;')
607
+ .replace(/>/g, '&gt;')
608
+ .replace(/"/g, '&quot;')
609
+ .replace(/'/g, '&#039;');
610
+ }
611
+ /**
612
+ * Filters entries to only include direct children of the given path.
613
+ */
614
+ function getDirectChildren(allEntries, parentPath) {
615
+ const normalizedParent = parentPath.replace(/^\/+|\/+$/g, '');
616
+ return allEntries.filter(entry => {
617
+ const entryDir = entry.relativePath.includes('/')
618
+ ? entry.relativePath.substring(0, entry.relativePath.lastIndexOf('/'))
619
+ : '';
620
+ return entryDir === normalizedParent;
621
+ });
622
+ }
623
+ //# sourceMappingURL=html-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html-generator.js","sourceRoot":"","sources":["../src/html-generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * fwdcast CLI - Temporary file sharing tool
4
+ * Streams local files as a public website without uploading them
5
+ *
6
+ * Requirements: 1.1, 1.5, 1.6, 7.1, 7.2, 7.4
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;GAKG"}