@devtion/devcli 0.0.0-7e983e3

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 (44) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +118 -0
  3. package/dist/.env +41 -0
  4. package/dist/index.js +3206 -0
  5. package/dist/types/commands/auth.d.ts +25 -0
  6. package/dist/types/commands/clean.d.ts +6 -0
  7. package/dist/types/commands/contribute.d.ts +139 -0
  8. package/dist/types/commands/finalize.d.ts +51 -0
  9. package/dist/types/commands/index.d.ts +9 -0
  10. package/dist/types/commands/listCeremonies.d.ts +5 -0
  11. package/dist/types/commands/logout.d.ts +6 -0
  12. package/dist/types/commands/observe.d.ts +22 -0
  13. package/dist/types/commands/setup.d.ts +86 -0
  14. package/dist/types/commands/validate.d.ts +8 -0
  15. package/dist/types/index.d.ts +2 -0
  16. package/dist/types/lib/errors.d.ts +60 -0
  17. package/dist/types/lib/files.d.ts +64 -0
  18. package/dist/types/lib/localConfigs.d.ts +110 -0
  19. package/dist/types/lib/prompts.d.ts +104 -0
  20. package/dist/types/lib/services.d.ts +31 -0
  21. package/dist/types/lib/theme.d.ts +42 -0
  22. package/dist/types/lib/utils.d.ts +158 -0
  23. package/dist/types/types/index.d.ts +65 -0
  24. package/package.json +100 -0
  25. package/src/commands/auth.ts +194 -0
  26. package/src/commands/clean.ts +49 -0
  27. package/src/commands/contribute.ts +1090 -0
  28. package/src/commands/finalize.ts +382 -0
  29. package/src/commands/index.ts +9 -0
  30. package/src/commands/listCeremonies.ts +32 -0
  31. package/src/commands/logout.ts +67 -0
  32. package/src/commands/observe.ts +193 -0
  33. package/src/commands/setup.ts +901 -0
  34. package/src/commands/validate.ts +29 -0
  35. package/src/index.ts +66 -0
  36. package/src/lib/errors.ts +77 -0
  37. package/src/lib/files.ts +102 -0
  38. package/src/lib/localConfigs.ts +186 -0
  39. package/src/lib/prompts.ts +748 -0
  40. package/src/lib/services.ts +191 -0
  41. package/src/lib/theme.ts +45 -0
  42. package/src/lib/utils.ts +778 -0
  43. package/src/types/conf.d.ts +16 -0
  44. package/src/types/index.ts +70 -0
@@ -0,0 +1,191 @@
1
+ import {
2
+ getCurrentFirebaseAuthUser,
3
+ initializeFirebaseCoreServices,
4
+ signInToFirebaseWithCredentials
5
+ } from "@p0tion/actions"
6
+ import clear from "clear"
7
+ import figlet from "figlet"
8
+ import { FirebaseApp } from "firebase/app"
9
+ import { OAuthCredential } from "firebase/auth"
10
+ import dotenv from "dotenv"
11
+ import { fileURLToPath } from "url"
12
+ import { dirname } from "path"
13
+ import { AuthUser } from "../types/index.js"
14
+ import { CONFIG_ERRORS, CORE_SERVICES_ERRORS, showError, THIRD_PARTY_SERVICES_ERRORS } from "./errors.js"
15
+ import { checkLocalAccessToken, deleteLocalAccessToken, getLocalAccessToken } from "./localConfigs.js"
16
+ import theme from "./theme.js"
17
+ import { exchangeGithubTokenForCredentials, getGithubProviderUserId, getUserHandleFromProviderUserId } from "./utils.js"
18
+
19
+ const packagePath = `${dirname(fileURLToPath(import.meta.url))}`
20
+ dotenv.config({
21
+ path: packagePath.includes(`src/lib`)
22
+ ? `${dirname(fileURLToPath(import.meta.url))}/../../.env`
23
+ : `${dirname(fileURLToPath(import.meta.url))}/.env`
24
+ })
25
+
26
+ /**
27
+ * Bootstrap services and configs is needed for a new command execution and related services.
28
+ * @returns <Promise<FirebaseServices>>
29
+ */
30
+ export const bootstrapCommandExecutionAndServices = async (): Promise<any> => {
31
+ // Clean terminal window.
32
+ clear()
33
+
34
+ // Print header.
35
+ console.log(theme.colors.magenta(figlet.textSync("Phase 2 cli", { font: "Ogre" })))
36
+
37
+ // Check configs.
38
+ if (!process.env.AUTH_GITHUB_CLIENT_ID) showError(CONFIG_ERRORS.CONFIG_GITHUB_ERROR, true)
39
+ if (
40
+ !process.env.FIREBASE_API_KEY ||
41
+ !process.env.FIREBASE_AUTH_DOMAIN ||
42
+ !process.env.FIREBASE_PROJECT_ID ||
43
+ !process.env.FIREBASE_MESSAGING_SENDER_ID ||
44
+ !process.env.FIREBASE_APP_ID ||
45
+ !process.env.FIREBASE_CF_URL_VERIFY_CONTRIBUTION
46
+ )
47
+ showError(CONFIG_ERRORS.CONFIG_FIREBASE_ERROR, true)
48
+ if (
49
+ !process.env.CONFIG_STREAM_CHUNK_SIZE_IN_MB ||
50
+ !process.env.CONFIG_CEREMONY_BUCKET_POSTFIX ||
51
+ !process.env.CONFIG_PRESIGNED_URL_EXPIRATION_IN_SECONDS
52
+ )
53
+ showError(CONFIG_ERRORS.CONFIG_OTHER_ERROR, true)
54
+
55
+ // Initialize and return Firebase services instances (App, Firestore, Functions)
56
+ return initializeFirebaseCoreServices(
57
+ String(process.env.FIREBASE_API_KEY),
58
+ String(process.env.FIREBASE_AUTH_DOMAIN),
59
+ String(process.env.FIREBASE_PROJECT_ID),
60
+ String(process.env.FIREBASE_MESSAGING_SENDER_ID),
61
+ String(process.env.FIREBASE_APP_ID)
62
+ )
63
+ }
64
+
65
+ /**
66
+ * Execute the sign in to Firebase using OAuth credentials.
67
+ * @dev wrapper method to handle custom errors.
68
+ * @param firebaseApp <FirebaseApp> - the configured instance of the Firebase App in use.
69
+ * @param credentials <OAuthCredential> - the OAuth credential generated from token exchange.
70
+ * @returns <Promise<void>>
71
+ */
72
+ export const signInToFirebase = async (firebaseApp: FirebaseApp, credentials: OAuthCredential): Promise<void> => {
73
+ try {
74
+ // Sign in with credentials to Firebase.
75
+ await signInToFirebaseWithCredentials(firebaseApp, credentials)
76
+ } catch (error: any) {
77
+ // Error handling by parsing error message.
78
+ if (error.toString().includes("Firebase: Unsuccessful check authorization response from Github")) {
79
+ showError(CORE_SERVICES_ERRORS.FIREBASE_TOKEN_EXPIRED_REMOVED_PERMISSIONS, false)
80
+
81
+ // Clean expired access token from local storage.
82
+ deleteLocalAccessToken()
83
+
84
+ // Inform user.
85
+ console.log(
86
+ `${theme.symbols.info} We have successfully removed your local token to make you able to repeat the authorization process once again. Please, run the auth command again whenever you are ready and complete the association with the CLI application.`
87
+ )
88
+
89
+ // Gracefully exit.
90
+ process.exit(0)
91
+ }
92
+
93
+ if (error.toString().includes("Firebase: Error (auth/user-disabled)"))
94
+ showError(CORE_SERVICES_ERRORS.FIREBASE_USER_DISABLED, true)
95
+
96
+ if (
97
+ error
98
+ .toString()
99
+ .includes("Firebase: Remote site 5XX from github.com for VERIFY_CREDENTIAL (auth/invalid-credential)")
100
+ )
101
+ showError(CORE_SERVICES_ERRORS.FIREBASE_FAILED_CREDENTIALS_VERIFICATION, true)
102
+
103
+ if (error.toString().includes("Firebase: Error (auth/network-request-failed)"))
104
+ showError(CORE_SERVICES_ERRORS.FIREBASE_NETWORK_ERROR, true)
105
+
106
+ if (error.toString().includes("HttpError: The authorization request was denied"))
107
+ showError(THIRD_PARTY_SERVICES_ERRORS.GITHUB_ACCOUNT_ASSOCIATION_REJECTED, true)
108
+
109
+ if (
110
+ error
111
+ .toString()
112
+ .includes(
113
+ "HttpError: request to https://github.com/login/device/code failed, reason: connect ETIMEDOUT"
114
+ )
115
+ )
116
+ showError(THIRD_PARTY_SERVICES_ERRORS.GITHUB_SERVER_TIMEDOUT, true)
117
+ }
118
+ }
119
+
120
+
121
+
122
+ /**
123
+ * Ensure that the callee is an authenticated user.
124
+ * @notice The token will be passed as parameter.
125
+ * @dev This method can be used within GitHub actions or other CI/CD pipelines.
126
+ * @param firebaseApp <FirebaseApp> - the configured instance of the Firebase App in use.
127
+ * @param token <string> - the token to be used for authentication.
128
+ * @returns <Promise<AuthUser>> - a custom object containing info about the authenticated user, the token and github handle.
129
+ */
130
+ export const authWithToken = async (firebaseApp: FirebaseApp, token: string): Promise<AuthUser> => {
131
+ // Get credentials.
132
+ const credentials = exchangeGithubTokenForCredentials(token)
133
+
134
+ // Sign in to Firebase using credentials.
135
+ await signInToFirebase(firebaseApp, credentials)
136
+
137
+ // Get current authenticated user.
138
+ const user = getCurrentFirebaseAuthUser(firebaseApp)
139
+
140
+ // Get Github unique identifier (handle-id).
141
+ const providerUserId = await getGithubProviderUserId(String(token))
142
+
143
+ // Greet the user.
144
+ console.log(
145
+ `Greetings, @${theme.text.bold(getUserHandleFromProviderUserId(providerUserId))} ${theme.emojis.wave}\n`
146
+ )
147
+
148
+ return {
149
+ user,
150
+ token,
151
+ providerUserId
152
+ }
153
+ }
154
+
155
+ /**
156
+ * Ensure that the callee is an authenticated user.
157
+ * @dev This method MUST be executed before each command to avoid authentication errors when interacting with the command.
158
+ * @returns <Promise<AuthUser>> - a custom object containing info about the authenticated user, the token and github handle.
159
+ */
160
+ export const checkAuth = async (firebaseApp: FirebaseApp): Promise<AuthUser> => {
161
+ // Check for local token.
162
+ const isLocalTokenStored = checkLocalAccessToken()
163
+
164
+ if (!isLocalTokenStored) showError(THIRD_PARTY_SERVICES_ERRORS.GITHUB_NOT_AUTHENTICATED, true)
165
+
166
+ // Retrieve local access token.
167
+ const token = String(getLocalAccessToken())
168
+
169
+ // Get credentials.
170
+ const credentials = exchangeGithubTokenForCredentials(token)
171
+
172
+ // Sign in to Firebase using credentials.
173
+ await signInToFirebase(firebaseApp, credentials)
174
+
175
+ // Get current authenticated user.
176
+ const user = getCurrentFirebaseAuthUser(firebaseApp)
177
+
178
+ // Get Github unique identifier (handle-id).
179
+ const providerUserId = await getGithubProviderUserId(String(token))
180
+
181
+ // Greet the user.
182
+ console.log(
183
+ `Greetings, @${theme.text.bold(getUserHandleFromProviderUserId(providerUserId))} ${theme.emojis.wave}\n`
184
+ )
185
+
186
+ return {
187
+ user,
188
+ token,
189
+ providerUserId
190
+ }
191
+ }
@@ -0,0 +1,45 @@
1
+ import chalk from "chalk"
2
+ import logSymbols from "log-symbols"
3
+ import emoji from "node-emoji"
4
+
5
+ /**
6
+ * Custom theme object.
7
+ */
8
+ export default {
9
+ colors: {
10
+ yellow: chalk.yellow,
11
+ magenta: chalk.magenta,
12
+ red: chalk.red,
13
+ green: chalk.green
14
+ },
15
+ text: {
16
+ underlined: chalk.underline,
17
+ bold: chalk.bold,
18
+ italic: chalk.italic
19
+ },
20
+ symbols: {
21
+ success: logSymbols.success,
22
+ warning: logSymbols.warning,
23
+ error: logSymbols.error,
24
+ info: logSymbols.info
25
+ },
26
+ emojis: {
27
+ tada: emoji.get("tada"),
28
+ key: emoji.get("key"),
29
+ broom: emoji.get("broom"),
30
+ pointDown: emoji.get("point_down"),
31
+ eyes: emoji.get("eyes"),
32
+ wave: emoji.get("wave"),
33
+ clipboard: emoji.get("clipboard"),
34
+ fire: emoji.get("fire"),
35
+ clock: emoji.get("hourglass"),
36
+ dizzy: emoji.get("dizzy_face"),
37
+ rocket: emoji.get("rocket"),
38
+ oldKey: emoji.get("old_key"),
39
+ pray: emoji.get("pray"),
40
+ moon: emoji.get("moon"),
41
+ upsideDown: emoji.get("upside_down_face"),
42
+ arrowUp: emoji.get("arrow_up"),
43
+ arrowDown: emoji.get("arrow_down")
44
+ }
45
+ }