@graphit/cli 0.1.1 → 0.1.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/package.json +1 -1
- package/skill/SKILL.md +68 -23
- package/skill/cursor/graphit-chart-patterns.mdc +67 -129
- package/skill/graphit.mdc +62 -80
- package/skill/references/chart-patterns.md +41 -218
- package/dist/api/client.d.ts +0 -16
- package/dist/api/client.js +0 -67
- package/dist/api/client.js.map +0 -1
- package/dist/auth/credentials.d.ts +0 -15
- package/dist/auth/credentials.js +0 -34
- package/dist/auth/credentials.js.map +0 -1
- package/dist/auth/login.d.ts +0 -2
- package/dist/auth/login.js +0 -230
- package/dist/auth/login.js.map +0 -1
- package/dist/auth/token.d.ts +0 -5
- package/dist/auth/token.js +0 -42
- package/dist/auth/token.js.map +0 -1
- package/dist/commands/auth.d.ts +0 -2
- package/dist/commands/auth.js +0 -68
- package/dist/commands/auth.js.map +0 -1
- package/dist/commands/connector.d.ts +0 -2
- package/dist/commands/connector.js +0 -97
- package/dist/commands/connector.js.map +0 -1
- package/dist/commands/dashboard.d.ts +0 -2
- package/dist/commands/dashboard.js +0 -124
- package/dist/commands/dashboard.js.map +0 -1
- package/dist/commands/ds.d.ts +0 -2
- package/dist/commands/ds.js +0 -53
- package/dist/commands/ds.js.map +0 -1
- package/dist/commands/kb.d.ts +0 -2
- package/dist/commands/kb.js +0 -259
- package/dist/commands/kb.js.map +0 -1
- package/dist/commands/query.d.ts +0 -2
- package/dist/commands/query.js +0 -61
- package/dist/commands/query.js.map +0 -1
- package/dist/commands/setup.d.ts +0 -2
- package/dist/commands/setup.js +0 -173
- package/dist/commands/setup.js.map +0 -1
- package/dist/config.d.ts +0 -4
- package/dist/config.js +0 -9
- package/dist/config.js.map +0 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.js +0 -24
- package/dist/index.js.map +0 -1
- package/dist/output/format.d.ts +0 -8
- package/dist/output/format.js +0 -30
- package/dist/output/format.js.map +0 -1
- package/dist/output/json.d.ts +0 -1
- package/dist/output/json.js +0 -4
- package/dist/output/json.js.map +0 -1
- package/dist/output/table.d.ts +0 -2
- package/dist/output/table.js +0 -17
- package/dist/output/table.js.map +0 -1
|
@@ -1,199 +1,62 @@
|
|
|
1
1
|
# Chart Patterns
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
All chart types are available via `graphit.chart()`. All data comes from `graphit.resolve()` - never embed static data.
|
|
4
4
|
|
|
5
|
-
**NEVER use `<canvas>`.** Canvas produces blurry charts inside the sandboxed iframe due to DPI scaling issues.
|
|
5
|
+
**NEVER use `<canvas>`.** Canvas produces blurry charts inside the sandboxed iframe due to DPI scaling issues.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## Runtime chart types
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
var maxVal = Math.max.apply(null, data.map(function(d){return d.value}));
|
|
12
|
-
data.forEach(function(d) {
|
|
13
|
-
var pct = (d.value / maxVal * 100).toFixed(1);
|
|
14
|
-
container.innerHTML += '<div style="display:flex;align-items:center;gap:12px;margin-bottom:8px">'
|
|
15
|
-
+ '<span style="width:100px;font-size:13px;font-weight:500;text-align:right">' + d.name + '</span>'
|
|
16
|
-
+ '<div style="flex:1;height:28px;background:var(--graphit-surface-sunken);border-radius:6px;overflow:hidden">'
|
|
17
|
-
+ '<div style="width:' + pct + '%;height:100%;background:var(--graphit-accent);border-radius:6px;min-width:2px"></div></div>'
|
|
18
|
-
+ '<span style="width:70px;font-size:13px;font-weight:600;text-align:right">' + fmt(d.value) + '</span></div>';
|
|
19
|
-
});
|
|
20
|
-
```
|
|
9
|
+
### bar
|
|
10
|
+
SVG vertical bars. Multi-series: grouped side-by-side. Y-axis: 4 grid lines with formatted labels. X-axis: category labels (sampled if >12). Rounded top corners (rx=3). `<title>` tooltips per bar.
|
|
21
11
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
var maxVal = Math.max.apply(null, data.map(function(d){return d.value}));
|
|
25
|
-
container.style.cssText = 'display:flex;align-items:flex-end;gap:8px;height:200px;padding-top:20px';
|
|
26
|
-
data.forEach(function(d) {
|
|
27
|
-
var pct = (d.value / maxVal * 100).toFixed(1);
|
|
28
|
-
container.innerHTML += '<div style="flex:1;height:' + pct + '%;background:var(--graphit-accent);border-radius:4px 4px 0 0;'
|
|
29
|
-
+ 'position:relative;min-width:30px">'
|
|
30
|
-
+ '<span style="position:absolute;top:-20px;left:50%;transform:translateX(-50%);font-size:12px;font-weight:600">'
|
|
31
|
-
+ d.value + '</span>'
|
|
32
|
-
+ '<span style="position:absolute;bottom:-22px;left:50%;transform:translateX(-50%);font-size:11px;color:var(--graphit-fg-subtle);white-space:nowrap">'
|
|
33
|
-
+ d.name + '</span></div>';
|
|
34
|
-
});
|
|
35
|
-
```
|
|
12
|
+
### line / area
|
|
13
|
+
SVG line with circle dots at each point. Area adds filled path below (opacity 0.18). Multi-series: separate colored paths. Y-axis scaled to data range (min to max). `<title>` tooltips per dot.
|
|
36
14
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
var colors = ['var(--graphit-accent)','#80CBC4','#26A69A','#5FA39B'];
|
|
40
|
-
data.forEach(function(row) {
|
|
41
|
-
var total = row.segments.reduce(function(a,s){return a+s.value},0);
|
|
42
|
-
var html = '<div style="display:flex;align-items:center;gap:12px;margin-bottom:8px">'
|
|
43
|
-
+ '<span style="width:100px;font-size:13px;font-weight:500;text-align:right">' + row.name + '</span>'
|
|
44
|
-
+ '<div style="flex:1;height:28px;display:flex;border-radius:6px;overflow:hidden">';
|
|
45
|
-
row.segments.forEach(function(s, i) {
|
|
46
|
-
html += '<div style="width:' + (s.value/total*100).toFixed(1) + '%;height:100%;background:' + colors[i%colors.length] + '"></div>';
|
|
47
|
-
});
|
|
48
|
-
html += '</div><span style="width:70px;font-size:13px;font-weight:600;text-align:right">' + total + '</span></div>';
|
|
49
|
-
container.innerHTML += html;
|
|
50
|
-
});
|
|
51
|
-
```
|
|
15
|
+
### donut / pie
|
|
16
|
+
SVG pie slices with center hole (58% of radius). Center shows formatted total. Legend below with color swatches. Each slice is a wedge path from center.
|
|
52
17
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
var maxVal = Math.max.apply(null, data.map(function(d){return d.value}));
|
|
57
|
-
var points = data.map(function(d, i) {
|
|
58
|
-
var x = pad + (i / (data.length - 1)) * (w - 2*pad);
|
|
59
|
-
var y = h - pad - ((d.value / maxVal) * (h - 2*pad));
|
|
60
|
-
return x + ',' + y;
|
|
61
|
-
});
|
|
62
|
-
svg.setAttribute('viewBox', '0 0 ' + w + ' ' + h);
|
|
63
|
-
svg.innerHTML =
|
|
64
|
-
'<path d="M' + points.join(' L') + ' L' + (w-pad) + ',' + (h-pad) + ' L' + pad + ',' + (h-pad) + ' Z" fill="rgba(77,182,172,0.15)"/>'
|
|
65
|
-
+ '<path d="M' + points.join(' L') + '" fill="none" stroke="var(--graphit-accent)" stroke-width="2"/>';
|
|
66
|
-
```
|
|
18
|
+
### scatter / bubble
|
|
19
|
+
SVG circles positioned by x/y. Size field scales radius (sqrt, 3-40px). Fill opacity 0.6 with solid stroke. 4 horizontal grid lines. Capped at 200 points.
|
|
20
|
+
Config: `x`, `y`, `size` (optional radius), `label` (tooltip), `xFormat`.
|
|
67
21
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
series.forEach(function(s, si) {
|
|
72
|
-
var pts = s.values.map(function(v, i) {
|
|
73
|
-
var x = pad + (i / (s.values.length - 1)) * (w - 2*pad);
|
|
74
|
-
var y = h - pad - ((v / maxAll) * (h - 2*pad));
|
|
75
|
-
return x + ',' + y;
|
|
76
|
-
});
|
|
77
|
-
svg.innerHTML += '<path d="M' + pts.join(' L') + '" fill="none" stroke="' + colors[si] + '" stroke-width="2"/>';
|
|
78
|
-
});
|
|
79
|
-
```
|
|
22
|
+
### stacked-bar / stacked
|
|
23
|
+
SVG vertical stacked bars. Segments stacked bottom-to-top per category. Y-axis scaled to max total. Legend shows series names.
|
|
24
|
+
Config: requires `series` field for stacking groups.
|
|
80
25
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
var max = Math.max.apply(null,vals), min = Math.min.apply(null,vals);
|
|
85
|
-
var pts = vals.map(function(v,i){
|
|
86
|
-
return (i/(vals.length-1))*120 + ',' + (30 - ((v-min)/(max-min||1))*26 - 2);
|
|
87
|
-
}).join(' L');
|
|
88
|
-
sparkSvg.innerHTML = '<path d="M' + pts + '" fill="none" stroke="var(--graphit-accent)" stroke-width="1.5"/>';
|
|
89
|
-
```
|
|
26
|
+
### heatmap
|
|
27
|
+
CSS grid. X = columns, Y = rows. Background intensity scales linearly (rgba teal, 0.08-0.98). Text flips white at >55% intensity. Headers auto-generated. Capped at 40x40.
|
|
28
|
+
Config: `x` (column), `y` (row), `value` (intensity, falls back to `y`).
|
|
90
29
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
var slices = [{v:40,c:'var(--graphit-accent)',label:'Category A'},{v:25,c:'#80CBC4',label:'Category B'},{v:20,c:'#26A69A',label:'Category C'},{v:15,c:'#009688',label:'Category D'}];
|
|
94
|
-
var total = slices.reduce(function(a,s){return a+s.v},0);
|
|
95
|
-
var cx=100, cy=100, r=80, hole=50, angle=-Math.PI/2;
|
|
96
|
-
svg.setAttribute('viewBox','0 0 200 200');
|
|
97
|
-
slices.forEach(function(s) {
|
|
98
|
-
var arc = (s.v/total)*Math.PI*2;
|
|
99
|
-
var x1 = cx + r*Math.cos(angle), y1 = cy + r*Math.sin(angle);
|
|
100
|
-
var x2 = cx + r*Math.cos(angle+arc), y2 = cy + r*Math.sin(angle+arc);
|
|
101
|
-
var large = arc > Math.PI ? 1 : 0;
|
|
102
|
-
var path = 'M'+x1+','+y1+' A'+r+','+r+' 0 '+large+' 1 '+x2+','+y2+' L'+cx+','+cy+' Z';
|
|
103
|
-
var el = document.createElementNS('http://www.w3.org/2000/svg','path');
|
|
104
|
-
el.setAttribute('d', path); el.setAttribute('fill', s.c);
|
|
105
|
-
el.style.cursor = 'pointer';
|
|
106
|
-
el.addEventListener('mouseenter', function(e) { showTooltip(e, s.label+': '+s.v+' ('+(s.v/total*100).toFixed(1)+'%)'); });
|
|
107
|
-
el.addEventListener('mouseleave', hideTooltip);
|
|
108
|
-
svg.appendChild(el);
|
|
109
|
-
angle += arc;
|
|
110
|
-
});
|
|
111
|
-
// Center hole
|
|
112
|
-
var circle = document.createElementNS('http://www.w3.org/2000/svg','circle');
|
|
113
|
-
circle.setAttribute('cx',cx); circle.setAttribute('cy',cy); circle.setAttribute('r',hole);
|
|
114
|
-
circle.setAttribute('fill','var(--graphit-surface-raised)');
|
|
115
|
-
svg.appendChild(circle);
|
|
116
|
-
```
|
|
30
|
+
### funnel
|
|
31
|
+
CSS horizontal bars narrowing top-to-bottom. First bar = 100% width, rest proportional. Shows step-over-step conversion rate. Colors cycle through palette.
|
|
117
32
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
var svgW=500, svgH=300, pad={top:16,right:16,bottom:36,left:50};
|
|
122
|
-
var pW=svgW-pad.left-pad.right, pH=svgH-pad.top-pad.bottom;
|
|
123
|
-
svg.setAttribute('viewBox','0 0 '+svgW+' '+svgH);
|
|
124
|
-
var maxX=Math.max.apply(null,data.map(function(d){return d.x}))*1.1;
|
|
125
|
-
var maxY=Math.max.apply(null,data.map(function(d){return d.y}))*1.15;
|
|
126
|
-
// Sort large-to-small so small bubbles render on top
|
|
127
|
-
data.sort(function(a,b){return b.size-a.size});
|
|
128
|
-
data.forEach(function(d) {
|
|
129
|
-
var cx = pad.left + (d.x/maxX)*pW;
|
|
130
|
-
var cy = svgH - pad.bottom - (d.y/maxY)*pH;
|
|
131
|
-
var r = Math.max(5, Math.sqrt(d.size)*28);
|
|
132
|
-
var g = document.createElementNS('http://www.w3.org/2000/svg','g');
|
|
133
|
-
g.style.cursor = 'pointer';
|
|
134
|
-
var c = document.createElementNS('http://www.w3.org/2000/svg','circle');
|
|
135
|
-
c.setAttribute('cx',cx); c.setAttribute('cy',cy); c.setAttribute('r',r);
|
|
136
|
-
c.setAttribute('fill','var(--graphit-accent)'); c.setAttribute('fill-opacity','0.55');
|
|
137
|
-
c.setAttribute('stroke','var(--graphit-accent)'); c.setAttribute('stroke-width','1.5');
|
|
138
|
-
g.appendChild(c);
|
|
139
|
-
var t = document.createElementNS('http://www.w3.org/2000/svg','text');
|
|
140
|
-
t.setAttribute('x',cx); t.setAttribute('y',cy-r-4);
|
|
141
|
-
t.setAttribute('text-anchor','middle'); t.setAttribute('font-size','10');
|
|
142
|
-
t.setAttribute('fill','var(--graphit-fg-subtle)');
|
|
143
|
-
t.textContent = d.label; g.appendChild(t);
|
|
144
|
-
g.addEventListener('mouseenter', function(e){ showTooltip(e, d.tooltipHtml); });
|
|
145
|
-
g.addEventListener('mousemove', function(e){ showTooltip(e, tooltip.innerHTML); });
|
|
146
|
-
g.addEventListener('mouseleave', hideTooltip);
|
|
147
|
-
svg.appendChild(g);
|
|
148
|
-
});
|
|
149
|
-
```
|
|
33
|
+
### gauge
|
|
34
|
+
CSS half-circle via `conic-gradient` + `clip-path`. Auto-colors: green (>=70%), yellow (>=40%), red (<40%). Override with `color` config (must be a valid CSS color token).
|
|
35
|
+
Config: `value`, `min` (default 0), `max` (default 100), `format`, `label`, `color`.
|
|
150
36
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
container.style.cssText = 'display:grid;grid-template-columns:repeat(' + cols + ',1fr);gap:2px';
|
|
155
|
-
cells.forEach(function(c) {
|
|
156
|
-
var intensity = c.value / max;
|
|
157
|
-
var bg = 'rgba(77,182,172,' + (0.1 + intensity*0.9).toFixed(2) + ')';
|
|
158
|
-
var fg = intensity > 0.6 ? 'white' : 'var(--graphit-fg)';
|
|
159
|
-
container.innerHTML += '<div style="aspect-ratio:1;border-radius:3px;display:flex;align-items:center;'
|
|
160
|
-
+ 'justify-content:center;font-size:11px;font-weight:600;background:' + bg + ';color:' + fg + '">'
|
|
161
|
-
+ c.value + '</div>';
|
|
162
|
-
});
|
|
163
|
-
```
|
|
37
|
+
### sparkline
|
|
38
|
+
Inline SVG polyline for KPI cards or table cells. No axes, no grid - just trend shape. Single data point renders as a dot.
|
|
39
|
+
Config: `y`, `width` (default 120), `height` (default 32), `label`, `showValue` (default true), `valueFormat`.
|
|
164
40
|
|
|
165
|
-
##
|
|
166
|
-
```js
|
|
167
|
-
var maxVal = data[0].value;
|
|
168
|
-
data.forEach(function(d, i) {
|
|
169
|
-
var pct = (d.value / maxVal * 100).toFixed(1);
|
|
170
|
-
var rate = i > 0 ? (d.value / data[i-1].value * 100).toFixed(1) + '%' : '';
|
|
171
|
-
container.innerHTML += '<div style="display:flex;align-items:center;gap:12px;margin-bottom:6px">'
|
|
172
|
-
+ '<span style="width:120px;font-size:13px;text-align:right">' + d.name + '</span>'
|
|
173
|
-
+ '<div style="width:' + pct + '%;height:36px;background:var(--graphit-accent);border-radius:4px;'
|
|
174
|
-
+ 'display:flex;align-items:center;padding:0 12px;color:white;font-weight:600;font-size:13px">'
|
|
175
|
-
+ d.value.toLocaleString() + '</div>'
|
|
176
|
-
+ '<span style="font-size:12px;color:var(--graphit-fg-subtle)">' + rate + '</span></div>';
|
|
177
|
-
});
|
|
178
|
-
```
|
|
41
|
+
## Color tokens
|
|
179
42
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
43
|
+
| Token | Usage |
|
|
44
|
+
|---|---|
|
|
45
|
+
| `var(--graphit-accent)` | Primary brand teal |
|
|
46
|
+
| `var(--graphit-success)` | Positive/good |
|
|
47
|
+
| `var(--graphit-warning)` | Caution |
|
|
48
|
+
| `var(--graphit-error)` | Negative/bad |
|
|
49
|
+
| `var(--graphit-fg)` | Primary text |
|
|
50
|
+
| `var(--graphit-fg-muted)` | Secondary text |
|
|
51
|
+
| `var(--graphit-fg-subtle)` | Labels, placeholders |
|
|
52
|
+
| `var(--graphit-border)` | Borders, grid lines |
|
|
53
|
+
| `var(--graphit-surface-raised)` | Card backgrounds |
|
|
54
|
+
| `var(--graphit-surface-sunken)` | Inset areas |
|
|
191
55
|
|
|
192
|
-
## Tooltip
|
|
56
|
+
## Tooltip pattern (for hand-rolled charts)
|
|
193
57
|
|
|
194
|
-
|
|
58
|
+
Runtime charts use `<title>` elements for native browser tooltips. For hand-rolled charts, add ONE shared tooltip div and always escape user data with a manual HTML escape function before passing to `showTooltip()`:
|
|
195
59
|
|
|
196
|
-
### HTML (add once, before `<script>`)
|
|
197
60
|
```html
|
|
198
61
|
<div id="tooltip" style="position:fixed;pointer-events:none;z-index:100;
|
|
199
62
|
background:var(--graphit-surface-raised);color:var(--graphit-fg);
|
|
@@ -203,7 +66,6 @@ Every chart with data points should have hover tooltips. Add ONE shared tooltip
|
|
|
203
66
|
max-width:240px"></div>
|
|
204
67
|
```
|
|
205
68
|
|
|
206
|
-
### JS helpers (add once)
|
|
207
69
|
```js
|
|
208
70
|
var tooltip = document.getElementById('tooltip');
|
|
209
71
|
function showTooltip(e, html) {
|
|
@@ -216,42 +78,3 @@ function showTooltip(e, html) {
|
|
|
216
78
|
}
|
|
217
79
|
function hideTooltip() { tooltip.style.opacity = '0'; }
|
|
218
80
|
```
|
|
219
|
-
|
|
220
|
-
### Tooltip row layout
|
|
221
|
-
```html
|
|
222
|
-
<!-- Inside tooltip content -->
|
|
223
|
-
<div style="font-weight:700;margin-bottom:4px">Title</div>
|
|
224
|
-
<div style="display:flex;justify-content:space-between;gap:16px">
|
|
225
|
-
<span style="color:var(--graphit-fg-muted)">Label</span>
|
|
226
|
-
<span style="font-weight:600">Value</span>
|
|
227
|
-
</div>
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
### SVG event attachment patterns
|
|
231
|
-
```js
|
|
232
|
-
// Bubble/scatter/donut: attach on each SVG <g> or <path>
|
|
233
|
-
element.addEventListener('mouseenter', function(e) { showTooltip(e, htmlContent); });
|
|
234
|
-
element.addEventListener('mousemove', function(e) { showTooltip(e, tooltip.innerHTML); });
|
|
235
|
-
element.addEventListener('mouseleave', hideTooltip);
|
|
236
|
-
|
|
237
|
-
// Line chart: invisible rect columns per x-tick + vertical guide line
|
|
238
|
-
weekData.forEach(function(w, i) {
|
|
239
|
-
var rect = document.createElementNS(NS, 'rect');
|
|
240
|
-
// x, y, width=colWidth, height=plotHeight, fill='transparent', cursor='pointer'
|
|
241
|
-
var vLine = document.createElementNS(NS, 'line');
|
|
242
|
-
// vertical dashed line at xPos(i), opacity=0
|
|
243
|
-
rect.addEventListener('mouseenter', function(e) {
|
|
244
|
-
vLine.setAttribute('opacity', '1');
|
|
245
|
-
showTooltip(e, buildWeekTooltip(w));
|
|
246
|
-
});
|
|
247
|
-
rect.addEventListener('mouseleave', function() {
|
|
248
|
-
vLine.setAttribute('opacity', '0');
|
|
249
|
-
hideTooltip();
|
|
250
|
-
});
|
|
251
|
-
});
|
|
252
|
-
|
|
253
|
-
// CSS bar rows: attach on each bar <div> row
|
|
254
|
-
row.addEventListener('mouseenter', function(e) { showTooltip(e, htmlContent); });
|
|
255
|
-
row.addEventListener('mousemove', function(e) { showTooltip(e, tooltip.innerHTML); });
|
|
256
|
-
row.addEventListener('mouseleave', hideTooltip);
|
|
257
|
-
```
|
package/dist/api/client.d.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export interface ApiError {
|
|
2
|
-
status: number;
|
|
3
|
-
detail: string;
|
|
4
|
-
retry_after_seconds?: number;
|
|
5
|
-
}
|
|
6
|
-
declare class ApiClient {
|
|
7
|
-
request<T>(method: string, path: string, body?: unknown): Promise<T>;
|
|
8
|
-
postUnauthed<T>(path: string, body: unknown): Promise<T>;
|
|
9
|
-
get<T>(path: string): Promise<T>;
|
|
10
|
-
post<T>(path: string, body: unknown): Promise<T>;
|
|
11
|
-
put<T>(path: string, body: unknown): Promise<T>;
|
|
12
|
-
delete<T>(path: string): Promise<T>;
|
|
13
|
-
private _fetch;
|
|
14
|
-
}
|
|
15
|
-
export declare const apiClient: ApiClient;
|
|
16
|
-
export {};
|
package/dist/api/client.js
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import { getValidIdToken } from "../auth/token.js";
|
|
2
|
-
import { getApiBaseUrl } from "../config.js";
|
|
3
|
-
const REQUEST_TIMEOUT_MS = 30_000;
|
|
4
|
-
class ApiClient {
|
|
5
|
-
async request(method, path, body) {
|
|
6
|
-
const { id_token } = await getValidIdToken();
|
|
7
|
-
return this._fetch(method, path, body, {
|
|
8
|
-
Authorization: `Bearer ${id_token}`,
|
|
9
|
-
});
|
|
10
|
-
}
|
|
11
|
-
async postUnauthed(path, body) {
|
|
12
|
-
return this._fetch("POST", path, body);
|
|
13
|
-
}
|
|
14
|
-
async get(path) {
|
|
15
|
-
return this.request("GET", path);
|
|
16
|
-
}
|
|
17
|
-
async post(path, body) {
|
|
18
|
-
return this.request("POST", path, body);
|
|
19
|
-
}
|
|
20
|
-
async put(path, body) {
|
|
21
|
-
return this.request("PUT", path, body);
|
|
22
|
-
}
|
|
23
|
-
async delete(path) {
|
|
24
|
-
return this.request("DELETE", path);
|
|
25
|
-
}
|
|
26
|
-
async _fetch(method, path, body, extraHeaders) {
|
|
27
|
-
const url = `${getApiBaseUrl()}${path}`;
|
|
28
|
-
const headers = {
|
|
29
|
-
"Content-Type": "application/json",
|
|
30
|
-
"X-Graphit-Source": "cli",
|
|
31
|
-
...extraHeaders,
|
|
32
|
-
};
|
|
33
|
-
const resp = await fetch(url, {
|
|
34
|
-
method,
|
|
35
|
-
headers,
|
|
36
|
-
body: body ? JSON.stringify(body) : undefined,
|
|
37
|
-
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
|
|
38
|
-
});
|
|
39
|
-
if (!resp.ok) {
|
|
40
|
-
let detail = `HTTP ${resp.status}`;
|
|
41
|
-
try {
|
|
42
|
-
const errBody = (await resp.json());
|
|
43
|
-
detail = errBody.detail || detail;
|
|
44
|
-
if (resp.status === 429) {
|
|
45
|
-
const retryAfter = parseInt(resp.headers.get("Retry-After") || "60", 10);
|
|
46
|
-
const err = {
|
|
47
|
-
status: 429,
|
|
48
|
-
detail,
|
|
49
|
-
retry_after_seconds: retryAfter,
|
|
50
|
-
};
|
|
51
|
-
throw err;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
catch (e) {
|
|
55
|
-
if (e.status === 429)
|
|
56
|
-
throw e;
|
|
57
|
-
}
|
|
58
|
-
const err = { status: resp.status, detail };
|
|
59
|
-
throw err;
|
|
60
|
-
}
|
|
61
|
-
if (resp.status === 204)
|
|
62
|
-
return undefined;
|
|
63
|
-
return (await resp.json());
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
export const apiClient = new ApiClient();
|
|
67
|
-
//# sourceMappingURL=client.js.map
|
package/dist/api/client.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export interface StoredCredentials {
|
|
2
|
-
refresh_token: string;
|
|
3
|
-
user_id: string;
|
|
4
|
-
email: string;
|
|
5
|
-
org_id: string;
|
|
6
|
-
org_name: string;
|
|
7
|
-
seat_type: string;
|
|
8
|
-
created_at: string;
|
|
9
|
-
id_token?: string;
|
|
10
|
-
id_token_expiry?: number;
|
|
11
|
-
}
|
|
12
|
-
export declare function getCredentialsPath(): string;
|
|
13
|
-
export declare function readCredentials(): Promise<StoredCredentials | null>;
|
|
14
|
-
export declare function writeCredentials(creds: StoredCredentials): Promise<void>;
|
|
15
|
-
export declare function deleteCredentials(): Promise<void>;
|
package/dist/auth/credentials.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { readFile, writeFile, unlink, mkdir, chmod } from "node:fs/promises";
|
|
2
|
-
import { homedir } from "node:os";
|
|
3
|
-
import { join, dirname } from "node:path";
|
|
4
|
-
import { existsSync } from "node:fs";
|
|
5
|
-
const CREDENTIALS_PATH = join(homedir(), ".graphit", "credentials.json");
|
|
6
|
-
export function getCredentialsPath() {
|
|
7
|
-
return CREDENTIALS_PATH;
|
|
8
|
-
}
|
|
9
|
-
export async function readCredentials() {
|
|
10
|
-
try {
|
|
11
|
-
const raw = await readFile(CREDENTIALS_PATH, "utf-8");
|
|
12
|
-
return JSON.parse(raw);
|
|
13
|
-
}
|
|
14
|
-
catch {
|
|
15
|
-
return null;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
export async function writeCredentials(creds) {
|
|
19
|
-
const dir = dirname(CREDENTIALS_PATH);
|
|
20
|
-
if (!existsSync(dir)) {
|
|
21
|
-
await mkdir(dir, { recursive: true });
|
|
22
|
-
}
|
|
23
|
-
await writeFile(CREDENTIALS_PATH, JSON.stringify(creds, null, 2), "utf-8");
|
|
24
|
-
await chmod(CREDENTIALS_PATH, 0o600);
|
|
25
|
-
}
|
|
26
|
-
export async function deleteCredentials() {
|
|
27
|
-
try {
|
|
28
|
-
await unlink(CREDENTIALS_PATH);
|
|
29
|
-
}
|
|
30
|
-
catch {
|
|
31
|
-
// File may not exist
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
//# sourceMappingURL=credentials.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/auth/credentials.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAcrC,MAAM,gBAAgB,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,kBAAkB,CAAC,CAAC;AAEzE,MAAM,UAAU,kBAAkB;IAChC,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;QACtD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAsB,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,KAAwB;IAC7D,MAAM,GAAG,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACtC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACrB,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACxC,CAAC;IACD,MAAM,SAAS,CAAC,gBAAgB,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IAC3E,MAAM,KAAK,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,qBAAqB;IACvB,CAAC;AACH,CAAC"}
|
package/dist/auth/login.d.ts
DELETED