neonctl 1.23.3 → 1.24.2

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/callback.html CHANGED
@@ -1,45 +1,139 @@
1
- <!DOCTYPE html>
1
+ <!doctype html>
2
2
  <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
5
  <title>Neon</title>
6
- <style>
7
- body, html {
8
- width: 100%;
9
- height: 100%;
10
- margin: 0;
11
- text-align: center;
12
- font-family: 'Open Sans', sans-serif;
13
- display: flex;
14
- flex-direction: column;
15
- justify-content: center;
16
- align-items: center;
17
- background-color: #ffffff;
18
- color: #2d374c;
19
- }
20
- @media (prefers-color-scheme: dark) {
21
- body, html {
22
- background-color: #191919;
23
- color: #bfbfbf;
24
- }
25
- }
26
- .logo {
27
- display: inline-block;
28
- width: 100px;
29
- height: 100px;
30
- margin: 0 auto;
31
- }
32
- svg {
33
- overflow: visible;
34
- }
35
- </style>
36
- </head>
37
- <body>
6
+ <style>
7
+ body,
8
+ html {
9
+ width: 100%;
10
+ height: 100%;
11
+ margin: 0;
12
+ text-align: center;
13
+ font-family: 'Open Sans', sans-serif;
14
+ display: flex;
15
+ flex-direction: column;
16
+ justify-content: center;
17
+ align-items: center;
18
+ background-color: #ffffff;
19
+ color: #2d374c;
20
+ }
21
+ @media (prefers-color-scheme: dark) {
22
+ body,
23
+ html {
24
+ background-color: #191919;
25
+ color: #bfbfbf;
26
+ }
27
+ }
28
+ .logo {
29
+ display: inline-block;
30
+ width: 100px;
31
+ height: 100px;
32
+ margin: 0 auto;
33
+ }
34
+ svg {
35
+ overflow: visible;
36
+ }
37
+ </style>
38
+ </head>
39
+ <body>
38
40
  <div class="logo">
39
- <svg id="eBsErktH1941" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 42 42" shape-rendering="geometricPrecision" text-rendering="geometricPrecision"><style><![CDATA[#eBsErktH1945 {animation: eBsErktH1945__fl 3000ms linear infinite normal forwards}@keyframes eBsErktH1945__fl { 0% {filter: drop-shadow(0px 0px 0px #5cff61)} 13.666667% {filter: drop-shadow(0px 0px 0px #5cff61)} 15% {filter: drop-shadow(0px 0px 4.242641px #5cff61)} 34% {filter: drop-shadow(0px 0px 4.242641px #5cff61)} 34.333333% {filter: drop-shadow(0px 0px 0px #5cff61)} 37.333333% {filter: drop-shadow(0px 0px 0px #5cff61)} 37.666667% {filter: drop-shadow(0px 0px 4.242641px #5cff61)} 43.666667% {filter: drop-shadow(0px 0px 4.242641px #5cff61)} 44% {filter: drop-shadow(0px 0px 0px #5cff61)} 47% {filter: drop-shadow(0px 0px 0px #5cff61)} 47.333333% {filter: drop-shadow(0px 0px 4.242641px #5cff61)} 51% {filter: drop-shadow(0px 0px 4.242641px #5cff61)} 51.333333% {filter: drop-shadow(0px 0px 0px #5cff61)} 53.666667% {filter: drop-shadow(0px 0px 0px #5cff61)} 54% {filter: drop-shadow(0px 0px 4.242641px #5cff61)} 100% {filter: drop-shadow(0px 0px 4.242641px #5cff61)}} #eBsErktH1946 {animation: eBsErktH1946__fl 3000ms linear infinite normal forwards}@keyframes eBsErktH1946__fl { 0% {filter: drop-shadow(0px 0px 0px #5cff61)} 13.666667% {filter: drop-shadow(0px 0px 0px #5cff61)} 15% {filter: drop-shadow(0px 0px 2.828427px #5cff61)} 34% {filter: drop-shadow(0px 0px 2.828427px #5cff61)} 34.333333% {filter: drop-shadow(0px 0px 0px #5cff61)} 37.333333% {filter: drop-shadow(0px 0px 0px #5cff61)} 37.666667% {filter: drop-shadow(0px 0px 2.828427px #5cff61)} 43.666667% {filter: drop-shadow(0px 0px 2.828427px #5cff61)} 44% {filter: drop-shadow(0px 0px 0px #5cff61)} 47% {filter: drop-shadow(0px 0px 0px #5cff61)} 47.333333% {filter: drop-shadow(0px 0px 2.828427px #5cff61)} 51% {filter: drop-shadow(0px 0px 2.828427px #5cff61)} 51.333333% {filter: drop-shadow(0px 0px 0px #5cff61)} 53.666667% {filter: drop-shadow(0px 0px 0px #5cff61)} 54% {filter: drop-shadow(0px 0px 2.828427px #5cff61)} 100% {filter: drop-shadow(0px 0px 2.828427px #5cff61)}} #eBsErktH1947 {animation: eBsErktH1947__fl 3000ms linear infinite normal forwards}@keyframes eBsErktH1947__fl { 0% {filter: drop-shadow(0px 0px 0px #5cff61)} 13.666667% {filter: drop-shadow(0px 0px 0px #5cff61)} 15% {filter: drop-shadow(0px 0px 1.414214px #5cff61)} 34% {filter: drop-shadow(0px 0px 1.414214px #5cff61)} 34.333333% {filter: drop-shadow(0px 0px 0px #5cff61)} 37.333333% {filter: drop-shadow(0px 0px 0px #5cff61)} 37.666667% {filter: drop-shadow(0px 0px 1.414214px #5cff61)} 43.666667% {filter: drop-shadow(0px 0px 1px #5cff61)} 44% {filter: drop-shadow(0px 0px 0px #5cff61)} 47% {filter: drop-shadow(0px 0px 0px #5cff61)} 47.333333% {filter: drop-shadow(0px 0px 1.414214px #5cff61)} 51% {filter: drop-shadow(0px 0px 1.414214px #5cff61)} 51.333333% {filter: drop-shadow(0px 0px 0px #5cff61)} 53.666667% {filter: drop-shadow(0px 0px 0px #5cff61)} 54% {filter: drop-shadow(0px 0px 1.414214px #5cff61)} 100% {filter: drop-shadow(0px 0px 1.414214px #5cff61)}}]]></style><defs><linearGradient id="eBsErktH1943-fill" x1="36" y1="36" x2="4.345" y2="0" spreadMethod="pad" gradientUnits="userSpaceOnUse" gradientTransform="translate(0 0)"><stop id="eBsErktH1943-fill-0" offset="0%" stop-color="#b9ffb3"/><stop id="eBsErktH1943-fill-1" offset="100%" stop-color="rgba(185,255,179,0)"/></linearGradient><linearGradient id="eBsErktH1944-fill" x1="36" y1="36" x2="14.617" y2="27.683" spreadMethod="pad" gradientUnits="userSpaceOnUse" gradientTransform="translate(0 0)"><stop id="eBsErktH1944-fill-0" offset="0%" stop-color="rgba(26,26,26,0.9)"/><stop id="eBsErktH1944-fill-1" offset="100%" stop-color="rgba(26,26,26,0)"/></linearGradient></defs><path d="M0,6.207c0-1.646199.65395-3.224973,1.817988-4.389012C2.982026,0.65395,4.560801,0,6.207,0h23.586c1.646199,0,3.224973.65395,4.389012,1.817988s1.817988,2.742813,1.817988,4.389012v20.06c0,3.546-4.488,5.085-6.664,2.286l-6.805-8.754v10.615c0,3.085063-2.500937,5.586-5.586,5.586h-10.738c-1.646199,0-3.224973-.65395-4.389012-1.817988s-1.817988-2.742813-1.817988-4.389012L0,6.207ZM6.207,4.966c-.686,0-1.241.555-1.241,1.24v23.587c0,.686.555,1.242,1.24,1.242h10.925c.343,0,.434-.278.434-.621v-14.234c0-3.547,4.488-5.086,6.665-2.286l6.805,8.753v-16.44c0-.686.064-1.241-.621-1.241h-24.207Z" transform="translate(3 3)" clip-rule="evenodd" fill="#12fff7" fill-rule="evenodd"/><path d="M0,6.207c0-1.646199.65395-3.224973,1.817988-4.389012C2.982026,0.65395,4.560801,0,6.207,0h23.586c1.646199,0,3.224973.65395,4.389012,1.817988s1.817988,2.742813,1.817988,4.389012v20.06c0,3.546-4.488,5.085-6.664,2.286l-6.805-8.754v10.615c0,3.085063-2.500937,5.586-5.586,5.586h-10.738c-1.646199,0-3.224973-.65395-4.389012-1.817988s-1.817988-2.742813-1.817988-4.389012L0,6.207ZM6.207,4.966c-.686,0-1.241.555-1.241,1.24v23.587c0,.686.555,1.242,1.24,1.242h10.925c.343,0,.434-.278.434-.621v-14.234c0-3.547,4.488-5.086,6.665-2.286l6.805,8.753v-16.44c0-.686.064-1.241-.621-1.241h-24.207Z" transform="translate(3 3)" clip-rule="evenodd" fill="url(#eBsErktH1943-fill)" fill-rule="evenodd"/><path d="M0,6.207c0-1.646199.65395-3.224973,1.817988-4.389012C2.982026,0.65395,4.560801,0,6.207,0h23.586c1.646199,0,3.224973.65395,4.389012,1.817988s1.817988,2.742813,1.817988,4.389012v20.06c0,3.546-4.488,5.085-6.664,2.286l-6.805-8.754v10.615c0,3.085063-2.500937,5.586-5.586,5.586h-10.738c-1.646199,0-3.224973-.65395-4.389012-1.817988s-1.817988-2.742813-1.817988-4.389012L0,6.207ZM6.207,4.966c-.686,0-1.241.555-1.241,1.24v23.587c0,.686.555,1.242,1.24,1.242h10.925c.343,0,.434-.278.434-.621v-14.234c0-3.547,4.488-5.086,6.665-2.286l6.805,8.753v-16.44c0-.686.064-1.241-.621-1.241h-24.207Z" transform="translate(3 3)" clip-rule="evenodd" fill="url(#eBsErktH1944-fill)" fill-rule="evenodd"/><path id="eBsErktH1945" style="filter:drop-shadow(0px 0px 0px #5cff61)" d="M29.793,0c1.646199,0,3.224973.65395,4.389012,1.817988s1.817988,2.742813,1.817988,4.389012v20.06c0,3.546-4.488,5.085-6.664,2.286l-6.805-8.754v10.615c0,3.085063-2.500937,5.586-5.586,5.586.342417,0,.62-.277583.62-.62v-19.2c0-3.547,4.488-5.086,6.665-2.286l6.805,8.753v-21.406c0-.685-.556-1.241-1.242-1.241Z" transform="translate(3 3)" fill="#b9ffb3"/><path id="eBsErktH1946" style="filter:drop-shadow(0px 0px 0px #5cff61)" d="M29.793,0c1.646199,0,3.224973.65395,4.389012,1.817988s1.817988,2.742813,1.817988,4.389012v20.06c0,3.546-4.488,5.085-6.664,2.286l-6.805-8.754v10.615c0,3.085063-2.500937,5.586-5.586,5.586.342417,0,.62-.277583.62-.62v-19.2c0-3.547,4.488-5.086,6.665-2.286l6.805,8.753v-21.406c0-.685-.556-1.241-1.242-1.241Z" transform="translate(3 3)" fill="#b9ffb3"/><path id="eBsErktH1947" style="filter:drop-shadow(0px 0px 0px #5cff61)" d="M29.793,0c1.646199,0,3.224973.65395,4.389012,1.817988s1.817988,2.742813,1.817988,4.389012v20.06c0,3.546-4.488,5.085-6.664,2.286l-6.805-8.754v10.615c0,3.085063-2.500937,5.586-5.586,5.586.342417,0,.62-.277583.62-.62v-19.2c0-3.547,4.488-5.086,6.665-2.286l6.805,8.753v-21.406c0-.685-.556-1.241-1.242-1.241Z" transform="translate(3 3)" fill="#b9ffb3"/></svg>
41
+ <svg
42
+ id="eBsErktH1941"
43
+ xmlns="http://www.w3.org/2000/svg"
44
+ xmlns:xlink="http://www.w3.org/1999/xlink"
45
+ viewBox="0 0 42 42"
46
+ shape-rendering="geometricPrecision"
47
+ text-rendering="geometricPrecision"
48
+ >
49
+ <style>
50
+ <![CDATA[#eBsErktH1945 {animation: eBsErktH1945__fl 3000ms linear infinite normal forwards}@keyframes eBsErktH1945__fl { 0% {filter: drop-shadow(0px 0px 0px #5cff61)} 13.666667% {filter: drop-shadow(0px 0px 0px #5cff61)} 15% {filter: drop-shadow(0px 0px 4.242641px #5cff61)} 34% {filter: drop-shadow(0px 0px 4.242641px #5cff61)} 34.333333% {filter: drop-shadow(0px 0px 0px #5cff61)} 37.333333% {filter: drop-shadow(0px 0px 0px #5cff61)} 37.666667% {filter: drop-shadow(0px 0px 4.242641px #5cff61)} 43.666667% {filter: drop-shadow(0px 0px 4.242641px #5cff61)} 44% {filter: drop-shadow(0px 0px 0px #5cff61)} 47% {filter: drop-shadow(0px 0px 0px #5cff61)} 47.333333% {filter: drop-shadow(0px 0px 4.242641px #5cff61)} 51% {filter: drop-shadow(0px 0px 4.242641px #5cff61)} 51.333333% {filter: drop-shadow(0px 0px 0px #5cff61)} 53.666667% {filter: drop-shadow(0px 0px 0px #5cff61)} 54% {filter: drop-shadow(0px 0px 4.242641px #5cff61)} 100% {filter: drop-shadow(0px 0px 4.242641px #5cff61)}} #eBsErktH1946 {animation: eBsErktH1946__fl 3000ms linear infinite normal forwards}@keyframes eBsErktH1946__fl { 0% {filter: drop-shadow(0px 0px 0px #5cff61)} 13.666667% {filter: drop-shadow(0px 0px 0px #5cff61)} 15% {filter: drop-shadow(0px 0px 2.828427px #5cff61)} 34% {filter: drop-shadow(0px 0px 2.828427px #5cff61)} 34.333333% {filter: drop-shadow(0px 0px 0px #5cff61)} 37.333333% {filter: drop-shadow(0px 0px 0px #5cff61)} 37.666667% {filter: drop-shadow(0px 0px 2.828427px #5cff61)} 43.666667% {filter: drop-shadow(0px 0px 2.828427px #5cff61)} 44% {filter: drop-shadow(0px 0px 0px #5cff61)} 47% {filter: drop-shadow(0px 0px 0px #5cff61)} 47.333333% {filter: drop-shadow(0px 0px 2.828427px #5cff61)} 51% {filter: drop-shadow(0px 0px 2.828427px #5cff61)} 51.333333% {filter: drop-shadow(0px 0px 0px #5cff61)} 53.666667% {filter: drop-shadow(0px 0px 0px #5cff61)} 54% {filter: drop-shadow(0px 0px 2.828427px #5cff61)} 100% {filter: drop-shadow(0px 0px 2.828427px #5cff61)}} #eBsErktH1947 {animation: eBsErktH1947__fl 3000ms linear infinite normal forwards}@keyframes eBsErktH1947__fl { 0% {filter: drop-shadow(0px 0px 0px #5cff61)} 13.666667% {filter: drop-shadow(0px 0px 0px #5cff61)} 15% {filter: drop-shadow(0px 0px 1.414214px #5cff61)} 34% {filter: drop-shadow(0px 0px 1.414214px #5cff61)} 34.333333% {filter: drop-shadow(0px 0px 0px #5cff61)} 37.333333% {filter: drop-shadow(0px 0px 0px #5cff61)} 37.666667% {filter: drop-shadow(0px 0px 1.414214px #5cff61)} 43.666667% {filter: drop-shadow(0px 0px 1px #5cff61)} 44% {filter: drop-shadow(0px 0px 0px #5cff61)} 47% {filter: drop-shadow(0px 0px 0px #5cff61)} 47.333333% {filter: drop-shadow(0px 0px 1.414214px #5cff61)} 51% {filter: drop-shadow(0px 0px 1.414214px #5cff61)} 51.333333% {filter: drop-shadow(0px 0px 0px #5cff61)} 53.666667% {filter: drop-shadow(0px 0px 0px #5cff61)} 54% {filter: drop-shadow(0px 0px 1.414214px #5cff61)} 100% {filter: drop-shadow(0px 0px 1.414214px #5cff61)}}]]>
51
+ </style>
52
+ <defs>
53
+ <linearGradient
54
+ id="eBsErktH1943-fill"
55
+ x1="36"
56
+ y1="36"
57
+ x2="4.345"
58
+ y2="0"
59
+ spreadMethod="pad"
60
+ gradientUnits="userSpaceOnUse"
61
+ gradientTransform="translate(0 0)"
62
+ >
63
+ <stop id="eBsErktH1943-fill-0" offset="0%" stop-color="#b9ffb3" />
64
+ <stop
65
+ id="eBsErktH1943-fill-1"
66
+ offset="100%"
67
+ stop-color="rgba(185,255,179,0)"
68
+ />
69
+ </linearGradient>
70
+ <linearGradient
71
+ id="eBsErktH1944-fill"
72
+ x1="36"
73
+ y1="36"
74
+ x2="14.617"
75
+ y2="27.683"
76
+ spreadMethod="pad"
77
+ gradientUnits="userSpaceOnUse"
78
+ gradientTransform="translate(0 0)"
79
+ >
80
+ <stop
81
+ id="eBsErktH1944-fill-0"
82
+ offset="0%"
83
+ stop-color="rgba(26,26,26,0.9)"
84
+ />
85
+ <stop
86
+ id="eBsErktH1944-fill-1"
87
+ offset="100%"
88
+ stop-color="rgba(26,26,26,0)"
89
+ />
90
+ </linearGradient>
91
+ </defs>
92
+ <path
93
+ d="M0,6.207c0-1.646199.65395-3.224973,1.817988-4.389012C2.982026,0.65395,4.560801,0,6.207,0h23.586c1.646199,0,3.224973.65395,4.389012,1.817988s1.817988,2.742813,1.817988,4.389012v20.06c0,3.546-4.488,5.085-6.664,2.286l-6.805-8.754v10.615c0,3.085063-2.500937,5.586-5.586,5.586h-10.738c-1.646199,0-3.224973-.65395-4.389012-1.817988s-1.817988-2.742813-1.817988-4.389012L0,6.207ZM6.207,4.966c-.686,0-1.241.555-1.241,1.24v23.587c0,.686.555,1.242,1.24,1.242h10.925c.343,0,.434-.278.434-.621v-14.234c0-3.547,4.488-5.086,6.665-2.286l6.805,8.753v-16.44c0-.686.064-1.241-.621-1.241h-24.207Z"
94
+ transform="translate(3 3)"
95
+ clip-rule="evenodd"
96
+ fill="#12fff7"
97
+ fill-rule="evenodd"
98
+ />
99
+ <path
100
+ d="M0,6.207c0-1.646199.65395-3.224973,1.817988-4.389012C2.982026,0.65395,4.560801,0,6.207,0h23.586c1.646199,0,3.224973.65395,4.389012,1.817988s1.817988,2.742813,1.817988,4.389012v20.06c0,3.546-4.488,5.085-6.664,2.286l-6.805-8.754v10.615c0,3.085063-2.500937,5.586-5.586,5.586h-10.738c-1.646199,0-3.224973-.65395-4.389012-1.817988s-1.817988-2.742813-1.817988-4.389012L0,6.207ZM6.207,4.966c-.686,0-1.241.555-1.241,1.24v23.587c0,.686.555,1.242,1.24,1.242h10.925c.343,0,.434-.278.434-.621v-14.234c0-3.547,4.488-5.086,6.665-2.286l6.805,8.753v-16.44c0-.686.064-1.241-.621-1.241h-24.207Z"
101
+ transform="translate(3 3)"
102
+ clip-rule="evenodd"
103
+ fill="url(#eBsErktH1943-fill)"
104
+ fill-rule="evenodd"
105
+ />
106
+ <path
107
+ d="M0,6.207c0-1.646199.65395-3.224973,1.817988-4.389012C2.982026,0.65395,4.560801,0,6.207,0h23.586c1.646199,0,3.224973.65395,4.389012,1.817988s1.817988,2.742813,1.817988,4.389012v20.06c0,3.546-4.488,5.085-6.664,2.286l-6.805-8.754v10.615c0,3.085063-2.500937,5.586-5.586,5.586h-10.738c-1.646199,0-3.224973-.65395-4.389012-1.817988s-1.817988-2.742813-1.817988-4.389012L0,6.207ZM6.207,4.966c-.686,0-1.241.555-1.241,1.24v23.587c0,.686.555,1.242,1.24,1.242h10.925c.343,0,.434-.278.434-.621v-14.234c0-3.547,4.488-5.086,6.665-2.286l6.805,8.753v-16.44c0-.686.064-1.241-.621-1.241h-24.207Z"
108
+ transform="translate(3 3)"
109
+ clip-rule="evenodd"
110
+ fill="url(#eBsErktH1944-fill)"
111
+ fill-rule="evenodd"
112
+ />
113
+ <path
114
+ id="eBsErktH1945"
115
+ style="filter: drop-shadow(0px 0px 0px #5cff61)"
116
+ d="M29.793,0c1.646199,0,3.224973.65395,4.389012,1.817988s1.817988,2.742813,1.817988,4.389012v20.06c0,3.546-4.488,5.085-6.664,2.286l-6.805-8.754v10.615c0,3.085063-2.500937,5.586-5.586,5.586.342417,0,.62-.277583.62-.62v-19.2c0-3.547,4.488-5.086,6.665-2.286l6.805,8.753v-21.406c0-.685-.556-1.241-1.242-1.241Z"
117
+ transform="translate(3 3)"
118
+ fill="#b9ffb3"
119
+ />
120
+ <path
121
+ id="eBsErktH1946"
122
+ style="filter: drop-shadow(0px 0px 0px #5cff61)"
123
+ d="M29.793,0c1.646199,0,3.224973.65395,4.389012,1.817988s1.817988,2.742813,1.817988,4.389012v20.06c0,3.546-4.488,5.085-6.664,2.286l-6.805-8.754v10.615c0,3.085063-2.500937,5.586-5.586,5.586.342417,0,.62-.277583.62-.62v-19.2c0-3.547,4.488-5.086,6.665-2.286l6.805,8.753v-21.406c0-.685-.556-1.241-1.242-1.241Z"
124
+ transform="translate(3 3)"
125
+ fill="#b9ffb3"
126
+ />
127
+ <path
128
+ id="eBsErktH1947"
129
+ style="filter: drop-shadow(0px 0px 0px #5cff61)"
130
+ d="M29.793,0c1.646199,0,3.224973.65395,4.389012,1.817988s1.817988,2.742813,1.817988,4.389012v20.06c0,3.546-4.488,5.085-6.664,2.286l-6.805-8.754v10.615c0,3.085063-2.500937,5.586-5.586,5.586.342417,0,.62-.277583.62-.62v-19.2c0-3.547,4.488-5.086,6.665-2.286l6.805,8.753v-21.406c0-.685-.556-1.241-1.242-1.241Z"
131
+ transform="translate(3 3)"
132
+ fill="#b9ffb3"
133
+ />
134
+ </svg>
40
135
  </div>
41
136
  <h1>Thank you for using Neon</h1>
42
- <p>
43
- You may close this page now
44
- </p>
45
- </body>
137
+ <p>You may close this page now</p>
138
+ </body>
139
+ </html>
@@ -12,6 +12,13 @@ const BRANCH_FIELDS = [
12
12
  'created_at',
13
13
  'updated_at',
14
14
  ];
15
+ const BRANCH_FIELDS_RESET = [
16
+ 'id',
17
+ 'name',
18
+ 'primary',
19
+ 'created_at',
20
+ 'last_reset_at',
21
+ ];
15
22
  export const command = 'branches';
16
23
  export const describe = 'Manage branches';
17
24
  export const aliases = ['branch'];
@@ -56,6 +63,16 @@ export const builder = (argv) => argv
56
63
  default: false,
57
64
  },
58
65
  }), async (args) => await create(args))
66
+ .command('reset <id|name>', 'Reset a branch', (yargs) => yargs.options({
67
+ parent: {
68
+ describe: 'Reset to a parent branch',
69
+ type: 'boolean',
70
+ default: false,
71
+ },
72
+ 'preserve-under-name': {
73
+ describe: 'Name under which to preserve the old branch',
74
+ },
75
+ }), async (args) => await reset(args))
59
76
  .command('rename <id|name> <new-name>', 'Rename a branch', (yargs) => yargs, async (args) => await rename(args))
60
77
  .command('set-primary <id|name>', 'Set a branch as primary', (yargs) => yargs, async (args) => await setPrimary(args))
61
78
  .command('add-compute <id|name>', 'Add a compute to a branch', (yargs) => yargs.options({
@@ -194,3 +211,26 @@ const addCompute = async (props) => {
194
211
  fields: ['id', 'host'],
195
212
  });
196
213
  };
214
+ const reset = async (props) => {
215
+ if (!props.parent) {
216
+ throw new Error('Only resetting to parent is supported for now');
217
+ }
218
+ const branchId = await branchIdFromProps(props);
219
+ const { data: { branch }, } = await props.apiClient.getProjectBranch(props.projectId, branchId);
220
+ if (!branch.parent_id) {
221
+ throw new Error('Branch has no parent');
222
+ }
223
+ const { data } = await retryOnLock(() => props.apiClient.request({
224
+ method: 'POST',
225
+ path: `/projects/${props.projectId}/branches/${branch.id}/reset`,
226
+ body: {
227
+ source_branch_id: branch.parent_id,
228
+ preserve_under_name: props.preserveUnderName || undefined,
229
+ },
230
+ }));
231
+ const resultBranch = data.branch;
232
+ writer(props).end(resultBranch, {
233
+ // need to reset types until we expose reset api
234
+ fields: BRANCH_FIELDS_RESET,
235
+ });
236
+ };
@@ -250,4 +250,18 @@ describe('branches', () => {
250
250
  snapshot: true,
251
251
  },
252
252
  });
253
+ testCliCommand({
254
+ name: 'reset branch to parent',
255
+ args: [
256
+ 'branches',
257
+ 'reset',
258
+ 'test_branch',
259
+ '--project-id',
260
+ 'test',
261
+ '--parent',
262
+ ],
263
+ expected: {
264
+ snapshot: true,
265
+ },
266
+ });
253
267
  });
@@ -2,9 +2,7 @@ import { updateContextFile } from '../context.js';
2
2
  import { branchIdFromProps } from '../utils/enrichers.js';
3
3
  export const command = 'set-context';
4
4
  export const describe = 'Set the current context';
5
- export const builder = (argv) => argv
6
- .usage('$0 set-context [options]')
7
- .options({
5
+ export const builder = (argv) => argv.usage('$0 set-context [options]').options({
8
6
  'project-id': {
9
7
  describe: 'Project ID',
10
8
  type: 'string',
@@ -1,6 +1,6 @@
1
1
  import { tmpdir } from 'node:os';
2
2
  import { join } from 'node:path';
3
- import { rmSync } from 'node:fs';
3
+ import { rmSync, writeFileSync } from 'node:fs';
4
4
  import { afterAll, describe } from '@jest/globals';
5
5
  import { testCliCommand } from '../test_utils/test_cli_command';
6
6
  const CONTEXT_FILE = join(tmpdir(), `neon_${Date.now()}`);
@@ -26,5 +26,28 @@ describe('set_context', () => {
26
26
  snapshot: true,
27
27
  },
28
28
  });
29
+ const overrideContextFile = join(tmpdir(), `neon_override_ctx_${Date.now()}`);
30
+ testCliCommand({
31
+ name: 'get branch id overrides context set branch',
32
+ before: async () => {
33
+ writeFileSync(overrideContextFile, JSON.stringify({
34
+ projectId: 'test',
35
+ branchId: 'br-cloudy-branch-12345678',
36
+ }));
37
+ },
38
+ after: async () => {
39
+ rmSync(overrideContextFile);
40
+ },
41
+ args: [
42
+ 'branches',
43
+ 'get',
44
+ 'br-sunny-branch-123456',
45
+ '--context-file',
46
+ overrideContextFile,
47
+ ],
48
+ expected: {
49
+ snapshot: true,
50
+ },
51
+ });
29
52
  });
30
53
  });
package/context.js CHANGED
@@ -36,7 +36,7 @@ export const enrichFromContext = (args) => {
36
36
  return;
37
37
  }
38
38
  const context = readContextFile(args.contextFile);
39
- if (!args.branch) {
39
+ if (!args.branch && !args.id && !args.name) {
40
40
  args.branch = context.branchId;
41
41
  }
42
42
  if (!args.projectId) {
package/index.js CHANGED
@@ -25,7 +25,13 @@ import { isAxiosError } from 'axios';
25
25
  import { matchErrorCode } from './errors.js';
26
26
  import { showHelp } from './help.js';
27
27
  import { currentContextFile, enrichFromContext } from './context.js';
28
- const NO_SUBCOMMANDS_VERBS = ['auth', 'me', 'cs', 'connection-string', 'set-context'];
28
+ const NO_SUBCOMMANDS_VERBS = [
29
+ 'auth',
30
+ 'me',
31
+ 'cs',
32
+ 'connection-string',
33
+ 'set-context',
34
+ ];
29
35
  let builder = yargs(hideBin(process.argv));
30
36
  builder = builder
31
37
  .scriptName(pkg.name)
@@ -101,7 +107,9 @@ builder = builder
101
107
  })
102
108
  .alias('help', 'h')
103
109
  .middleware(async (args) => {
104
- if (args.help || args._.length === 1 && !NO_SUBCOMMANDS_VERBS.includes(args._[0])) {
110
+ if (args.help ||
111
+ (args._.length === 1 &&
112
+ !NO_SUBCOMMANDS_VERBS.includes(args._[0]))) {
105
113
  await showHelp(builder);
106
114
  }
107
115
  })
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "url": "git@github.com:neondatabase/neonctl.git"
6
6
  },
7
7
  "type": "module",
8
- "version": "1.23.3",
8
+ "version": "1.24.2",
9
9
  "description": "CLI tool for NeonDB Cloud management",
10
10
  "main": "index.js",
11
11
  "author": "NeonDB",
@@ -44,7 +44,7 @@
44
44
  "lint-staged": "^13.0.3",
45
45
  "oauth2-mock-server": "^6.0.0",
46
46
  "pkg": "^5.8.1",
47
- "prettier": "^2.7.1",
47
+ "prettier": "^3.1.0",
48
48
  "rollup": "^3.26.2",
49
49
  "semantic-release": "^21.0.2",
50
50
  "strip-ansi": "^7.1.0",
@@ -85,14 +85,18 @@
85
85
  },
86
86
  "scripts": {
87
87
  "watch": "tsc --watch",
88
- "lint": "tsc --noEmit && eslint src --ext .ts",
88
+ "lint": "tsc --noEmit && eslint src --ext .ts && prettier --check .",
89
89
  "build": "npm run generateParams && npm run clean && tsc && cp src/*.html package*.json README.md ./dist",
90
90
  "clean": "rm -rf dist",
91
91
  "generateParams": "node --loader ts-node/esm ./generateOptionsFromSpec.ts",
92
92
  "start": "node src/index.js",
93
- "test": "node --experimental-vm-modules node_modules/.bin/jest"
93
+ "test": "node --experimental-vm-modules node_modules/.bin/jest",
94
+ "prepare": "test -d .git && husky install || true"
94
95
  },
95
96
  "lint-staged": {
97
+ ".{cjs,js,json,md,html}": [
98
+ "prettier --write"
99
+ ],
96
100
  "*.ts": [
97
101
  "eslint --cache --fix",
98
102
  "prettier --write"
@@ -4,13 +4,19 @@ import { join } from 'node:path';
4
4
  import { log } from '../log.js';
5
5
  import strip from 'strip-ansi';
6
6
  import { runMockServer } from './mock_server.js';
7
- export const testCliCommand = ({ args, name, expected, mockDir = 'main', }) => {
7
+ export const testCliCommand = ({ args, name, expected, before, after, mockDir = 'main', }) => {
8
8
  let server;
9
9
  describe(name, () => {
10
10
  beforeAll(async () => {
11
+ if (before) {
12
+ await before();
13
+ }
11
14
  server = await runMockServer(mockDir);
12
15
  });
13
16
  afterAll(async () => {
17
+ if (after) {
18
+ await after();
19
+ }
14
20
  return new Promise((resolve) => {
15
21
  server.close(() => {
16
22
  resolve();
package/utils/formats.js CHANGED
@@ -1,4 +1,4 @@
1
- const HAIKU_REGEX = /^[a-z]+-[a-z]+-\d+$/;
1
+ const HAIKU_REGEX = /^[a-z]+-[a-z]+-[a-z0-9]+$/;
2
2
  export const looksLikeBranchId = (branch) => branch.startsWith('br-') && HAIKU_REGEX.test(branch.substring(3));
3
3
  const LSN_REGEX = /^[a-fA-F0-9]{1,8}\/[a-fA-F0-9]{1,8}$/;
4
4
  export const looksLikeLSN = (lsn) => LSN_REGEX.test(lsn);
@@ -0,0 +1,32 @@
1
+ import { test, describe, expect } from '@jest/globals';
2
+ import { looksLikeBranchId, looksLikeLSN, looksLikeTimestamp } from './formats';
3
+ describe('branch formats', () => {
4
+ test('branch name', () => {
5
+ expect(looksLikeBranchId('master')).toBe(false);
6
+ });
7
+ test('initial short', () => {
8
+ expect(looksLikeBranchId('br-flower-sunshine-123456')).toBe(true);
9
+ });
10
+ test('update 1, longer version', () => {
11
+ expect(looksLikeBranchId('br-flower-sunshine-12345678')).toBe(true);
12
+ });
13
+ test('update 2, includes region', () => {
14
+ expect(looksLikeBranchId('br-bold-recipe-a13oexw7')).toBe(true);
15
+ });
16
+ });
17
+ describe('timestamp formats', () => {
18
+ test('valid', () => {
19
+ expect(looksLikeTimestamp('2021-03-13T19:47:33.000Z')).toBe(true);
20
+ });
21
+ test('invalid', () => {
22
+ expect(looksLikeTimestamp('branch_name')).toBe(false);
23
+ });
24
+ });
25
+ describe('LSN formats', () => {
26
+ test('valid', () => {
27
+ expect(looksLikeLSN('0/1F56000')).toBe(true);
28
+ });
29
+ test('invalid', () => {
30
+ expect(looksLikeLSN('branch_name')).toBe(false);
31
+ });
32
+ });