@devtion/devcli 0.0.0-004e6ad

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 (56) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +120 -0
  3. package/dist/.env +55 -0
  4. package/dist/index.js +3635 -0
  5. package/dist/public/mini-semaphore.wasm +0 -0
  6. package/dist/public/mini-semaphore.zkey +0 -0
  7. package/dist/types/commands/auth.d.ts +25 -0
  8. package/dist/types/commands/authBandada.d.ts +2 -0
  9. package/dist/types/commands/authSIWE.d.ts +7 -0
  10. package/dist/types/commands/ceremony/index.d.ts +3 -0
  11. package/dist/types/commands/ceremony/listParticipants.d.ts +2 -0
  12. package/dist/types/commands/clean.d.ts +6 -0
  13. package/dist/types/commands/contribute.d.ts +139 -0
  14. package/dist/types/commands/finalize.d.ts +52 -0
  15. package/dist/types/commands/index.d.ts +11 -0
  16. package/dist/types/commands/listCeremonies.d.ts +5 -0
  17. package/dist/types/commands/logout.d.ts +6 -0
  18. package/dist/types/commands/observe.d.ts +22 -0
  19. package/dist/types/commands/setup.d.ts +86 -0
  20. package/dist/types/commands/validate.d.ts +8 -0
  21. package/dist/types/index.d.ts +2 -0
  22. package/dist/types/lib/bandada.d.ts +6 -0
  23. package/dist/types/lib/errors.d.ts +60 -0
  24. package/dist/types/lib/files.d.ts +65 -0
  25. package/dist/types/lib/localConfigs.d.ts +148 -0
  26. package/dist/types/lib/prompts.d.ts +104 -0
  27. package/dist/types/lib/services.d.ts +31 -0
  28. package/dist/types/lib/theme.d.ts +42 -0
  29. package/dist/types/lib/utils.d.ts +159 -0
  30. package/dist/types/types/index.d.ts +134 -0
  31. package/package.json +108 -0
  32. package/src/commands/auth.ts +214 -0
  33. package/src/commands/authBandada.ts +120 -0
  34. package/src/commands/authSIWE.ts +185 -0
  35. package/src/commands/ceremony/index.ts +20 -0
  36. package/src/commands/ceremony/listParticipants.ts +56 -0
  37. package/src/commands/clean.ts +49 -0
  38. package/src/commands/contribute.ts +1116 -0
  39. package/src/commands/finalize.ts +395 -0
  40. package/src/commands/index.ts +11 -0
  41. package/src/commands/listCeremonies.ts +31 -0
  42. package/src/commands/logout.ts +69 -0
  43. package/src/commands/observe.ts +197 -0
  44. package/src/commands/setup.ts +912 -0
  45. package/src/commands/validate.ts +28 -0
  46. package/src/index.ts +88 -0
  47. package/src/lib/bandada.ts +51 -0
  48. package/src/lib/errors.ts +77 -0
  49. package/src/lib/files.ts +102 -0
  50. package/src/lib/localConfigs.ts +240 -0
  51. package/src/lib/prompts.ts +745 -0
  52. package/src/lib/services.ts +214 -0
  53. package/src/lib/theme.ts +45 -0
  54. package/src/lib/utils.ts +813 -0
  55. package/src/types/conf.d.ts +16 -0
  56. package/src/types/index.ts +145 -0
@@ -0,0 +1,197 @@
1
+ #!/usr/bin/env node
2
+
3
+ import {
4
+ FirebaseDocumentInfo,
5
+ getCeremonyCircuits,
6
+ getCircuitContributionsFromContributor,
7
+ getOpenedCeremonies,
8
+ isCoordinator,
9
+ convertToDoubleDigits
10
+ } from "@devtion/actions"
11
+ import { Firestore } from "firebase/firestore"
12
+ import logSymbols from "log-symbols"
13
+ import readline from "readline"
14
+ import { COMMAND_ERRORS, GENERIC_ERRORS, showError } from "../lib/errors.js"
15
+ import { promptForCeremonySelection } from "../lib/prompts.js"
16
+ import { bootstrapCommandExecutionAndServices, checkAuth } from "../lib/services.js"
17
+ import theme from "../lib/theme.js"
18
+ import { customSpinner, getSecondsMinutesHoursFromMillis, sleep } from "../lib/utils.js"
19
+
20
+ /**
21
+ * Clean cursor lines from current position back to root (default: zero).
22
+ * @param currentCursorPos - the current position of the cursor.
23
+ * @returns <number>
24
+ */
25
+ export const cleanCursorPosBackToRoot = (currentCursorPos: number) => {
26
+ while (currentCursorPos < 0) {
27
+ // Get back and clean line by line.
28
+ readline.cursorTo(process.stdout, 0)
29
+ readline.clearLine(process.stdout, 0)
30
+ readline.moveCursor(process.stdout, -1, -1)
31
+
32
+ currentCursorPos += 1
33
+ }
34
+
35
+ return currentCursorPos
36
+ }
37
+
38
+ /**
39
+ * Show the latest updates for the given circuit.
40
+ * @param firestoreDatabase <Firestore> - the Firestore database to query from.
41
+ * @param ceremony <FirebaseDocumentInfo> - the Firebase document containing info about the ceremony.
42
+ * @param circuit <FirebaseDocumentInfo> - the Firebase document containing info about the circuit.
43
+ * @returns Promise<number> return the current position of the cursor (i.e., number of lines displayed).
44
+ */
45
+ export const displayLatestCircuitUpdates = async (
46
+ firestoreDatabase: Firestore,
47
+ ceremony: FirebaseDocumentInfo,
48
+ circuit: FirebaseDocumentInfo
49
+ ): Promise<number> => {
50
+ let observation = theme.text.bold(`- Circuit # ${theme.colors.magenta(circuit.data.sequencePosition)}`) // Observation output.
51
+ let cursorPos = -1 // Current cursor position (nb. decrease every time there's a new line!).
52
+
53
+ const { waitingQueue } = circuit.data
54
+
55
+ // Get info from circuit.
56
+ const { currentContributor } = waitingQueue
57
+ const { completedContributions } = waitingQueue
58
+
59
+ if (!currentContributor) {
60
+ observation += `\n> Nobody's currently waiting to contribute ${theme.emojis.eyes}`
61
+ cursorPos -= 1
62
+ } else {
63
+ // Search for currentContributor' contribution.
64
+ const contributions = await getCircuitContributionsFromContributor(
65
+ firestoreDatabase,
66
+ ceremony.id,
67
+ circuit.id,
68
+ currentContributor
69
+ )
70
+
71
+ if (!contributions.length) {
72
+ // The contributor is currently contributing.
73
+ observation += `\n> Participant ${theme.text.bold(`#${completedContributions + 1}`)} (${theme.text.bold(
74
+ currentContributor
75
+ )}) is currently contributing ${theme.emojis.fire}`
76
+
77
+ cursorPos -= 1
78
+ } else {
79
+ // The contributor has contributed.
80
+ observation += `\n> Participant ${theme.text.bold(`#${completedContributions}`)} (${theme.text.bold(
81
+ currentContributor
82
+ )}) has completed the contribution ${theme.emojis.tada}`
83
+
84
+ cursorPos -= 1
85
+
86
+ // The contributor has finished the contribution.
87
+ const contributionData = contributions.at(0)?.data
88
+
89
+ if (!contributionData) showError(GENERIC_ERRORS.GENERIC_ERROR_RETRIEVING_DATA, true)
90
+
91
+ // Convert times to seconds.
92
+ const {
93
+ seconds: contributionTimeSeconds,
94
+ minutes: contributionTimeMinutes,
95
+ hours: contributionTimeHours
96
+ } = getSecondsMinutesHoursFromMillis(contributionData?.contributionComputationTime)
97
+ const {
98
+ seconds: verificationTimeSeconds,
99
+ minutes: verificationTimeMinutes,
100
+ hours: verificationTimeHours
101
+ } = getSecondsMinutesHoursFromMillis(contributionData?.verificationComputationTime)
102
+
103
+ observation += `\n> The ${theme.text.bold("computation")} took ${theme.text.bold(
104
+ `${convertToDoubleDigits(contributionTimeHours)}:${convertToDoubleDigits(
105
+ contributionTimeMinutes
106
+ )}:${convertToDoubleDigits(contributionTimeSeconds)}`
107
+ )}`
108
+ observation += `\n> The ${theme.text.bold("verification")} took ${theme.text.bold(
109
+ `${convertToDoubleDigits(verificationTimeHours)}:${convertToDoubleDigits(
110
+ verificationTimeMinutes
111
+ )}:${convertToDoubleDigits(verificationTimeSeconds)}`
112
+ )}`
113
+ observation += `\n> Contribution ${
114
+ contributionData?.valid
115
+ ? `${theme.text.bold("VALID")} ${theme.symbols.success}`
116
+ : `${theme.text.bold("INVALID")} ${theme.symbols.error}`
117
+ }`
118
+
119
+ cursorPos -= 3
120
+ }
121
+ }
122
+
123
+ // Show observation for circuit.
124
+ process.stdout.write(`${observation}\n\n`)
125
+ cursorPos -= 1
126
+
127
+ return cursorPos
128
+ }
129
+
130
+ /**
131
+ * Observe command.
132
+ */
133
+ const observe = async () => {
134
+ // @todo to be moved as command configuration parameter.
135
+ const observationWaitingTimeInMillis = 3000
136
+ try {
137
+ // Initialize services.
138
+ const { firebaseApp, firestoreDatabase } = await bootstrapCommandExecutionAndServices()
139
+
140
+ // Handle current authenticated user sign in.
141
+ const { user } = await checkAuth(firebaseApp)
142
+
143
+ // Preserve command execution only for coordinators].
144
+ if (!(await isCoordinator(user))) showError(COMMAND_ERRORS.COMMAND_NOT_COORDINATOR, true)
145
+
146
+ // Get running ceremonies info (if any).
147
+ const runningCeremoniesDocs = await getOpenedCeremonies(firestoreDatabase)
148
+
149
+ // Ask to select a ceremony.
150
+ const ceremony = await promptForCeremonySelection(
151
+ runningCeremoniesDocs,
152
+ false,
153
+ "Which ceremony would you like to observe?"
154
+ )
155
+
156
+ console.log(`${logSymbols.info} Refresh rate set to ~3 seconds for waiting queue updates\n`)
157
+
158
+ let cursorPos = 0 // Keep track of current cursor position.
159
+
160
+ const spinner = customSpinner(`Getting ready...`, "clock")
161
+ spinner.start()
162
+
163
+ // Get circuit updates every 3 seconds.
164
+ setInterval(async () => {
165
+ // Clean cursor position back to root.
166
+ cursorPos = cleanCursorPosBackToRoot(cursorPos)
167
+
168
+ spinner.stop()
169
+
170
+ spinner.text = `Updating...`
171
+ spinner.start()
172
+
173
+ // Get updates from circuits.
174
+ const circuits = await getCeremonyCircuits(firestoreDatabase, ceremony.id)
175
+
176
+ await sleep(observationWaitingTimeInMillis / 10) // Just for a smoother UX/UI experience.
177
+
178
+ spinner.stop()
179
+
180
+ // Observe changes for each circuit
181
+ for await (const circuit of circuits)
182
+ cursorPos += await displayLatestCircuitUpdates(firestoreDatabase, ceremony, circuit)
183
+
184
+ process.stdout.write(`Press CTRL+C to exit`)
185
+
186
+ await sleep(1000) // Just for a smoother UX/UI experience.
187
+ }, observationWaitingTimeInMillis)
188
+
189
+ await sleep(observationWaitingTimeInMillis) // Wait until the first update.
190
+
191
+ spinner.stop()
192
+ } catch (err: any) {
193
+ showError(`Something went wrong: ${err.toString()}`, true)
194
+ }
195
+ }
196
+
197
+ export default observe