orizu 0.1.2 → 0.1.4
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/index.js +113 -3
- package/package.json +1 -1
- package/src/index.ts +115 -3
package/dist/index.js
CHANGED
|
@@ -360,6 +360,113 @@ function resolveAuthCallbackPort() {
|
|
|
360
360
|
}
|
|
361
361
|
return parsed;
|
|
362
362
|
}
|
|
363
|
+
function renderCliAuthBrowserPage(status) {
|
|
364
|
+
const isSuccess = status === 'success';
|
|
365
|
+
const eyebrow = isSuccess ? '// cli login complete' : '// cli login';
|
|
366
|
+
const title = isSuccess ? 'Browser authorization complete' : 'Missing authorization code';
|
|
367
|
+
const detail = isSuccess
|
|
368
|
+
? 'Your terminal will finish connecting the Orizu CLI. You can close this tab.'
|
|
369
|
+
: 'Close this tab and run orizu login again to start a fresh browser request.';
|
|
370
|
+
const accent = isSuccess ? '#E8923C' : '#C8442A';
|
|
371
|
+
return `<!doctype html>
|
|
372
|
+
<html lang="en">
|
|
373
|
+
<head>
|
|
374
|
+
<meta charset="utf-8">
|
|
375
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
376
|
+
<title>Orizu CLI Login</title>
|
|
377
|
+
<style>
|
|
378
|
+
@import url('https://fonts.googleapis.com/css2?family=Geist+Mono:wght@400;500;700&display=swap');
|
|
379
|
+
:root {
|
|
380
|
+
color-scheme: light;
|
|
381
|
+
--paper: #F4EFE3;
|
|
382
|
+
--border: #E6DFCE;
|
|
383
|
+
--ink: #353535;
|
|
384
|
+
--muted: #6B6358;
|
|
385
|
+
}
|
|
386
|
+
* { box-sizing: border-box; }
|
|
387
|
+
body {
|
|
388
|
+
margin: 0;
|
|
389
|
+
min-height: 100vh;
|
|
390
|
+
background: #FFFFFF;
|
|
391
|
+
color: #4B4B4B;
|
|
392
|
+
font-family: 'Geist Mono', Menlo, Monaco, Consolas, monospace;
|
|
393
|
+
letter-spacing: -0.025em;
|
|
394
|
+
}
|
|
395
|
+
main {
|
|
396
|
+
min-height: 100vh;
|
|
397
|
+
display: flex;
|
|
398
|
+
align-items: center;
|
|
399
|
+
justify-content: center;
|
|
400
|
+
padding: 48px 24px;
|
|
401
|
+
}
|
|
402
|
+
section {
|
|
403
|
+
width: min(100%, 520px);
|
|
404
|
+
text-align: center;
|
|
405
|
+
}
|
|
406
|
+
.brand {
|
|
407
|
+
display: flex;
|
|
408
|
+
flex-direction: column;
|
|
409
|
+
align-items: center;
|
|
410
|
+
gap: 12px;
|
|
411
|
+
margin-bottom: 28px;
|
|
412
|
+
}
|
|
413
|
+
.brand svg {
|
|
414
|
+
width: 42px;
|
|
415
|
+
height: 42px;
|
|
416
|
+
color: #202124;
|
|
417
|
+
}
|
|
418
|
+
.brand span {
|
|
419
|
+
color: #000000;
|
|
420
|
+
font-size: 16px;
|
|
421
|
+
font-weight: 700;
|
|
422
|
+
}
|
|
423
|
+
.eyebrow {
|
|
424
|
+
margin: 0 0 12px;
|
|
425
|
+
color: ${accent};
|
|
426
|
+
font-size: 12px;
|
|
427
|
+
text-transform: lowercase;
|
|
428
|
+
}
|
|
429
|
+
h1 {
|
|
430
|
+
margin: 0 0 8px;
|
|
431
|
+
color: var(--ink);
|
|
432
|
+
font-size: 24px;
|
|
433
|
+
line-height: 1.15;
|
|
434
|
+
letter-spacing: -0.05em;
|
|
435
|
+
}
|
|
436
|
+
.detail {
|
|
437
|
+
margin: 0;
|
|
438
|
+
color: var(--muted);
|
|
439
|
+
font-size: 13px;
|
|
440
|
+
line-height: 1.6;
|
|
441
|
+
}
|
|
442
|
+
</style>
|
|
443
|
+
</head>
|
|
444
|
+
<body>
|
|
445
|
+
<main>
|
|
446
|
+
<section>
|
|
447
|
+
<div class="brand" aria-hidden="true">
|
|
448
|
+
<svg viewBox="0 0 2048 2048" xmlns="http://www.w3.org/2000/svg">
|
|
449
|
+
<g fill="currentColor">
|
|
450
|
+
<polygon points="1545,879 787,1195 1189,1577"></polygon>
|
|
451
|
+
<polygon points="992,624 444,1104 688,1338"></polygon>
|
|
452
|
+
<polygon points="602,1593 1180,1594 768,1202"></polygon>
|
|
453
|
+
<polygon points="1650,1195 1398,1203 1204,1594 1229,1593"></polygon>
|
|
454
|
+
<polygon points="807,413 751,509 823,744 980,608"></polygon>
|
|
455
|
+
<polygon points="441,1127 592,1572 681,1356"></polygon>
|
|
456
|
+
<polygon points="793,399 611,457 604,471 658,602"></polygon>
|
|
457
|
+
<polygon points="593,493 498,667 636,600"></polygon>
|
|
458
|
+
</g>
|
|
459
|
+
</svg>
|
|
460
|
+
<span>orizu</span>
|
|
461
|
+
</div>
|
|
462
|
+
<p class="eyebrow">${eyebrow}</p>
|
|
463
|
+
<h1>${title}</h1>
|
|
464
|
+
<p class="detail">${detail}</p>
|
|
465
|
+
</section>
|
|
466
|
+
</main>
|
|
467
|
+
</body>
|
|
468
|
+
</html>`;
|
|
469
|
+
}
|
|
363
470
|
async function login() {
|
|
364
471
|
const baseUrl = resolveLoginBaseUrl();
|
|
365
472
|
const codeVerifier = createCodeVerifier();
|
|
@@ -372,12 +479,13 @@ async function login() {
|
|
|
372
479
|
const code = url.searchParams.get('code');
|
|
373
480
|
if (!code) {
|
|
374
481
|
response.statusCode = 400;
|
|
375
|
-
response.
|
|
482
|
+
response.setHeader('content-type', 'text/html; charset=utf-8');
|
|
483
|
+
response.end(renderCliAuthBrowserPage('error'));
|
|
376
484
|
return;
|
|
377
485
|
}
|
|
378
486
|
response.statusCode = 200;
|
|
379
|
-
response.setHeader('content-type', 'text/html');
|
|
380
|
-
response.end('
|
|
487
|
+
response.setHeader('content-type', 'text/html; charset=utf-8');
|
|
488
|
+
response.end(renderCliAuthBrowserPage('success'));
|
|
381
489
|
server.close();
|
|
382
490
|
resolve(code);
|
|
383
491
|
}
|
|
@@ -453,8 +561,10 @@ async function logout() {
|
|
|
453
561
|
await fetch(`${baseUrl}/api/cli/auth/logout`, {
|
|
454
562
|
method: 'POST',
|
|
455
563
|
headers: {
|
|
564
|
+
'Content-Type': 'application/json',
|
|
456
565
|
Authorization: `Bearer ${credentials.accessToken}`,
|
|
457
566
|
},
|
|
567
|
+
body: JSON.stringify({ refreshToken: credentials.refreshToken }),
|
|
458
568
|
}).catch(() => undefined);
|
|
459
569
|
clearServerCredentials(baseUrl);
|
|
460
570
|
console.log(`Logged out from ${baseUrl}.`);
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -637,6 +637,115 @@ function resolveAuthCallbackPort(): number {
|
|
|
637
637
|
return parsed
|
|
638
638
|
}
|
|
639
639
|
|
|
640
|
+
function renderCliAuthBrowserPage(status: 'success' | 'error'): string {
|
|
641
|
+
const isSuccess = status === 'success'
|
|
642
|
+
const eyebrow = isSuccess ? '// cli login complete' : '// cli login'
|
|
643
|
+
const title = isSuccess ? 'Browser authorization complete' : 'Missing authorization code'
|
|
644
|
+
const detail = isSuccess
|
|
645
|
+
? 'Your terminal will finish connecting the Orizu CLI. You can close this tab.'
|
|
646
|
+
: 'Close this tab and run orizu login again to start a fresh browser request.'
|
|
647
|
+
const accent = isSuccess ? '#E8923C' : '#C8442A'
|
|
648
|
+
|
|
649
|
+
return `<!doctype html>
|
|
650
|
+
<html lang="en">
|
|
651
|
+
<head>
|
|
652
|
+
<meta charset="utf-8">
|
|
653
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
654
|
+
<title>Orizu CLI Login</title>
|
|
655
|
+
<style>
|
|
656
|
+
@import url('https://fonts.googleapis.com/css2?family=Geist+Mono:wght@400;500;700&display=swap');
|
|
657
|
+
:root {
|
|
658
|
+
color-scheme: light;
|
|
659
|
+
--paper: #F4EFE3;
|
|
660
|
+
--border: #E6DFCE;
|
|
661
|
+
--ink: #353535;
|
|
662
|
+
--muted: #6B6358;
|
|
663
|
+
}
|
|
664
|
+
* { box-sizing: border-box; }
|
|
665
|
+
body {
|
|
666
|
+
margin: 0;
|
|
667
|
+
min-height: 100vh;
|
|
668
|
+
background: #FFFFFF;
|
|
669
|
+
color: #4B4B4B;
|
|
670
|
+
font-family: 'Geist Mono', Menlo, Monaco, Consolas, monospace;
|
|
671
|
+
letter-spacing: -0.025em;
|
|
672
|
+
}
|
|
673
|
+
main {
|
|
674
|
+
min-height: 100vh;
|
|
675
|
+
display: flex;
|
|
676
|
+
align-items: center;
|
|
677
|
+
justify-content: center;
|
|
678
|
+
padding: 48px 24px;
|
|
679
|
+
}
|
|
680
|
+
section {
|
|
681
|
+
width: min(100%, 520px);
|
|
682
|
+
text-align: center;
|
|
683
|
+
}
|
|
684
|
+
.brand {
|
|
685
|
+
display: flex;
|
|
686
|
+
flex-direction: column;
|
|
687
|
+
align-items: center;
|
|
688
|
+
gap: 12px;
|
|
689
|
+
margin-bottom: 28px;
|
|
690
|
+
}
|
|
691
|
+
.brand svg {
|
|
692
|
+
width: 42px;
|
|
693
|
+
height: 42px;
|
|
694
|
+
color: #202124;
|
|
695
|
+
}
|
|
696
|
+
.brand span {
|
|
697
|
+
color: #000000;
|
|
698
|
+
font-size: 16px;
|
|
699
|
+
font-weight: 700;
|
|
700
|
+
}
|
|
701
|
+
.eyebrow {
|
|
702
|
+
margin: 0 0 12px;
|
|
703
|
+
color: ${accent};
|
|
704
|
+
font-size: 12px;
|
|
705
|
+
text-transform: lowercase;
|
|
706
|
+
}
|
|
707
|
+
h1 {
|
|
708
|
+
margin: 0 0 8px;
|
|
709
|
+
color: var(--ink);
|
|
710
|
+
font-size: 24px;
|
|
711
|
+
line-height: 1.15;
|
|
712
|
+
letter-spacing: -0.05em;
|
|
713
|
+
}
|
|
714
|
+
.detail {
|
|
715
|
+
margin: 0;
|
|
716
|
+
color: var(--muted);
|
|
717
|
+
font-size: 13px;
|
|
718
|
+
line-height: 1.6;
|
|
719
|
+
}
|
|
720
|
+
</style>
|
|
721
|
+
</head>
|
|
722
|
+
<body>
|
|
723
|
+
<main>
|
|
724
|
+
<section>
|
|
725
|
+
<div class="brand" aria-hidden="true">
|
|
726
|
+
<svg viewBox="0 0 2048 2048" xmlns="http://www.w3.org/2000/svg">
|
|
727
|
+
<g fill="currentColor">
|
|
728
|
+
<polygon points="1545,879 787,1195 1189,1577"></polygon>
|
|
729
|
+
<polygon points="992,624 444,1104 688,1338"></polygon>
|
|
730
|
+
<polygon points="602,1593 1180,1594 768,1202"></polygon>
|
|
731
|
+
<polygon points="1650,1195 1398,1203 1204,1594 1229,1593"></polygon>
|
|
732
|
+
<polygon points="807,413 751,509 823,744 980,608"></polygon>
|
|
733
|
+
<polygon points="441,1127 592,1572 681,1356"></polygon>
|
|
734
|
+
<polygon points="793,399 611,457 604,471 658,602"></polygon>
|
|
735
|
+
<polygon points="593,493 498,667 636,600"></polygon>
|
|
736
|
+
</g>
|
|
737
|
+
</svg>
|
|
738
|
+
<span>orizu</span>
|
|
739
|
+
</div>
|
|
740
|
+
<p class="eyebrow">${eyebrow}</p>
|
|
741
|
+
<h1>${title}</h1>
|
|
742
|
+
<p class="detail">${detail}</p>
|
|
743
|
+
</section>
|
|
744
|
+
</main>
|
|
745
|
+
</body>
|
|
746
|
+
</html>`
|
|
747
|
+
}
|
|
748
|
+
|
|
640
749
|
async function login() {
|
|
641
750
|
const baseUrl = resolveLoginBaseUrl()
|
|
642
751
|
const codeVerifier = createCodeVerifier()
|
|
@@ -651,13 +760,14 @@ async function login() {
|
|
|
651
760
|
|
|
652
761
|
if (!code) {
|
|
653
762
|
response.statusCode = 400
|
|
654
|
-
response.
|
|
763
|
+
response.setHeader('content-type', 'text/html; charset=utf-8')
|
|
764
|
+
response.end(renderCliAuthBrowserPage('error'))
|
|
655
765
|
return
|
|
656
766
|
}
|
|
657
767
|
|
|
658
768
|
response.statusCode = 200
|
|
659
|
-
response.setHeader('content-type', 'text/html')
|
|
660
|
-
response.end('
|
|
769
|
+
response.setHeader('content-type', 'text/html; charset=utf-8')
|
|
770
|
+
response.end(renderCliAuthBrowserPage('success'))
|
|
661
771
|
|
|
662
772
|
server.close()
|
|
663
773
|
resolve(code)
|
|
@@ -748,8 +858,10 @@ async function logout() {
|
|
|
748
858
|
await fetch(`${baseUrl}/api/cli/auth/logout`, {
|
|
749
859
|
method: 'POST',
|
|
750
860
|
headers: {
|
|
861
|
+
'Content-Type': 'application/json',
|
|
751
862
|
Authorization: `Bearer ${credentials.accessToken}`,
|
|
752
863
|
},
|
|
864
|
+
body: JSON.stringify({ refreshToken: credentials.refreshToken }),
|
|
753
865
|
}).catch(() => undefined)
|
|
754
866
|
|
|
755
867
|
clearServerCredentials(baseUrl)
|