@picked/vite-plugin-picked 0.0.48-next.1 → 0.0.49-next.1

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/esm/index.js CHANGED
@@ -1,30 +1,900 @@
1
- import { fetchProject as $ } from "@picked/client/plugins/dynamic-experiences";
2
- const m = "picked", x = "\x1B[0m";
3
- function L() {
4
- const n = process.env.NO_COLOR;
5
- return n === "1" || n === "true";
1
+ import { createClientHeaders as R, fetchProject as g } from "@picked/client/plugins/dynamic-experiences";
2
+ var h = Object.freeze, I = Object.defineProperty, L = (e, t) => h(I(e, "raw", { value: h(t || e.slice()) })), y;
3
+ function b(e) {
4
+ const t = JSON.stringify(e), r = e.length > 0 ? e.map(
5
+ (n) => `
6
+ <div class="feature-row">
7
+ <label>
8
+ <input type="checkbox" data-feature-id="${S(n.id)}" checked>
9
+ <span class="feature-name">${w(n.name)}</span>
10
+ <span class="feature-id">${w(n.id)}</span>
11
+ </label>
12
+ <select data-value-for="${S(n.id)}">
13
+ <option value="true" selected>true</option>
14
+ <option value="false">false</option>
15
+ </select>
16
+ </div>`
17
+ ).join("") : '<p class="text no-features">No features configured for this project.</p>';
18
+ return String.raw(y || (y = L([`<!DOCTYPE html>
19
+ <html lang="en">
20
+ <head>
21
+ <meta charset="UTF-8">
22
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
23
+ <meta name="robots" content="noindex, nofollow">
24
+ <title>Picked</title>
25
+ <style>
26
+ main {
27
+ position: fixed;
28
+ top: 0;
29
+ right: 0;
30
+ bottom: 0;
31
+ left: 0;
32
+ display: grid;
33
+ align-items: center;
34
+ justify-content: center;
35
+ font-family: monospace;
36
+ color: #4A4A4A
37
+ }
38
+
39
+ .wrap {
40
+ padding-left: 1.5rem;
41
+ padding-right: 1.5rem;
42
+ max-width: 480px;
43
+ width: 100%;
44
+ }
45
+
46
+ .title {
47
+ font-size: 1.125rem;
48
+ font-weight: 700;
49
+ margin-bottom: 0;
50
+ }
51
+
52
+ .text {
53
+ margin-top: .5rem;
54
+ font-size: .875rem
55
+ }
56
+
57
+ .text a {
58
+ color: #4A4A4A;
59
+ text-decoration: none;
60
+ }
61
+
62
+ .text a:hover {
63
+ cursor: pointer;
64
+ text-decoration: underline
65
+ }
66
+
67
+ .preview-form {
68
+ margin-top: 2rem;
69
+ display: flex;
70
+ flex-direction: column;
71
+ gap: 0.5rem;
72
+ }
73
+
74
+ .preview-input {
75
+ padding: 0.5rem;
76
+ border: 1px solid #4A4A4A;
77
+ border-radius: 0;
78
+ font-family: monospace;
79
+ }
80
+
81
+ .preview-button {
82
+ padding: 0.5rem;
83
+ background: #4A4A4A;
84
+ color: white;
85
+ border: none;
86
+ border-radius: 0;
87
+ cursor: pointer;
88
+ font-family: monospace;
89
+ }
90
+
91
+ .preview-button:hover {
92
+ opacity: 0.9;
93
+ }
94
+
95
+ .buttons {
96
+ display: grid;
97
+ gap: 0.5em;
98
+ grid-template-columns: 1fr 1fr;
99
+ }
100
+
101
+ #copy-status {
102
+ font-size: 1em;
103
+ text-align: right;
104
+ margin-top: 0.5em;
105
+ }
106
+
107
+ .features-section {
108
+ margin-top: 1.5rem;
109
+ }
110
+
111
+ .features-label {
112
+ font-weight: 700;
113
+ font-size: .875rem;
114
+ margin-bottom: 0.5rem;
115
+ }
116
+
117
+ .feature-row {
118
+ display: flex;
119
+ align-items: center;
120
+ justify-content: space-between;
121
+ gap: 0.5rem;
122
+ padding: 0.25rem 0;
123
+ }
124
+
125
+ .feature-row label {
126
+ display: flex;
127
+ align-items: center;
128
+ gap: 0.5rem;
129
+ cursor: pointer;
130
+ min-width: 0;
131
+ flex: 1;
132
+ }
133
+
134
+ .feature-name {
135
+ font-size: .875rem;
136
+ }
137
+
138
+ .feature-id {
139
+ font-size: .75rem;
140
+ color: #888;
141
+ }
142
+
143
+ .feature-row select {
144
+ font-family: monospace;
145
+ font-size: .75rem;
146
+ padding: 0.125rem 0.25rem;
147
+ border: 1px solid #4A4A4A;
148
+ border-radius: 0;
149
+ background: white;
150
+ flex-shrink: 0;
151
+ }
152
+
153
+ .no-features {
154
+ color: #888;
155
+ font-style: italic;
156
+ }
157
+
158
+ .url-history {
159
+ margin-top: 0.5rem;
160
+ font-size: .75rem;
161
+ }
162
+
163
+ .url-history-item {
164
+ display: flex;
165
+ align-items: center;
166
+ gap: 0.25rem;
167
+ padding: 0.125rem 0;
168
+ }
169
+
170
+ .url-history-item button {
171
+ background: none;
172
+ border: none;
173
+ cursor: pointer;
174
+ font-family: monospace;
175
+ font-size: .75rem;
176
+ color: #888;
177
+ padding: 0;
178
+ }
179
+
180
+ .url-history-item button.url-link {
181
+ color: #4A4A4A;
182
+ text-decoration: none;
183
+ text-align: left;
184
+ overflow: hidden;
185
+ text-overflow: ellipsis;
186
+ white-space: nowrap;
187
+ flex: 1;
188
+ min-width: 0;
189
+ }
190
+
191
+ .url-history-item button.url-link:hover {
192
+ text-decoration: underline;
193
+ }
194
+
195
+ .url-history-item button.url-delete:hover {
196
+ color: #b71c1c;
197
+ }
198
+
199
+ @media (min-width: 640px) {
200
+ .title {
201
+ font-size: 1.25rem
202
+ }
203
+
204
+ .text {
205
+ font-size: 1rem
206
+ }
207
+ }
208
+ </style>
209
+ </head>
210
+ <body>
211
+
212
+ <main>
213
+ <div class="wrap">
214
+ <p class="title">Picked</p>
215
+ <p class="text">
216
+ Learn more at
217
+ <a href="https://picked.app">
218
+ https://picked.app
219
+ </a>
220
+ </p>
221
+ <div class="preview-form">
222
+ <input type="text" id="url-input" pattern="^(https?://)?.+" placeholder="Enter preview URL" required
223
+ class="preview-input">
224
+ <div id="url-history" class="url-history"></div>
225
+ <div class="features-section">
226
+ <p class="features-label">Features</p>
227
+ `, `
228
+ </div>
229
+ <div class="buttons">
230
+ <button type="button" class="preview-button" id="copy-btn">Copy</button>
231
+ <button type="button" class="preview-button" id="preview-btn">Preview</button>
232
+ </div>
233
+ <p class="text" id="copy-status" aria-live="polite" style="visibility:hidden;">
234
+ &nbsp;
235
+ </p>
236
+ </div>
237
+ </div>
238
+
239
+ <script>
240
+ var FEATURES = `, `;
241
+ var STORAGE_KEY_URL = 'picked-launcher-url';
242
+ var STORAGE_KEY_HISTORY = 'picked-launcher-history';
243
+ var STORAGE_KEY_SELECTIONS = 'picked-launcher-selections';
244
+
245
+ function getUrlInput() {
246
+ return document.getElementById('url-input');
247
+ }
248
+
249
+ // URL history
250
+ function getHistory() {
251
+ try {
252
+ var raw = localStorage.getItem(STORAGE_KEY_HISTORY);
253
+ if (!raw) return [];
254
+ var parsed = JSON.parse(raw);
255
+ return Array.isArray(parsed) ? parsed : [];
256
+ } catch (e) {
257
+ return [];
258
+ }
259
+ }
260
+
261
+ function saveHistory(history) {
262
+ localStorage.setItem(STORAGE_KEY_HISTORY, JSON.stringify(history));
263
+ }
264
+
265
+ function addToHistory(url) {
266
+ var history = getHistory().filter(function(h) { return h !== url; });
267
+ history.unshift(url);
268
+ if (history.length > 10) history = history.slice(0, 10);
269
+ saveHistory(history);
270
+ renderHistory();
271
+ }
272
+
273
+ function removeFromHistory(url) {
274
+ var history = getHistory().filter(function(h) { return h !== url; });
275
+ saveHistory(history);
276
+ renderHistory();
277
+ }
278
+
279
+ function renderHistory() {
280
+ var container = document.getElementById('url-history');
281
+ if (!container) return;
282
+ var history = getHistory();
283
+ if (history.length === 0) {
284
+ container.innerHTML = '';
285
+ return;
286
+ }
287
+ container.innerHTML = history.map(function(url) {
288
+ return '<div class="url-history-item">' +
289
+ '<button type="button" class="url-link" data-history-url="' + escapeAttr(url) + '">' + escapeHtml(url) + '</button>' +
290
+ '<button type="button" class="url-delete" data-history-delete="' + escapeAttr(url) + '">x</button>' +
291
+ '</div>';
292
+ }).join('');
293
+ }
294
+
295
+ // Feature selection persistence
296
+ function getSelections() {
297
+ try {
298
+ var raw = localStorage.getItem(STORAGE_KEY_SELECTIONS);
299
+ if (!raw) return {};
300
+ var parsed = JSON.parse(raw);
301
+ return typeof parsed === 'object' && parsed !== null ? parsed : {};
302
+ } catch (e) {
303
+ return {};
304
+ }
305
+ }
306
+
307
+ function saveSelections() {
308
+ var selections = {};
309
+ FEATURES.forEach(function(f) {
310
+ var checkbox = document.querySelector('input[data-feature-id="' + f.id + '"]');
311
+ var select = document.querySelector('select[data-value-for="' + f.id + '"]');
312
+ if (checkbox && select) {
313
+ selections[f.id] = { checked: checkbox.checked, value: select.value };
314
+ }
315
+ });
316
+ localStorage.setItem(STORAGE_KEY_SELECTIONS, JSON.stringify(selections));
317
+ }
318
+
319
+ function restoreSelections() {
320
+ var selections = getSelections();
321
+ FEATURES.forEach(function(f) {
322
+ var saved = selections[f.id];
323
+ if (!saved) return;
324
+ var checkbox = document.querySelector('input[data-feature-id="' + f.id + '"]');
325
+ var select = document.querySelector('select[data-value-for="' + f.id + '"]');
326
+ if (checkbox) checkbox.checked = saved.checked;
327
+ if (select) select.value = saved.value;
328
+ });
329
+ }
330
+
331
+ function escapeHtml(str) {
332
+ var div = document.createElement('div');
333
+ div.textContent = str;
334
+ return div.innerHTML;
335
+ }
336
+
337
+ function escapeAttr(str) {
338
+ return str.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
339
+ }
340
+
341
+ function buildTargetUrl(inputValue) {
342
+ var value = inputValue;
343
+ if (!value.startsWith('http://') && !value.startsWith('https://')) {
344
+ value = 'https://' + value;
345
+ }
346
+ var hostname = window.location.hostname;
347
+ var subdomain = hostname.split('.').length > 2 ? hostname.split('.')[0] : '';
348
+ var target = value;
349
+ var sep = target.includes('?') ? '&' : '?';
350
+ if (subdomain) {
351
+ target = target + sep + 'cvly_env=' + encodeURIComponent(subdomain);
352
+ sep = '&';
353
+ }
354
+ FEATURES.forEach(function(f) {
355
+ var checkbox = document.querySelector('input[data-feature-id="' + f.id + '"]');
356
+ var select = document.querySelector('select[data-value-for="' + f.id + '"]');
357
+ if (checkbox && checkbox.checked && select) {
358
+ target = target + sep + 'picked-feature=' + encodeURIComponent(f.id + ':' + select.value);
359
+ sep = '&';
360
+ }
361
+ });
362
+ return target;
363
+ }
364
+
365
+ function showCopyStatus(message, success) {
366
+ var el = document.getElementById('copy-status');
367
+ if (!el) return;
368
+ el.textContent = message;
369
+ el.style.visibility = 'visible';
370
+ el.style.color = success ? '#2e7d32' : '#b71c1c';
371
+ setTimeout(function() {
372
+ el.style.visibility = 'hidden';
373
+ }, 2000);
374
+ }
375
+
376
+ // Init
377
+ window.addEventListener('load', function() {
378
+ var input = getUrlInput();
379
+ var savedUrl = localStorage.getItem(STORAGE_KEY_URL);
380
+ if (savedUrl && input) {
381
+ input.value = savedUrl;
382
+ }
383
+ renderHistory();
384
+ restoreSelections();
385
+ });
386
+
387
+ // Delegate click events
388
+ document.addEventListener('click', function(e) {
389
+ var target = e.target;
390
+
391
+ // History URL click
392
+ var historyUrl = target.getAttribute('data-history-url');
393
+ if (historyUrl) {
394
+ var input = getUrlInput();
395
+ if (input) input.value = historyUrl;
396
+ return;
397
+ }
398
+
399
+ // History delete click
400
+ var deleteUrl = target.getAttribute('data-history-delete');
401
+ if (deleteUrl) {
402
+ removeFromHistory(deleteUrl);
403
+ return;
404
+ }
405
+ });
406
+
407
+ // Feature change persistence
408
+ document.addEventListener('change', function(e) {
409
+ var target = e.target;
410
+ if (target.getAttribute('data-feature-id') || target.getAttribute('data-value-for')) {
411
+ saveSelections();
412
+ }
413
+ });
414
+
415
+ // Copy button
416
+ document.getElementById('copy-btn').addEventListener('click', function() {
417
+ var input = getUrlInput();
418
+ if (!input || !input.value) return;
419
+ localStorage.setItem(STORAGE_KEY_URL, input.value);
420
+ addToHistory(input.value);
421
+ saveSelections();
422
+ var target = buildTargetUrl(input.value);
423
+ navigator.clipboard.writeText(target).then(function() {
424
+ showCopyStatus('Preview URL copied to clipboard', true);
425
+ });
426
+ });
427
+
428
+ // Preview button
429
+ document.getElementById('preview-btn').addEventListener('click', function() {
430
+ var input = getUrlInput();
431
+ if (!input || !input.value) return;
432
+ localStorage.setItem(STORAGE_KEY_URL, input.value);
433
+ addToHistory(input.value);
434
+ saveSelections();
435
+ var target = buildTargetUrl(input.value);
436
+ window.location.href = target;
437
+ });
438
+ <\/script>
439
+ </main>
440
+ </body>
441
+ </html>`], [`<!DOCTYPE html>
442
+ <html lang="en">
443
+ <head>
444
+ <meta charset="UTF-8">
445
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
446
+ <meta name="robots" content="noindex, nofollow">
447
+ <title>Picked</title>
448
+ <style>
449
+ main {
450
+ position: fixed;
451
+ top: 0;
452
+ right: 0;
453
+ bottom: 0;
454
+ left: 0;
455
+ display: grid;
456
+ align-items: center;
457
+ justify-content: center;
458
+ font-family: monospace;
459
+ color: #4A4A4A
460
+ }
461
+
462
+ .wrap {
463
+ padding-left: 1.5rem;
464
+ padding-right: 1.5rem;
465
+ max-width: 480px;
466
+ width: 100%;
467
+ }
468
+
469
+ .title {
470
+ font-size: 1.125rem;
471
+ font-weight: 700;
472
+ margin-bottom: 0;
473
+ }
474
+
475
+ .text {
476
+ margin-top: .5rem;
477
+ font-size: .875rem
478
+ }
479
+
480
+ .text a {
481
+ color: #4A4A4A;
482
+ text-decoration: none;
483
+ }
484
+
485
+ .text a:hover {
486
+ cursor: pointer;
487
+ text-decoration: underline
488
+ }
489
+
490
+ .preview-form {
491
+ margin-top: 2rem;
492
+ display: flex;
493
+ flex-direction: column;
494
+ gap: 0.5rem;
495
+ }
496
+
497
+ .preview-input {
498
+ padding: 0.5rem;
499
+ border: 1px solid #4A4A4A;
500
+ border-radius: 0;
501
+ font-family: monospace;
502
+ }
503
+
504
+ .preview-button {
505
+ padding: 0.5rem;
506
+ background: #4A4A4A;
507
+ color: white;
508
+ border: none;
509
+ border-radius: 0;
510
+ cursor: pointer;
511
+ font-family: monospace;
512
+ }
513
+
514
+ .preview-button:hover {
515
+ opacity: 0.9;
516
+ }
517
+
518
+ .buttons {
519
+ display: grid;
520
+ gap: 0.5em;
521
+ grid-template-columns: 1fr 1fr;
522
+ }
523
+
524
+ #copy-status {
525
+ font-size: 1em;
526
+ text-align: right;
527
+ margin-top: 0.5em;
528
+ }
529
+
530
+ .features-section {
531
+ margin-top: 1.5rem;
532
+ }
533
+
534
+ .features-label {
535
+ font-weight: 700;
536
+ font-size: .875rem;
537
+ margin-bottom: 0.5rem;
538
+ }
539
+
540
+ .feature-row {
541
+ display: flex;
542
+ align-items: center;
543
+ justify-content: space-between;
544
+ gap: 0.5rem;
545
+ padding: 0.25rem 0;
546
+ }
547
+
548
+ .feature-row label {
549
+ display: flex;
550
+ align-items: center;
551
+ gap: 0.5rem;
552
+ cursor: pointer;
553
+ min-width: 0;
554
+ flex: 1;
555
+ }
556
+
557
+ .feature-name {
558
+ font-size: .875rem;
559
+ }
560
+
561
+ .feature-id {
562
+ font-size: .75rem;
563
+ color: #888;
564
+ }
565
+
566
+ .feature-row select {
567
+ font-family: monospace;
568
+ font-size: .75rem;
569
+ padding: 0.125rem 0.25rem;
570
+ border: 1px solid #4A4A4A;
571
+ border-radius: 0;
572
+ background: white;
573
+ flex-shrink: 0;
574
+ }
575
+
576
+ .no-features {
577
+ color: #888;
578
+ font-style: italic;
579
+ }
580
+
581
+ .url-history {
582
+ margin-top: 0.5rem;
583
+ font-size: .75rem;
584
+ }
585
+
586
+ .url-history-item {
587
+ display: flex;
588
+ align-items: center;
589
+ gap: 0.25rem;
590
+ padding: 0.125rem 0;
591
+ }
592
+
593
+ .url-history-item button {
594
+ background: none;
595
+ border: none;
596
+ cursor: pointer;
597
+ font-family: monospace;
598
+ font-size: .75rem;
599
+ color: #888;
600
+ padding: 0;
601
+ }
602
+
603
+ .url-history-item button.url-link {
604
+ color: #4A4A4A;
605
+ text-decoration: none;
606
+ text-align: left;
607
+ overflow: hidden;
608
+ text-overflow: ellipsis;
609
+ white-space: nowrap;
610
+ flex: 1;
611
+ min-width: 0;
612
+ }
613
+
614
+ .url-history-item button.url-link:hover {
615
+ text-decoration: underline;
616
+ }
617
+
618
+ .url-history-item button.url-delete:hover {
619
+ color: #b71c1c;
620
+ }
621
+
622
+ @media (min-width: 640px) {
623
+ .title {
624
+ font-size: 1.25rem
625
+ }
626
+
627
+ .text {
628
+ font-size: 1rem
629
+ }
630
+ }
631
+ </style>
632
+ </head>
633
+ <body>
634
+
635
+ <main>
636
+ <div class="wrap">
637
+ <p class="title">Picked</p>
638
+ <p class="text">
639
+ Learn more at
640
+ <a href="https://picked.app">
641
+ https://picked.app
642
+ </a>
643
+ </p>
644
+ <div class="preview-form">
645
+ <input type="text" id="url-input" pattern="^(https?:\\/\\/)?.+" placeholder="Enter preview URL" required
646
+ class="preview-input">
647
+ <div id="url-history" class="url-history"></div>
648
+ <div class="features-section">
649
+ <p class="features-label">Features</p>
650
+ `, `
651
+ </div>
652
+ <div class="buttons">
653
+ <button type="button" class="preview-button" id="copy-btn">Copy</button>
654
+ <button type="button" class="preview-button" id="preview-btn">Preview</button>
655
+ </div>
656
+ <p class="text" id="copy-status" aria-live="polite" style="visibility:hidden;">
657
+ &nbsp;
658
+ </p>
659
+ </div>
660
+ </div>
661
+
662
+ <script>
663
+ var FEATURES = `, `;
664
+ var STORAGE_KEY_URL = 'picked-launcher-url';
665
+ var STORAGE_KEY_HISTORY = 'picked-launcher-history';
666
+ var STORAGE_KEY_SELECTIONS = 'picked-launcher-selections';
667
+
668
+ function getUrlInput() {
669
+ return document.getElementById('url-input');
670
+ }
671
+
672
+ // URL history
673
+ function getHistory() {
674
+ try {
675
+ var raw = localStorage.getItem(STORAGE_KEY_HISTORY);
676
+ if (!raw) return [];
677
+ var parsed = JSON.parse(raw);
678
+ return Array.isArray(parsed) ? parsed : [];
679
+ } catch (e) {
680
+ return [];
681
+ }
682
+ }
683
+
684
+ function saveHistory(history) {
685
+ localStorage.setItem(STORAGE_KEY_HISTORY, JSON.stringify(history));
686
+ }
687
+
688
+ function addToHistory(url) {
689
+ var history = getHistory().filter(function(h) { return h !== url; });
690
+ history.unshift(url);
691
+ if (history.length > 10) history = history.slice(0, 10);
692
+ saveHistory(history);
693
+ renderHistory();
694
+ }
695
+
696
+ function removeFromHistory(url) {
697
+ var history = getHistory().filter(function(h) { return h !== url; });
698
+ saveHistory(history);
699
+ renderHistory();
700
+ }
701
+
702
+ function renderHistory() {
703
+ var container = document.getElementById('url-history');
704
+ if (!container) return;
705
+ var history = getHistory();
706
+ if (history.length === 0) {
707
+ container.innerHTML = '';
708
+ return;
709
+ }
710
+ container.innerHTML = history.map(function(url) {
711
+ return '<div class="url-history-item">' +
712
+ '<button type="button" class="url-link" data-history-url="' + escapeAttr(url) + '">' + escapeHtml(url) + '</button>' +
713
+ '<button type="button" class="url-delete" data-history-delete="' + escapeAttr(url) + '">x</button>' +
714
+ '</div>';
715
+ }).join('');
716
+ }
717
+
718
+ // Feature selection persistence
719
+ function getSelections() {
720
+ try {
721
+ var raw = localStorage.getItem(STORAGE_KEY_SELECTIONS);
722
+ if (!raw) return {};
723
+ var parsed = JSON.parse(raw);
724
+ return typeof parsed === 'object' && parsed !== null ? parsed : {};
725
+ } catch (e) {
726
+ return {};
727
+ }
728
+ }
729
+
730
+ function saveSelections() {
731
+ var selections = {};
732
+ FEATURES.forEach(function(f) {
733
+ var checkbox = document.querySelector('input[data-feature-id="' + f.id + '"]');
734
+ var select = document.querySelector('select[data-value-for="' + f.id + '"]');
735
+ if (checkbox && select) {
736
+ selections[f.id] = { checked: checkbox.checked, value: select.value };
737
+ }
738
+ });
739
+ localStorage.setItem(STORAGE_KEY_SELECTIONS, JSON.stringify(selections));
740
+ }
741
+
742
+ function restoreSelections() {
743
+ var selections = getSelections();
744
+ FEATURES.forEach(function(f) {
745
+ var saved = selections[f.id];
746
+ if (!saved) return;
747
+ var checkbox = document.querySelector('input[data-feature-id="' + f.id + '"]');
748
+ var select = document.querySelector('select[data-value-for="' + f.id + '"]');
749
+ if (checkbox) checkbox.checked = saved.checked;
750
+ if (select) select.value = saved.value;
751
+ });
752
+ }
753
+
754
+ function escapeHtml(str) {
755
+ var div = document.createElement('div');
756
+ div.textContent = str;
757
+ return div.innerHTML;
758
+ }
759
+
760
+ function escapeAttr(str) {
761
+ return str.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
762
+ }
763
+
764
+ function buildTargetUrl(inputValue) {
765
+ var value = inputValue;
766
+ if (!value.startsWith('http://') && !value.startsWith('https://')) {
767
+ value = 'https://' + value;
768
+ }
769
+ var hostname = window.location.hostname;
770
+ var subdomain = hostname.split('.').length > 2 ? hostname.split('.')[0] : '';
771
+ var target = value;
772
+ var sep = target.includes('?') ? '&' : '?';
773
+ if (subdomain) {
774
+ target = target + sep + 'cvly_env=' + encodeURIComponent(subdomain);
775
+ sep = '&';
776
+ }
777
+ FEATURES.forEach(function(f) {
778
+ var checkbox = document.querySelector('input[data-feature-id="' + f.id + '"]');
779
+ var select = document.querySelector('select[data-value-for="' + f.id + '"]');
780
+ if (checkbox && checkbox.checked && select) {
781
+ target = target + sep + 'picked-feature=' + encodeURIComponent(f.id + ':' + select.value);
782
+ sep = '&';
783
+ }
784
+ });
785
+ return target;
786
+ }
787
+
788
+ function showCopyStatus(message, success) {
789
+ var el = document.getElementById('copy-status');
790
+ if (!el) return;
791
+ el.textContent = message;
792
+ el.style.visibility = 'visible';
793
+ el.style.color = success ? '#2e7d32' : '#b71c1c';
794
+ setTimeout(function() {
795
+ el.style.visibility = 'hidden';
796
+ }, 2000);
797
+ }
798
+
799
+ // Init
800
+ window.addEventListener('load', function() {
801
+ var input = getUrlInput();
802
+ var savedUrl = localStorage.getItem(STORAGE_KEY_URL);
803
+ if (savedUrl && input) {
804
+ input.value = savedUrl;
805
+ }
806
+ renderHistory();
807
+ restoreSelections();
808
+ });
809
+
810
+ // Delegate click events
811
+ document.addEventListener('click', function(e) {
812
+ var target = e.target;
813
+
814
+ // History URL click
815
+ var historyUrl = target.getAttribute('data-history-url');
816
+ if (historyUrl) {
817
+ var input = getUrlInput();
818
+ if (input) input.value = historyUrl;
819
+ return;
820
+ }
821
+
822
+ // History delete click
823
+ var deleteUrl = target.getAttribute('data-history-delete');
824
+ if (deleteUrl) {
825
+ removeFromHistory(deleteUrl);
826
+ return;
827
+ }
828
+ });
829
+
830
+ // Feature change persistence
831
+ document.addEventListener('change', function(e) {
832
+ var target = e.target;
833
+ if (target.getAttribute('data-feature-id') || target.getAttribute('data-value-for')) {
834
+ saveSelections();
835
+ }
836
+ });
837
+
838
+ // Copy button
839
+ document.getElementById('copy-btn').addEventListener('click', function() {
840
+ var input = getUrlInput();
841
+ if (!input || !input.value) return;
842
+ localStorage.setItem(STORAGE_KEY_URL, input.value);
843
+ addToHistory(input.value);
844
+ saveSelections();
845
+ var target = buildTargetUrl(input.value);
846
+ navigator.clipboard.writeText(target).then(function() {
847
+ showCopyStatus('Preview URL copied to clipboard', true);
848
+ });
849
+ });
850
+
851
+ // Preview button
852
+ document.getElementById('preview-btn').addEventListener('click', function() {
853
+ var input = getUrlInput();
854
+ if (!input || !input.value) return;
855
+ localStorage.setItem(STORAGE_KEY_URL, input.value);
856
+ addToHistory(input.value);
857
+ saveSelections();
858
+ var target = buildTargetUrl(input.value);
859
+ window.location.href = target;
860
+ });
861
+ <\/script>
862
+ </main>
863
+ </body>
864
+ </html>`])), r, t);
865
+ }
866
+ function w(e) {
867
+ return e.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;");
868
+ }
869
+ function S(e) {
870
+ return e.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
6
871
  }
7
- function l(n) {
8
- return (e) => L() ? e : `${n}${e}${x}`;
872
+ const E = "picked", H = "\x1B[0m";
873
+ function O() {
874
+ const e = process.env.NO_COLOR;
875
+ return e === "1" || e === "true";
9
876
  }
10
- const b = ["debug", "info", "warn", "error", "silent"], u = {
877
+ function c(e) {
878
+ return (t) => O() ? t : `${e}${t}${H}`;
879
+ }
880
+ const x = ["debug", "info", "warn", "error", "silent"], m = {
11
881
  debug: {
12
- color: l("\x1B[2m"),
882
+ color: c("\x1B[2m"),
13
883
  log: console.debug,
14
884
  enabled: !1
15
885
  },
16
886
  info: {
17
- color: l("\x1B[36m"),
887
+ color: c("\x1B[36m"),
18
888
  log: console.log,
19
889
  enabled: !0
20
890
  },
21
891
  warn: {
22
- color: l("\x1B[33m"),
892
+ color: c("\x1B[33m"),
23
893
  log: console.warn,
24
894
  enabled: !0
25
895
  },
26
896
  error: {
27
- color: l("\x1B[31m"),
897
+ color: c("\x1B[31m"),
28
898
  log: console.error,
29
899
  enabled: !0
30
900
  },
@@ -34,119 +904,162 @@ const b = ["debug", "info", "warn", "error", "silent"], u = {
34
904
  enabled: !1
35
905
  }
36
906
  };
37
- function I(n, e) {
38
- const o = (/* @__PURE__ */ new Date()).toLocaleTimeString(), t = e ? `${m}:${e}` : m;
39
- return `${o} [${t}] ${n}`;
907
+ function $(e, t) {
908
+ const r = (/* @__PURE__ */ new Date()).toLocaleTimeString(), n = t ? `${E}:${t}` : E;
909
+ return `${r} [${n}] ${e}`;
40
910
  }
41
- function g(n, e, o, t) {
42
- if (!n.enabled)
911
+ function v(e, t, r, n) {
912
+ if (!e.enabled)
43
913
  return;
44
- const r = I(e, t);
45
- n.log(n.color ? n.color(r) : r), o !== void 0 && n.log(o);
914
+ const o = $(t, n);
915
+ e.log(e.color ? e.color(o) : o), r !== void 0 && e.log(r);
46
916
  }
47
- function d(n) {
48
- const e = u[n], o = /* @__PURE__ */ new Set();
917
+ function p(e) {
918
+ const t = m[e], r = /* @__PURE__ */ new Set();
49
919
  return Object.assign(
50
- (t, r, c) => {
51
- g(e, t, r, c);
920
+ (n, o, i) => {
921
+ v(t, n, o, i);
52
922
  },
53
923
  {
54
- once(t, r, c) {
55
- !e.enabled || o.has(t) || (o.add(t), g(e, t, r, c));
924
+ once(n, o, i) {
925
+ !t.enabled || r.has(n) || (r.add(n), v(t, n, o, i));
56
926
  }
57
927
  }
58
928
  );
59
929
  }
60
- function R(n) {
61
- const e = b.indexOf(n);
62
- if (e === -1) {
63
- g(u.error, `invalid log level: ${n}`);
930
+ function C(e) {
931
+ const t = x.indexOf(e);
932
+ if (t === -1) {
933
+ v(m.error, `invalid log level: ${e}`);
64
934
  return;
65
935
  }
66
- for (const [o, t] of b.entries())
67
- u[t].enabled = o >= e;
68
- }
69
- const s = l("\x1B[34m"), h = l("\x1B[36m");
70
- function y() {
71
- const n = [
72
- ` ${s("_")} ${h("_")} _ _ _`,
73
- `${s("(_)")} ${h("(_)")} _ __(_)__| |_____ __| |`,
936
+ for (const [r, n] of x.entries())
937
+ m[n].enabled = r >= t;
938
+ }
939
+ const s = c("\x1B[34m"), _ = c("\x1B[36m");
940
+ function Y() {
941
+ const e = [
942
+ ` ${s("_")} ${_("_")} _ _ _`,
943
+ `${s("(_)")} ${_("(_)")} _ __(_)__| |_____ __| |`,
74
944
  ` ${s("_")} ${s("_")} | '_ \\ / _| / / -_) _\` |`,
75
945
  `${s("(_)")} ${s("(_)")} | .__/_\\__|_\\_\\___\\__,_|`,
76
946
  ` |_|
77
947
  `
78
948
  ];
79
- console.log(n.join(`
949
+ console.log(e.join(`
80
950
  `));
81
951
  }
82
- const a = {
83
- banner: y,
84
- debug: d("debug"),
85
- info: d("info"),
86
- warn: d("warn"),
87
- error: d("error"),
88
- setLevel: R
952
+ const l = {
953
+ banner: Y,
954
+ debug: p("debug"),
955
+ info: p("info"),
956
+ warn: p("warn"),
957
+ error: p("error"),
958
+ setLevel: C
89
959
  };
90
- function B(n) {
91
- if (n.length === 0)
960
+ function B(e) {
961
+ return (t, r, n) => {
962
+ if (t.method !== "GET") {
963
+ n();
964
+ return;
965
+ }
966
+ const i = (t.url ?? "").split("?")[0];
967
+ if (i !== "/" && i !== "/index.html") {
968
+ n();
969
+ return;
970
+ }
971
+ const a = e();
972
+ r.setHeader("Content-Type", "text/html"), r.statusCode = 200, r.end(a);
973
+ };
974
+ }
975
+ function F(e) {
976
+ if (e.length === 0)
92
977
  return;
93
- const e = Math.max(4, ...n.map((i) => i.name.length)), o = Math.max(2, ...n.map((i) => i.id.length)), t = ` ${"Name".padEnd(e)} ${"ID".padEnd(o)} Status Weight Ver`, r = ` ${"─".repeat(e)} ${"─".repeat(o)} ──────── ────── ───`, c = n.map((i) => {
94
- const f = i.enabled ? "\x1B[32m enabled\x1B[0m" : "\x1B[2mdisabled\x1B[0m", _ = `${i.weight.toString()}%`.padStart(6), S = `v${i.version.toString()}`;
95
- return ` ${i.name.padEnd(e)} ${i.id.padEnd(o)} ${f} ${_} ${S}`;
978
+ const t = Math.max(4, ...e.map((a) => a.name.length)), r = Math.max(2, ...e.map((a) => a.id.length)), n = ` ${"Name".padEnd(t)} ${"ID".padEnd(r)} Status Weight Ver`, o = ` ${"─".repeat(t)} ${"─".repeat(r)} ──────── ────── ───`, i = e.map((a) => {
979
+ const d = a.enabled ? "\x1B[32m enabled\x1B[0m" : "\x1B[2mdisabled\x1B[0m", u = `${a.weight.toString()}%`.padStart(6), f = `v${a.version.toString()}`;
980
+ return ` ${a.name.padEnd(t)} ${a.id.padEnd(r)} ${d} ${u} ${f}`;
96
981
  });
97
- console.log(["", " Features:", "", t, r, ...c, ""].join(`
982
+ console.log(["", " Features:", "", n, o, ...i, ""].join(`
98
983
  `));
99
984
  }
100
- function O(n) {
985
+ function z(e) {
101
986
  try {
102
- const e = new URL(n).hostname;
103
- return e === "localhost" || e === "127.0.0.1" || e === "::1";
987
+ const t = new URL(e).hostname;
988
+ return t === "localhost" || t === "127.0.0.1" || t === "::1";
104
989
  } catch {
105
990
  return !1;
106
991
  }
107
992
  }
108
- function T(n) {
109
- return new Promise((e) => {
110
- setTimeout(e, n);
993
+ function P(e) {
994
+ return new Promise((t) => {
995
+ setTimeout(t, e);
111
996
  });
112
997
  }
113
- async function v(n, e) {
114
- const o = await $(n, e);
115
- if (o || !O(n))
116
- return o;
117
- for (let t = 1; t <= w; t++) {
118
- a.info(
119
- `local API not ready, retrying in ${(E / 1e3).toString()}s (${t.toString()}/${w.toString()})`
120
- ), await T(E);
121
- const r = await $(n, e);
122
- if (r)
123
- return r;
998
+ async function N(e, t, r) {
999
+ const n = await g(e, t, { headers: r });
1000
+ if (n || !z(e))
1001
+ return n;
1002
+ for (let o = 1; o <= T; o++) {
1003
+ l.info(
1004
+ `local API not ready, retrying in ${(k / 1e3).toString()}s (${o.toString()}/${T.toString()})`
1005
+ ), await P(k);
1006
+ const i = await g(e, t, { headers: r });
1007
+ if (i)
1008
+ return i;
124
1009
  }
125
1010
  return null;
126
1011
  }
127
- const p = "https://api.picked.app", C = "__PICKED_PROJECT_CONFIG__", w = 5, E = 2e3;
128
- function P(n) {
129
- const e = n.apiUrl ?? p;
1012
+ function G() {
1013
+ return "0.0.49-next.1";
1014
+ }
1015
+ const A = "https://api.picked.app", K = "__PICKED_PROJECT_CONFIG__", T = 5, k = 2e3;
1016
+ function q(e) {
1017
+ const t = e.apiUrl ?? A;
1018
+ let r = [];
130
1019
  return {
131
1020
  name: "picked",
132
1021
  config: async () => {
133
- a.banner(), a.info(`fetching project config for "${n.projectId}"`), e !== p && a.warn(`using custom API URL: ${e}`);
134
- const o = performance.now(), t = await v(e, n.projectId), r = (performance.now() - o).toFixed(0);
135
- if (!t) {
136
- a.warn(`failed to fetch project config for "${n.projectId}" (${r}ms)`);
1022
+ l.banner(), l.info(`fetching project config for "${e.projectId}"`), t !== A && l.warn(`using custom API URL: ${t}`);
1023
+ const n = R("vite-plugin", G()), o = performance.now(), i = await N(t, e.projectId, n), a = (performance.now() - o).toFixed(0);
1024
+ if (!i) {
1025
+ l.warn(`failed to fetch project config for "${e.projectId}" (${a}ms)`);
137
1026
  return;
138
1027
  }
139
- const c = t.features.length, i = t.features.filter((_) => _.enabled).length, f = JSON.stringify(t).length;
140
- return a.info(
141
- `fetched ${c.toString()} features (${i.toString()} enabled) for "${n.projectId}" in ${r}ms`
142
- ), B(t.features), a.debug(`config size: ${f.toString()} bytes`), {
1028
+ r = i.features;
1029
+ const d = i.features.length, u = i.features.filter((U) => U.enabled).length, f = JSON.stringify(i).length;
1030
+ return l.info(
1031
+ `fetched ${d.toString()} features (${u.toString()} enabled) for "${e.projectId}" in ${a}ms`
1032
+ ), F(i.features), l.debug(`config size: ${f.toString()} bytes`), {
143
1033
  define: {
144
- [C]: JSON.stringify(t)
1034
+ [K]: JSON.stringify(i)
145
1035
  }
146
1036
  };
1037
+ },
1038
+ configureServer(n) {
1039
+ if (e.disableLauncher) return;
1040
+ n.middlewares.use(B(() => b(r)));
1041
+ const o = n.printUrls.bind(n);
1042
+ n.printUrls = () => {
1043
+ const i = n.resolvedUrls?.local[0];
1044
+ if (i) {
1045
+ const a = i.replace(
1046
+ /:(?<port>\d+)\//,
1047
+ (d, u) => `:\x1B[1m${u}\x1B[22m/`
1048
+ );
1049
+ console.log(` \x1B[32m➜\x1B[0m \x1B[1mPicked\x1B[22m: \x1B[36m${a}\x1B[0m`);
1050
+ }
1051
+ o();
1052
+ };
1053
+ },
1054
+ generateBundle() {
1055
+ e.disableLauncher || this.emitFile({
1056
+ type: "asset",
1057
+ fileName: "index.html",
1058
+ source: b(r)
1059
+ });
147
1060
  }
148
1061
  };
149
1062
  }
150
1063
  export {
151
- P as picked
1064
+ q as picked
152
1065
  };