redkite 0.1.6

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.
Files changed (179) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +819 -0
  3. package/bin/redkite.mjs +12 -0
  4. package/dist/build.d.ts +27 -0
  5. package/dist/build.d.ts.map +1 -0
  6. package/dist/build.js +132 -0
  7. package/dist/build.js.map +1 -0
  8. package/dist/checks.d.ts +4 -0
  9. package/dist/checks.d.ts.map +1 -0
  10. package/dist/checks.js +49 -0
  11. package/dist/checks.js.map +1 -0
  12. package/dist/cli/agent.d.ts +2 -0
  13. package/dist/cli/agent.d.ts.map +1 -0
  14. package/dist/cli/agent.js +24 -0
  15. package/dist/cli/agent.js.map +1 -0
  16. package/dist/cli/config.d.ts +5 -0
  17. package/dist/cli/config.d.ts.map +1 -0
  18. package/dist/cli/config.js +217 -0
  19. package/dist/cli/config.js.map +1 -0
  20. package/dist/cli/index.d.ts +11 -0
  21. package/dist/cli/index.d.ts.map +1 -0
  22. package/dist/cli/index.js +438 -0
  23. package/dist/cli/index.js.map +1 -0
  24. package/dist/cli/log.d.ts +9 -0
  25. package/dist/cli/log.d.ts.map +1 -0
  26. package/dist/cli/log.js +128 -0
  27. package/dist/cli/log.js.map +1 -0
  28. package/dist/cli/screen.d.ts +34 -0
  29. package/dist/cli/screen.d.ts.map +1 -0
  30. package/dist/cli/screen.js +298 -0
  31. package/dist/cli/screen.js.map +1 -0
  32. package/dist/cli/viewer.d.ts +9 -0
  33. package/dist/cli/viewer.d.ts.map +1 -0
  34. package/dist/cli/viewer.js +139 -0
  35. package/dist/cli/viewer.js.map +1 -0
  36. package/dist/config.d.ts +7 -0
  37. package/dist/config.d.ts.map +1 -0
  38. package/dist/config.js +79 -0
  39. package/dist/config.js.map +1 -0
  40. package/dist/deploy.d.ts +19 -0
  41. package/dist/deploy.d.ts.map +1 -0
  42. package/dist/deploy.js +275 -0
  43. package/dist/deploy.js.map +1 -0
  44. package/dist/docker.d.ts +96 -0
  45. package/dist/docker.d.ts.map +1 -0
  46. package/dist/docker.js +325 -0
  47. package/dist/docker.js.map +1 -0
  48. package/dist/dockerfile.d.ts +14 -0
  49. package/dist/dockerfile.d.ts.map +1 -0
  50. package/dist/dockerfile.js +160 -0
  51. package/dist/dockerfile.js.map +1 -0
  52. package/dist/health.d.ts +13 -0
  53. package/dist/health.d.ts.map +1 -0
  54. package/dist/health.js +54 -0
  55. package/dist/health.js.map +1 -0
  56. package/dist/host.d.ts +21 -0
  57. package/dist/host.d.ts.map +1 -0
  58. package/dist/host.js +27 -0
  59. package/dist/host.js.map +1 -0
  60. package/dist/index.d.ts +26 -0
  61. package/dist/index.d.ts.map +1 -0
  62. package/dist/index.js +26 -0
  63. package/dist/index.js.map +1 -0
  64. package/dist/layout.d.ts +5 -0
  65. package/dist/layout.d.ts.map +1 -0
  66. package/dist/layout.js +45 -0
  67. package/dist/layout.js.map +1 -0
  68. package/dist/localHost.d.ts +7 -0
  69. package/dist/localHost.d.ts.map +1 -0
  70. package/dist/localHost.js +32 -0
  71. package/dist/localHost.js.map +1 -0
  72. package/dist/log.d.ts +14 -0
  73. package/dist/log.d.ts.map +1 -0
  74. package/dist/log.js +15 -0
  75. package/dist/log.js.map +1 -0
  76. package/dist/nginx.d.ts +4 -0
  77. package/dist/nginx.d.ts.map +1 -0
  78. package/dist/nginx.js +53 -0
  79. package/dist/nginx.js.map +1 -0
  80. package/dist/pipeline.d.ts +103 -0
  81. package/dist/pipeline.d.ts.map +1 -0
  82. package/dist/pipeline.js +142 -0
  83. package/dist/pipeline.js.map +1 -0
  84. package/dist/presets/index.d.ts +3 -0
  85. package/dist/presets/index.d.ts.map +1 -0
  86. package/dist/presets/index.js +3 -0
  87. package/dist/presets/index.js.map +1 -0
  88. package/dist/presets/nextApp.d.ts +15 -0
  89. package/dist/presets/nextApp.d.ts.map +1 -0
  90. package/dist/presets/nextApp.js +53 -0
  91. package/dist/presets/nextApp.js.map +1 -0
  92. package/dist/presets/nodeApp.d.ts +19 -0
  93. package/dist/presets/nodeApp.d.ts.map +1 -0
  94. package/dist/presets/nodeApp.js +29 -0
  95. package/dist/presets/nodeApp.js.map +1 -0
  96. package/dist/secrets/bitwarden.d.ts +3 -0
  97. package/dist/secrets/bitwarden.d.ts.map +1 -0
  98. package/dist/secrets/bitwarden.js +6 -0
  99. package/dist/secrets/bitwarden.js.map +1 -0
  100. package/dist/secrets/refs.d.ts +9 -0
  101. package/dist/secrets/refs.d.ts.map +1 -0
  102. package/dist/secrets/refs.js +20 -0
  103. package/dist/secrets/refs.js.map +1 -0
  104. package/dist/secrets/store.d.ts +9 -0
  105. package/dist/secrets/store.d.ts.map +1 -0
  106. package/dist/secrets/store.js +104 -0
  107. package/dist/secrets/store.js.map +1 -0
  108. package/dist/services/ensure.d.ts +18 -0
  109. package/dist/services/ensure.d.ts.map +1 -0
  110. package/dist/services/ensure.js +93 -0
  111. package/dist/services/ensure.js.map +1 -0
  112. package/dist/services/index.d.ts +19 -0
  113. package/dist/services/index.d.ts.map +1 -0
  114. package/dist/services/index.js +27 -0
  115. package/dist/services/index.js.map +1 -0
  116. package/dist/services/planned.d.ts +20 -0
  117. package/dist/services/planned.d.ts.map +1 -0
  118. package/dist/services/planned.js +77 -0
  119. package/dist/services/planned.js.map +1 -0
  120. package/dist/shell.d.ts +11 -0
  121. package/dist/shell.d.ts.map +1 -0
  122. package/dist/shell.js +65 -0
  123. package/dist/shell.js.map +1 -0
  124. package/dist/source.d.ts +16 -0
  125. package/dist/source.d.ts.map +1 -0
  126. package/dist/source.js +108 -0
  127. package/dist/source.js.map +1 -0
  128. package/dist/sshHost.d.ts +15 -0
  129. package/dist/sshHost.d.ts.map +1 -0
  130. package/dist/sshHost.js +91 -0
  131. package/dist/sshHost.js.map +1 -0
  132. package/dist/steps.d.ts +27 -0
  133. package/dist/steps.d.ts.map +1 -0
  134. package/dist/steps.js +69 -0
  135. package/dist/steps.js.map +1 -0
  136. package/dist/topology.d.ts +40 -0
  137. package/dist/topology.d.ts.map +1 -0
  138. package/dist/topology.js +113 -0
  139. package/dist/topology.js.map +1 -0
  140. package/dist/types.d.ts +100 -0
  141. package/dist/types.d.ts.map +1 -0
  142. package/dist/types.js +2 -0
  143. package/dist/types.js.map +1 -0
  144. package/package.json +64 -0
  145. package/src/build.ts +236 -0
  146. package/src/checks.ts +65 -0
  147. package/src/cli/agent.ts +28 -0
  148. package/src/cli/config.ts +275 -0
  149. package/src/cli/index.ts +559 -0
  150. package/src/cli/log.ts +168 -0
  151. package/src/cli/screen.ts +409 -0
  152. package/src/cli/viewer.ts +192 -0
  153. package/src/config.ts +90 -0
  154. package/src/deploy.ts +409 -0
  155. package/src/docker.ts +433 -0
  156. package/src/dockerfile.ts +228 -0
  157. package/src/health.ts +83 -0
  158. package/src/host.ts +54 -0
  159. package/src/index.ts +25 -0
  160. package/src/layout.ts +41 -0
  161. package/src/localHost.ts +50 -0
  162. package/src/log.ts +38 -0
  163. package/src/nginx.ts +63 -0
  164. package/src/pipeline.ts +335 -0
  165. package/src/presets/index.ts +2 -0
  166. package/src/presets/nextApp.ts +70 -0
  167. package/src/presets/nodeApp.ts +46 -0
  168. package/src/secrets/bitwarden.ts +7 -0
  169. package/src/secrets/refs.ts +32 -0
  170. package/src/secrets/store.ts +147 -0
  171. package/src/services/ensure.ts +160 -0
  172. package/src/services/index.ts +48 -0
  173. package/src/services/planned.ts +119 -0
  174. package/src/shell.ts +95 -0
  175. package/src/source.ts +171 -0
  176. package/src/sshHost.ts +145 -0
  177. package/src/steps.ts +101 -0
  178. package/src/topology.ts +199 -0
  179. package/src/types.ts +243 -0
@@ -0,0 +1,298 @@
1
+ // The deploy as a list of collapsibles. A step is a title and the lines it
2
+ // produced; the one running is open, the ones finished are shut, and the person
3
+ // watching moves between them. The model and the renderer are pure, so what the
4
+ // terminal shows is asserted on rather than driven.
5
+ export function emptyModel(rows, columns, now) {
6
+ return {
7
+ steps: [],
8
+ messages: [],
9
+ cursor: 0,
10
+ following: true,
11
+ minimal: false,
12
+ rows,
13
+ columns,
14
+ started: now,
15
+ now,
16
+ };
17
+ }
18
+ const ESCAPE = "\u001b";
19
+ const INTERRUPT = "\u0003";
20
+ // A terminal delivers whatever arrived since the last read, so two arrow keys
21
+ // pressed quickly land as one chunk. Reading only the whole chunk drops both
22
+ export function keysOf(data) {
23
+ const keys = [];
24
+ let rest = data;
25
+ while (rest.length > 0) {
26
+ const sequence = rest.startsWith(ESCAPE) ? CSI.exec(rest)?.[0] : undefined;
27
+ const token = sequence ?? rest.slice(0, 1);
28
+ const key = keyOf(token);
29
+ if (key)
30
+ keys.push(key);
31
+ rest = rest.slice(token.length);
32
+ }
33
+ return keys;
34
+ }
35
+ const CSI = /^\u001b\[[0-9;]*[A-Za-z]/;
36
+ export function keyOf(data) {
37
+ if (data === `${ESCAPE}[A`)
38
+ return "up";
39
+ if (data === `${ESCAPE}[B`)
40
+ return "down";
41
+ if (data === `${ESCAPE}[1;2A`)
42
+ return "latest";
43
+ if (data === `${ESCAPE}[1;2B`)
44
+ return "first";
45
+ if (data === "\r" || data === "\n")
46
+ return "toggle";
47
+ if (data === "+" || data === "=")
48
+ return "expand";
49
+ if (data === "-" || data === "_")
50
+ return "collapse";
51
+ if (data === "q" || data === INTERRUPT)
52
+ return "quit";
53
+ return undefined;
54
+ }
55
+ // Moving up runs out of log before it runs out of steps: the window climbs to
56
+ // the top of what this step printed, and only then does the cursor leave it
57
+ export function apply(model, key) {
58
+ const step = model.steps[model.cursor];
59
+ if (key === "latest") {
60
+ return { ...model, cursor: Math.max(0, model.steps.length - 1), following: true };
61
+ }
62
+ if (key === "first")
63
+ return { ...model, cursor: 0, following: false };
64
+ if (key === "up") {
65
+ if (step?.expanded && step.offset < Math.max(0, step.lines.length - 1)) {
66
+ return scrolled(model, step.offset + 1);
67
+ }
68
+ return { ...model, cursor: Math.max(0, model.cursor - 1), following: false };
69
+ }
70
+ if (key === "down") {
71
+ if (step?.expanded && step.offset > 0)
72
+ return scrolled(model, step.offset - 1);
73
+ const last = model.steps.length - 1;
74
+ const cursor = Math.max(0, Math.min(last, model.cursor + 1));
75
+ return { ...model, cursor, following: cursor === last };
76
+ }
77
+ if (key === "collapse") {
78
+ return {
79
+ ...model,
80
+ minimal: true,
81
+ steps: model.steps.map((item) => ({ ...item, expanded: false, held: false })),
82
+ };
83
+ }
84
+ // Anywhere, so a reader who collapsed everything does not have to find the
85
+ // running step before opening it again
86
+ if (key === "expand") {
87
+ const current = model.steps.length - 1;
88
+ return {
89
+ ...model,
90
+ minimal: false,
91
+ steps: model.steps.map((item, index) => index === current ? { ...item, expanded: true, held: true, offset: 0 } : item),
92
+ };
93
+ }
94
+ if (key === "toggle" && step) {
95
+ const opening = !step.expanded;
96
+ return {
97
+ ...model,
98
+ // Opening the running step is the same instruction as pressing plus
99
+ minimal: opening && model.cursor === model.steps.length - 1 ? false : model.minimal,
100
+ steps: model.steps.map((item, index) => index === model.cursor
101
+ ? { ...item, expanded: opening, held: opening, offset: 0 }
102
+ : item),
103
+ };
104
+ }
105
+ return model;
106
+ }
107
+ function scrolled(model, offset) {
108
+ return {
109
+ ...model,
110
+ steps: model.steps.map((item, index) => index === model.cursor ? { ...item, offset } : item),
111
+ };
112
+ }
113
+ // Colours are put on after every width is measured, because an escape is zero
114
+ // columns wide and a row measured with one in it is a row that wraps
115
+ const DIM = 90;
116
+ const CURSOR = 96;
117
+ const RUNNING = 93;
118
+ const DONE = 32;
119
+ const FAILED = 91;
120
+ const WARN = 33;
121
+ function paint(text, colour, on) {
122
+ if (!on || colour === undefined || text === "")
123
+ return text;
124
+ return `\u001b[${colour}m${text}\u001b[0m`;
125
+ }
126
+ function widthOf(pieces) {
127
+ return pieces.reduce((total, piece) => total + piece.text.length, 0);
128
+ }
129
+ // Clips the row as one string would clip, then hands each surviving piece its
130
+ // colour. The ellipsis belongs to whichever piece was cut
131
+ function clipped(pieces, room, on) {
132
+ if (widthOf(pieces) <= room) {
133
+ return pieces.map((piece) => paint(piece.text, piece.colour, on)).join("");
134
+ }
135
+ const kept = [];
136
+ let left = room - 1;
137
+ for (const piece of pieces) {
138
+ if (left <= 0)
139
+ break;
140
+ const text = piece.text.slice(0, left);
141
+ kept.push(paint(text, piece.colour, on));
142
+ left -= text.length;
143
+ }
144
+ return `${kept.join("")}\u2026`;
145
+ }
146
+ const FOOTER = 2;
147
+ // A step that is open but not the one being read shows this much of itself
148
+ const GLANCE = 6;
149
+ // What the focused step keeps even when everything else wants the room
150
+ const FLOOR = 3;
151
+ // How many of them the frame carries. Every message is written out again when
152
+ // the view closes, and a list that only grows crowds every log off the screen
153
+ const MESSAGES = 6;
154
+ export const HELP = "\u2191\u2193 move \u00b7 enter open \u00b7 shift+\u2191 latest \u00b7 + open \u00b7 - collapse all \u00b7 q quit";
155
+ export function render(model, colour = false) {
156
+ const body = Math.max(1, model.rows - FOOTER);
157
+ const rows = [];
158
+ const messages = model.messages.slice(-MESSAGES);
159
+ // More titles than the terminal has lines, so nothing can be open and the
160
+ // list itself is what scrolls
161
+ if (model.steps.length + messages.length > body) {
162
+ const start = Math.max(0, Math.min(model.cursor, model.steps.length - body));
163
+ for (const [index, step] of model.steps.entries()) {
164
+ if (index >= start && rows.length < body) {
165
+ rows.push(title(model, step, index, colour));
166
+ }
167
+ }
168
+ return finish(rows, body, colour);
169
+ }
170
+ const shown = share(model, body - model.steps.length - messages.length);
171
+ for (const [index, step] of model.steps.entries()) {
172
+ rows.push(title(model, step, index, colour));
173
+ rows.push(...logs(model, step, shown.get(index) ?? 0, colour));
174
+ }
175
+ for (const message of messages) {
176
+ rows.push(clipped([
177
+ { text: gutter(model), colour: DIM },
178
+ { text: " " },
179
+ { text: message, colour: WARN },
180
+ ], Math.max(24, model.columns), colour));
181
+ }
182
+ return finish(rows, body, colour);
183
+ }
184
+ // The focused step is the one being read, so it is served first and every other
185
+ // open one gets a glance out of what it did not need
186
+ function share(model, budget) {
187
+ const shown = new Map();
188
+ const open = model.steps
189
+ .map((step, index) => ({ step, index }))
190
+ .filter((item) => item.step.expanded);
191
+ const focused = open.find((item) => item.index === model.cursor);
192
+ const others = open.filter((item) => item.index !== model.cursor);
193
+ let left = Math.max(0, budget);
194
+ if (focused) {
195
+ // What the glances would actually cost, not what they could: a step that
196
+ // printed nothing reserves nothing, and served last the focused step used
197
+ // to be left with whatever the others happened not to want
198
+ const glances = others.reduce((total, item) => total + Math.min(GLANCE, item.step.lines.length), 0);
199
+ const reserve = Math.min(glances, Math.max(0, left - FLOOR));
200
+ const take = Math.min(left - reserve, focused.step.lines.length);
201
+ shown.set(focused.index, take);
202
+ left -= take;
203
+ }
204
+ for (const item of others) {
205
+ const take = Math.min(GLANCE, item.step.lines.length, Math.max(0, left));
206
+ shown.set(item.index, take);
207
+ left -= take;
208
+ }
209
+ return shown;
210
+ }
211
+ const RULE = " \u2502 ";
212
+ // The newest lines, less whatever the reader has scrolled back past. One line
213
+ // each: a wrapped line would push the rows below it off a frame sized in rows
214
+ function logs(model, step, take, colour) {
215
+ if (take <= 0)
216
+ return [];
217
+ const end = Math.max(1, step.lines.length - step.offset);
218
+ const room = Math.max(8, model.columns - RULE.length);
219
+ return step.lines
220
+ .slice(Math.max(0, end - take), end)
221
+ .map((line) => `${paint(RULE, DIM, colour)}${clip(line, room)}`);
222
+ }
223
+ // The ellipsis is the whole point: a line that was cut has to say so
224
+ export function clip(text, room) {
225
+ if (text.length <= room)
226
+ return text;
227
+ return `${text.slice(0, room - 1)}\u2026`;
228
+ }
229
+ function finish(rows, body, colour) {
230
+ const filled = rows.slice(0, body);
231
+ while (filled.length < body)
232
+ filled.push("");
233
+ return [...filled, "", paint(HELP, DIM, colour)];
234
+ }
235
+ function title(model, step, index, colour) {
236
+ const selected = index === model.cursor;
237
+ const caret = selected ? "\u276f" : " ";
238
+ const arrow = step.expanded ? "\u25be" : "\u25b8";
239
+ const glyph = step.state === "done" ? "\u2714" : step.state === "failed" ? "\u2718" : arrow;
240
+ const said = step.note ? `: ${step.note}` : step.detail ? ` ${step.detail}` : "";
241
+ const head = [
242
+ { text: gutter(model), colour: DIM },
243
+ { text: " " },
244
+ { text: caret, colour: selected ? CURSOR : undefined },
245
+ { text: " " },
246
+ { text: glyph, colour: stateColour(step) },
247
+ { text: " " },
248
+ { text: step.label, colour: labelColour(step, selected) },
249
+ { text: said, colour: DIM },
250
+ ];
251
+ // Frozen at what it cost the moment it finished, still counting until then
252
+ return fit(model, head, elapsed(step.ended ?? model.now, step.started), colour);
253
+ }
254
+ function stateColour(step) {
255
+ if (step.state === "done")
256
+ return DONE;
257
+ if (step.state === "failed")
258
+ return FAILED;
259
+ return RUNNING;
260
+ }
261
+ // A failure outranks everything: it is the row the reader is looking for. Then
262
+ // where the cursor is, then what is still running
263
+ function labelColour(step, selected) {
264
+ if (step.state === "failed")
265
+ return FAILED;
266
+ if (selected)
267
+ return CURSOR;
268
+ if (step.state === "running")
269
+ return RUNNING;
270
+ return undefined;
271
+ }
272
+ // The stamp is the whole run, and it keeps counting for every row a step adds
273
+ function gutter(model) {
274
+ return `[${elapsed(model.now, model.started, true)}]`;
275
+ }
276
+ export function elapsed(now, started, clock = false) {
277
+ const seconds = Math.max(0, Math.floor((now - started) / 1000));
278
+ const minutes = Math.floor(seconds / 60);
279
+ if (clock)
280
+ return `${pad(minutes)}:${pad(seconds % 60)}`;
281
+ if (seconds < 60)
282
+ return `${seconds}s`;
283
+ return `${minutes}m${pad(seconds % 60)}s`;
284
+ }
285
+ function pad(value) {
286
+ return String(value).padStart(2, "0");
287
+ }
288
+ // The timer is pushed to the right edge, and the label is what gives way when
289
+ // there is not room for both. One space between them always, which is a row
290
+ // wider than the terminal when the label is allowed to fill the gap
291
+ function fit(model, head, timer, colour) {
292
+ const width = Math.max(24, model.columns);
293
+ const room = width - timer.length - 1;
294
+ const shown = Math.min(widthOf(head), room - 1);
295
+ return (`${clipped(head, room - 1, colour)}` +
296
+ `${" ".repeat(Math.max(1, room - shown))} ${paint(timer, DIM, colour)}`);
297
+ }
298
+ //# sourceMappingURL=screen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screen.js","sourceRoot":"","sources":["../../src/cli/screen.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { Log } from "../log.js";
2
+ export type Viewer = Log & {
3
+ close(): void;
4
+ };
5
+ export type ViewerOptions = {
6
+ onQuit?: () => void;
7
+ };
8
+ export declare function createViewer(stream: NodeJS.WriteStream, input: NodeJS.ReadStream, options?: ViewerOptions): Viewer;
9
+ //# sourceMappingURL=viewer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"viewer.d.ts","sourceRoot":"","sources":["../../src/cli/viewer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAQ,MAAM,WAAW,CAAC;AAyB3C,MAAM,MAAM,MAAM,GAAG,GAAG,GAAG;IAGzB,KAAK,IAAI,IAAI,CAAC;CACf,CAAC;AAYF,MAAM,MAAM,aAAa,GAAG;IAG1B,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,CAAC,WAAW,EAC1B,KAAK,EAAE,MAAM,CAAC,UAAU,EACxB,OAAO,GAAE,aAAkB,GAC1B,MAAM,CA8HR"}
@@ -0,0 +1,139 @@
1
+ import { apply, elapsed, emptyModel, keysOf, render, } from "./screen.js";
2
+ // The terminal half: raw keys in, a frame out on a timer. Everything it decides
3
+ // lives in screen.ts, so this file is only the parts a test cannot run.
4
+ const FRAME_MS = 100;
5
+ const ALTERNATE_ON = "\u001b[?1049h\u001b[?25l";
6
+ const ALTERNATE_OFF = "\u001b[?25h\u001b[?1049l";
7
+ const HOME = "\u001b[H";
8
+ const CLEAR_LINE = "\u001b[K";
9
+ const CLEAR_BELOW = "\u001b[J";
10
+ // A build prints tens of thousands of lines and only the tail is ever read
11
+ const KEPT = 2000;
12
+ // A pty whose size nobody set answers 0 rather than nothing, and a view one row
13
+ // tall can only ever show the step the cursor is on
14
+ const ROWS = 24;
15
+ const COLUMNS = 80;
16
+ const sizeOf = (stream) => ({
17
+ rows: stream.rows && stream.rows > 4 ? stream.rows : ROWS,
18
+ columns: stream.columns && stream.columns > 20 ? stream.columns : COLUMNS,
19
+ });
20
+ export function createViewer(stream, input, options = {}) {
21
+ // NO_COLOR is a standing instruction rather than a preference to re-ask
22
+ // about, and a terminal that took the alternate screen still may not paint
23
+ const colour = !process.env["NO_COLOR"] && stream.isTTY === true;
24
+ const size = sizeOf(stream);
25
+ let model = emptyModel(size.rows, size.columns, Date.now());
26
+ let open = true;
27
+ const draw = () => {
28
+ if (!open)
29
+ return;
30
+ model = { ...model, now: Date.now(), ...sizeOf(stream) };
31
+ const rows = render(model, colour).map((row) => `${row}${CLEAR_LINE}`);
32
+ stream.write(`${HOME}${rows.join("\n")}${CLEAR_BELOW}`);
33
+ };
34
+ const change = (next) => {
35
+ model = next(model);
36
+ draw();
37
+ };
38
+ const timer = setInterval(draw, FRAME_MS);
39
+ timer.unref();
40
+ stream.write(ALTERNATE_ON);
41
+ if (input.isTTY)
42
+ input.setRawMode(true);
43
+ input.resume();
44
+ input.setEncoding("utf8");
45
+ const say = (message) => change((current) => ({ ...current, messages: [...current.messages, message] }));
46
+ const onKey = (data) => {
47
+ for (const key of keysOf(data)) {
48
+ // Not a return: two presses in one read are two asks, and the second one
49
+ // is what hardens the signal the first one sent
50
+ if (key === "quit")
51
+ quit();
52
+ else
53
+ change((current) => apply(current, key));
54
+ }
55
+ };
56
+ input.on("data", onKey);
57
+ const onResize = () => draw();
58
+ stream.on("resize", onResize);
59
+ const close = () => {
60
+ if (!open)
61
+ return;
62
+ open = false;
63
+ clearInterval(timer);
64
+ input.off("data", onKey);
65
+ stream.off("resize", onResize);
66
+ if (input.isTTY)
67
+ input.setRawMode(false);
68
+ input.pause();
69
+ stream.write(ALTERNATE_OFF);
70
+ // The alternate screen takes every frame with it, so the run has to be
71
+ // written again on the screen the person keeps
72
+ for (const line of summary(model))
73
+ stream.write(`${line}\n`);
74
+ };
75
+ // What a second press means is not the view's to decide: the same key
76
+ // arrives as a signal when there is no view, and one answer serves both
77
+ const quit = () => options.onQuit?.();
78
+ process.once("exit", () => open && stream.write(ALTERNATE_OFF));
79
+ const step = (label) => {
80
+ let index = 0;
81
+ change((current) => {
82
+ index = current.steps.length;
83
+ const started = {
84
+ label,
85
+ started: Date.now(),
86
+ state: "running",
87
+ lines: [],
88
+ // The one running is the one being read, unless the reader said no
89
+ expanded: !current.minimal,
90
+ held: false,
91
+ offset: 0,
92
+ };
93
+ return {
94
+ ...current,
95
+ steps: [...current.steps, started],
96
+ cursor: current.following ? index : current.cursor,
97
+ };
98
+ });
99
+ const edit = (change_) => change((current) => ({
100
+ ...current,
101
+ steps: current.steps.map((item, at) => (at === index ? change_(item) : item)),
102
+ }));
103
+ // A finished step shuts, so the list stays a list. One the reader opened by
104
+ // hand stays open: it is being read, and closing it would move the screen
105
+ const settle = (state, note) => edit((item) => ({
106
+ ...item,
107
+ state,
108
+ note,
109
+ detail: undefined,
110
+ ended: Date.now(),
111
+ expanded: item.held,
112
+ }));
113
+ return {
114
+ detail: (message) => edit((item) => ({ ...item, detail: message })),
115
+ line: (message) => edit((item) => ({ ...item, lines: [...item.lines, message].slice(-KEPT) })),
116
+ done: (message) => settle("done", message),
117
+ fail: (message) => settle("failed", message),
118
+ };
119
+ };
120
+ return Object.assign(say, {
121
+ warn: say,
122
+ fail: say,
123
+ done: say,
124
+ step,
125
+ close,
126
+ });
127
+ }
128
+ // One line per step and whatever was said outside them, which is the record a
129
+ // person scrolls back to after the deploy is over
130
+ function summary(model) {
131
+ const rows = model.steps.map((step) => {
132
+ const glyph = step.state === "done" ? "✔" : step.state === "failed" ? "✘" : "·";
133
+ const said = step.note ? `: ${step.note}` : "";
134
+ const took = elapsed(step.ended ?? model.now, step.started);
135
+ return `${glyph} ${step.label}${said} (${took})`;
136
+ });
137
+ return [...rows, ...model.messages];
138
+ }
139
+ //# sourceMappingURL=viewer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"viewer.js","sourceRoot":"","sources":["../../src/cli/viewer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { Deployment, Environment } from "./types.js";
2
+ export declare function environmentOf(config: Deployment, name: string): Environment | undefined;
3
+ export declare function defineDeployment<const T extends Deployment & {
4
+ environments?: never;
5
+ }>(config: T): T;
6
+ export declare function defineEnvironment<const T extends Environment>(environment: T): T;
7
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAK1D,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,2BAE7D;AAMD,wBAAgB,gBAAgB,CAAC,KAAK,CAAC,CAAC,SAAS,UAAU,GAAG;IAAE,YAAY,CAAC,EAAE,KAAK,CAAA;CAAE,EACpF,MAAM,EAAE,CAAC,GACR,CAAC,CAOH;AAID,wBAAgB,iBAAiB,CAAC,KAAK,CAAC,CAAC,SAAS,WAAW,EAAE,WAAW,EAAE,CAAC,GAAG,CAAC,CAEhF"}
package/dist/config.js ADDED
@@ -0,0 +1,79 @@
1
+ import { assertSteps } from "./pipeline.js";
2
+ // The one selected, from the one place worth looking. A deployment that carries
3
+ // its own overrides every file, which is what makes it an override rather than
4
+ // a default nobody can displace
5
+ export function environmentOf(config, name) {
6
+ return config.environment ?? config.environments?.[name];
7
+ }
8
+ // Identity, but it pins the type so a missing health predicate fails to
9
+ // compile. Environments are excluded rather than merely unused: each lives in
10
+ // a redkite.<name>.config.ts of its own, and a second place to put one is a
11
+ // second place for them to disagree
12
+ export function defineDeployment(config) {
13
+ assertUniqueNames(config);
14
+ assertOneSource(config);
15
+ assertRoutesResolvable(config);
16
+ assertDirsRelative(config);
17
+ assertSteps(config.steps ?? []);
18
+ return config;
19
+ }
20
+ // Identity, for the environment a redkite.<name>.config.ts holds. It pins the
21
+ // type the same way defineDeployment does, so a missing subnet fails to compile
22
+ export function defineEnvironment(environment) {
23
+ return environment;
24
+ }
25
+ // Cloned or already here, and the two are built differently enough that
26
+ // guessing between them is worse than being told
27
+ function assertOneSource(config) {
28
+ for (const app of config.apps) {
29
+ if (app.repo && app.path) {
30
+ throw new Error(`${app.name} names both a repo and a path, and is built from one of them`);
31
+ }
32
+ if (!app.repo && !app.path) {
33
+ throw new Error(`${app.name} names no source, so give it a repo to clone or a path to build`);
34
+ }
35
+ // A clone is whatever the repository holds, so there is nothing here to
36
+ // narrow and an include would quietly do nothing
37
+ if (app.include && !app.path) {
38
+ throw new Error(`${app.name} says what to include, but is cloned rather than built from a path`);
39
+ }
40
+ if (app.include?.length === 0) {
41
+ throw new Error(`${app.name} includes nothing, so there would be no build context`);
42
+ }
43
+ }
44
+ }
45
+ // A dir is joined onto /app inside the image, so an absolute one would render
46
+ // a path with two slashes and a climbing one would leave the checkout
47
+ function assertDirsRelative(config) {
48
+ for (const app of config.apps) {
49
+ const dir = app.dir;
50
+ if (dir === undefined)
51
+ continue;
52
+ if (!dir || dir.startsWith("/") || dir.endsWith("/")) {
53
+ throw new Error(`dir for ${app.name} must be a path inside the repository`);
54
+ }
55
+ if (dir.split("/").includes("..")) {
56
+ throw new Error(`dir for ${app.name} must not climb out of the repository`);
57
+ }
58
+ }
59
+ }
60
+ function assertUniqueNames(config) {
61
+ const names = [...config.apps, ...config.services].map((item) => item.name);
62
+ const duplicate = names.find((name, i) => names.indexOf(name) !== i);
63
+ if (duplicate)
64
+ throw new Error(`Duplicate name in deployment: ${duplicate}`);
65
+ }
66
+ // Two apps on the same route means one of them is unreachable, and which one
67
+ // depends on nginx location precedence rather than on anything written here
68
+ function assertRoutesResolvable(config) {
69
+ const routes = config.apps.map((app) => app.route);
70
+ const duplicate = routes.find((route, i) => routes.indexOf(route) !== i);
71
+ if (duplicate)
72
+ throw new Error(`Two apps share the route ${duplicate}`);
73
+ for (const app of config.apps) {
74
+ if (app.route.startsWith("/"))
75
+ continue;
76
+ throw new Error(`Route for ${app.name} must start with a slash`);
77
+ }
78
+ }
79
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { type HealthDeps } from "./health.js";
2
+ import type { Host } from "./host.js";
3
+ import { type Log } from "./log.js";
4
+ import { type Finished } from "./pipeline.js";
5
+ import { type SecretStores } from "./secrets/refs.js";
6
+ import type { Deployment } from "./types.js";
7
+ export type DeployOptions = {
8
+ config: Deployment;
9
+ environment: string;
10
+ host: Host;
11
+ secrets: SecretStores;
12
+ health?: Omit<HealthDeps, "probe">;
13
+ log?: Log;
14
+ verbose?: boolean;
15
+ signal?: AbortSignal;
16
+ };
17
+ export declare function deploy(options: DeployOptions): Promise<Finished>;
18
+ export declare function verify(options: DeployOptions): Promise<Finished>;
19
+ //# sourceMappingURL=deploy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../src/deploy.ts"],"names":[],"mappings":"AAIA,OAAO,EAAe,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,EAAU,KAAK,GAAG,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAQL,KAAK,QAAQ,EAMd,MAAM,eAAe,CAAC;AACvB,OAAO,EAAoB,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAIxE,OAAO,KAAK,EAAW,UAAU,EAAE,MAAM,YAAY,CAAC;AAWtD,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,UAAU,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IAEpB,IAAI,EAAE,IAAI,CAAC;IAEX,OAAO,EAAE,YAAY,CAAC;IAGtB,MAAM,CAAC,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACnC,GAAG,CAAC,EAAE,GAAG,CAAC;IAEV,OAAO,CAAC,EAAE,OAAO,CAAC;IAGlB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,CAAC;AAEF,wBAAsB,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,QAAQ,CAAC,CAEtE;AAID,wBAAsB,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,QAAQ,CAAC,CAEtE"}