eitri-cli 1.38.0-beta.9 → 1.39.0-beta.1

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 (95) hide show
  1. package/.husky/pre-commit +0 -0
  2. package/eitri-cli-v2/eitri-cli-v2.darwin-arm64.node +0 -0
  3. package/eitri-cli-v2/eitri-cli-v2.darwin-x64.node +0 -0
  4. package/eitri-cli-v2/eitri-cli-v2.linux-x64-gnu.node +0 -0
  5. package/eitri-cli-v2/eitri-cli-v2.win32-x64-msvc.node +0 -0
  6. package/eitri-cli-v2/index.d.ts +11 -1
  7. package/index.js +4 -21
  8. package/package.json +3 -49
  9. package/src/modules/app/AppCommand.js +1 -1
  10. package/src/modules/vegvisir/VegvisirCommand.js +7 -13
  11. package/.eslintrc.json +0 -26
  12. package/.prettierrc +0 -6
  13. package/src/cmd/clean.js +0 -144
  14. package/src/cmd/create.js +0 -332
  15. package/src/cmd/credentials.js +0 -105
  16. package/src/cmd/doctor.js +0 -70
  17. package/src/cmd/invite.js +0 -87
  18. package/src/cmd/list.js +0 -36
  19. package/src/cmd/login.js +0 -70
  20. package/src/cmd/loginV2.js +0 -89
  21. package/src/cmd/manage-env.js +0 -129
  22. package/src/cmd/open-share.js +0 -6
  23. package/src/cmd/order-details.js +0 -6
  24. package/src/cmd/push-version.js +0 -260
  25. package/src/cmd/show-message-if-outdated-package.js +0 -32
  26. package/src/cmd/signup.js +0 -71
  27. package/src/cmd/start.js +0 -181
  28. package/src/cmd/tail-logs.js +0 -26
  29. package/src/cmd/test-initialization-params.js +0 -6
  30. package/src/cmd/validate.js +0 -164
  31. package/src/cmd/version.js +0 -18
  32. package/src/enum/WatcherOpts.js +0 -3
  33. package/src/enum/target.js +0 -6
  34. package/src/helpers/request-listener-helper.js +0 -55
  35. package/src/model/EitriAppType.js +0 -4
  36. package/src/model/Payload.js +0 -45
  37. package/src/model/Target.js +0 -61
  38. package/src/model/User.js +0 -11
  39. package/src/service/AuthConfig.js +0 -85
  40. package/src/service/BlindGuardian.js +0 -131
  41. package/src/service/CliLogin.js +0 -52
  42. package/src/service/ConfigService.js +0 -9
  43. package/src/service/CredentialsService.js +0 -47
  44. package/src/service/EitriAppManager.js +0 -32
  45. package/src/service/EitriAppService.js +0 -49
  46. package/src/service/Emulator/AndroidEmulatorService.js +0 -132
  47. package/src/service/Emulator/IOSEmulatorService.js +0 -71
  48. package/src/service/EmulatorService.js +0 -17
  49. package/src/service/GATrackingStrategy.js +0 -16
  50. package/src/service/HashFolder.js +0 -79
  51. package/src/service/Http.js +0 -300
  52. package/src/service/HuginService.js +0 -38
  53. package/src/service/InviteService.js +0 -45
  54. package/src/service/LibsService.js +0 -191
  55. package/src/service/ManageEnvService.js +0 -10
  56. package/src/service/MiniLog.js +0 -166
  57. package/src/service/PrerequisitesValidator.js +0 -99
  58. package/src/service/QRCodeFactory.js +0 -81
  59. package/src/service/ReleaseService.js +0 -126
  60. package/src/service/Server.js +0 -220
  61. package/src/service/StarterService.js +0 -31
  62. package/src/service/TagTree.js +0 -101
  63. package/src/service/TargetService.js +0 -97
  64. package/src/service/TrackService.js +0 -11
  65. package/src/service/TrackingEitriAnalytics.js +0 -26
  66. package/src/service/TrackingService.js +0 -183
  67. package/src/service/ValidateResult.js +0 -57
  68. package/src/service/Watcher.js +0 -118
  69. package/src/service/Workspace.js +0 -1045
  70. package/src/service/WorkspaceManager.js +0 -76
  71. package/src/service/factories/DoubtsStarterFactory.js +0 -25
  72. package/src/service/factories/MiniWebAppFactory.js +0 -44
  73. package/src/service/factories/QRCodeStarterFactory.js +0 -154
  74. package/src/service/factories/WebStarterFactory.js +0 -88
  75. package/src/service/factories/WoodCoffeeFactory.js +0 -292
  76. package/src/util/AboutTemplate.jsx +0 -14
  77. package/src/util/FileUtils.js +0 -25
  78. package/src/util/GenericUtils.js +0 -41
  79. package/src/util/LibUtil.js +0 -32
  80. package/src/util/LogUtil.js +0 -14
  81. package/src/util/UrlUtils.js +0 -12
  82. package/src/util/UserLocalCredential.js +0 -128
  83. package/src/util/convertKeysToCamelCase.js +0 -26
  84. package/src/util/error-messages/error-messages.js +0 -24
  85. package/src/util/error-messages/invite/invite-error-messages.js +0 -14
  86. package/src/util/getCliVersion.js +0 -13
  87. package/src/util/getCreateFactory.js +0 -9
  88. package/src/util/getWorkspace.js +0 -37
  89. package/src/util/ipv4.js +0 -19
  90. package/src/util/manage-env.js +0 -65
  91. package/src/util/open-docs.js +0 -7
  92. package/src/util/os.js +0 -39
  93. package/src/util/server-url.js +0 -15
  94. package/src/util/template-utils.js +0 -21
  95. package/src/view/index.html +0 -19
@@ -1,1045 +0,0 @@
1
- const fs = require("fs")
2
- const os = require("os")
3
- const path = require("path")
4
- const Http = require("./Http")
5
- const Base64 = require("base-64")
6
- const TagTree = require("./TagTree")
7
- const FormData = require("form-data")
8
- const { v4: uuidv4 } = require("uuid")
9
- const AdmZip = require("adm-zip")
10
- const BlindGuardian = require("./BlindGuardian")
11
- const HashFolder = require("./HashFolder")
12
- const packageJson = require(path.resolve(__dirname, "..", "..", "package.json"))
13
- const tempFolderPath = require("../util/os").OS_MAPPER
14
- const TargetService = require("../service/TargetService")
15
- const WatcherOpts = require("../enum/WatcherOpts")
16
- const ipv4 = require("../util/ipv4")
17
- const { compressToBase64 } = require("lz-string")
18
- const Buffer = require("buffer")
19
- const DEFAULT_ENV = "dev"
20
- const cliProgress = require("cli-progress")
21
- const EitriAppManager = require("./EitriAppManager")
22
- const EitriAppService = require("./EitriAppService")
23
- const HuginService = require("./HuginService")
24
- const EitriAppType = require("../model/EitriAppType")
25
- const LibsService = require("./LibsService")
26
- const { LogSuccess } = require("../util/LogUtil")
27
- const { extractSlug } = require("../util/LibUtil")
28
- const huginService = new HuginService()
29
- const YAML = require("yaml")
30
- const { readFile } = require("fs/promises")
31
- const convertKeysToCamelCase = require("../util/convertKeysToCamelCase")
32
- const { exit } = require("process")
33
- const debug = require("debug")("eitri:Workspace")
34
- const FileUtils = require("../util/FileUtils")
35
-
36
- class Workspace {
37
- constructor(blindGuardian, hashFolder) {
38
- const configService = require("./ConfigService")
39
- this.config = configService.get("workspace")
40
- this.basePath = this.config.basePath
41
- this.blindGuardian = blindGuardian
42
- this.hashFolder = hashFolder
43
- this.folder2watch = ""
44
- this.resourceFolders2watch = []
45
- this.http = new Http(this.blindGuardian)
46
- this.upsertQueue = []
47
- this.requestNumber = 0
48
- this.publishing = false
49
- if (!this.config.hugin) {
50
- console.warn("Missing colossus config inside workspace.")
51
- }
52
- this.shareApi = configService.get("shareApi")
53
- this.vegvisir = configService.get("vegvisir")
54
- this.targets = []
55
-
56
- /**
57
- * @type {cliProgress.SingleBar}
58
- * @private
59
- */
60
- this.progressBar
61
- this.progressBarCounter = 0
62
- /**
63
- * @type {EitriAppService}
64
- * @private
65
- */
66
- this.eitriAppService = new EitriAppService()
67
- }
68
-
69
- getTargets() {
70
- return this.targets
71
- }
72
-
73
- setTargets(targets) {
74
- this.targets = targets
75
- }
76
-
77
- setServerUrl(url) {
78
- this.serverUrl = url
79
- }
80
-
81
- setQrCodeUrl(qrCodeUrl) {
82
- this.qrCodeUrl = qrCodeUrl
83
- }
84
-
85
- setFolder2Watch(folderPath) {
86
- this.folder2watch = folderPath
87
- }
88
-
89
- setResourceFolder2Watch(resourceFolders2watch) {
90
- this.resourceFolders2watch = resourceFolders2watch
91
- }
92
-
93
- getResourceFolder2Watch() {
94
- return this.resourceFolders2watch
95
- }
96
-
97
- getTarget() {
98
- if (!this.target) {
99
- console.warn("Target não foi detectado no setup()")
100
- }
101
-
102
- return this.target
103
- }
104
-
105
- async getProjectSourceFolderSize() {
106
- return await FileUtils.getFolderSize(this.folder2watch)
107
- }
108
-
109
- async init() {
110
- const token = await this.blindGuardian.getToken()
111
- this.http.setToken(token)
112
- this.userEmail = token.email
113
- }
114
-
115
- async initPushVersion(workspaceId = "") {
116
- this.http.setWorkspaceId(workspaceId)
117
- this.init()
118
- }
119
-
120
- getMiniConf() {
121
- if (!this._miniConf) {
122
- const eitriAppConfPath = path.resolve(this.folder2watch, "../eitri-app.conf.js")
123
- if (fs.existsSync(eitriAppConfPath)) {
124
- this._miniConf = require(eitriAppConfPath)
125
- } else {
126
- const miniAppConfPath = path.resolve(this.folder2watch, "../miniapp.conf.js")
127
- if (!fs.existsSync(miniAppConfPath)) {
128
- throw new Error("Por favor, verifique se você está dentro da pasta de um projeto Eitri-App.")
129
- }
130
- this._miniConf = require(miniAppConfPath)
131
- }
132
- if (!this._miniConf.version) {
133
- throw Error("Arquivo eitri-app.conf.js sem version")
134
- }
135
- }
136
- if (process.env.WORKSPACE_SHARED) {
137
- this._miniConf["eitri-luminus"] = process.env.WORKSPACE_SHARED
138
- }
139
- return this._miniConf
140
- }
141
-
142
- setMiniConf(miniConf) {
143
- this._miniConf = miniConf
144
- return new Promise((resolve, reject) => {
145
- const eitriAppConfPath = path.resolve(this.folder2watch, "../eitri-app.conf.js")
146
- if (fs.existsSync(eitriAppConfPath)) {
147
- const jsonContent = JSON.stringify(miniConf, null, 4)
148
- fs.writeFile(eitriAppConfPath, `module.exports = ${jsonContent}`, (err) => {
149
- if (err) {
150
- console.log(err)
151
- return reject(err)
152
- }
153
- resolve()
154
- })
155
- } else {
156
- const miniAppConfPath = path.resolve(this.folder2watch, "../miniapp.conf.js")
157
- const jsonContent = JSON.stringify(miniConf, null, 4)
158
- fs.writeFile(miniAppConfPath, `module.exports = ${jsonContent}`, (err) => {
159
- if (err) {
160
- console.log(err)
161
- return reject(err)
162
- }
163
- resolve()
164
- })
165
- }
166
- })
167
- }
168
-
169
- async setup(args) {
170
- const eitriConf = this.getMiniConf()
171
- eitriConf.isShared = args?.shared
172
- const headers = {
173
- accept: this.config.libs.updateLibsEndpointVersion,
174
- }
175
-
176
- let runAppMode = "CLIENT_APP"
177
- if (args?.playground) runAppMode = "PLAYGROUND"
178
-
179
- debug("RUN_APP_MODE", runAppMode)
180
-
181
- try {
182
- const appConfig = await this.getAppConfig()
183
- const setupResponse = await this.http.post(
184
- `${this.serverUrl}/${this.basePath}/v2/workspace/setup`,
185
- {
186
- eitriConf,
187
- appConfig,
188
- runAppMode,
189
- },
190
- headers,
191
- ) // somente para garantir que a pasta do usuario existe
192
-
193
- console.log("Preparando compilador")
194
- await this.http.put(`${this.serverUrl}/${this.basePath}/version`, eitriConf, headers) // TODO PDV Setup fara isso aqui
195
- console.log("Compilador pronto para uso contínuo")
196
-
197
- const setupData = setupResponse.data
198
-
199
- const { state, application, eitriConf: remoteEitriConf } = setupData
200
-
201
- if (!application) {
202
- console.error("O Aplicativo não foi encontrado durante o processo de setup do Eitri-App.")
203
- return exit(1)
204
- }
205
-
206
- if (!this.eitriAppService.validEitriConf(eitriConf)) {
207
- await this.eitriAppService.writeEitriConf(remoteEitriConf, eitriConf, this.folder2watch)
208
- }
209
-
210
- await LibsService.validateLibsVersions({ libs: state.libs, eitriAppConf: eitriConf })
211
-
212
- this.printLibsVersion(state)
213
-
214
- await this.loadTarget(application)
215
-
216
- return setupData
217
- } catch (e) {
218
- if (e.response && e.response.data && e.response.data.name === "WorkspaceService.setup.mismatchAppType") {
219
- console.error(`\x1b[1m\x1b[31m${e.response.data.message}\x1b[0m`)
220
- process.exit(1)
221
- }
222
- throw Error(e)
223
- }
224
- }
225
-
226
- async getAppConfig() {
227
- const appConfigPath = path.resolve(this.folder2watch, "../../app-config.yaml")
228
- if (!fs.existsSync(appConfigPath)) return
229
- const content = await readFile(appConfigPath, "utf8")
230
- const appConfig = YAML.parse(content)
231
- return convertKeysToCamelCase(appConfig)
232
- }
233
-
234
- async loadTarget(remoteTarget) {
235
- const targets = await this.availableTargets()
236
- this.target = targets.find((t) => t.name === remoteTarget.name)
237
-
238
- if (!this.target) {
239
- const friendlyErrorMessage = `Você ainda não foi registrado na application [${remoteTarget?.name}]. Por favor, entre em contato com o administrador da sua organização.`
240
- throw new Error(friendlyErrorMessage)
241
- }
242
- }
243
-
244
- printLibsVersion(state) {
245
- const miniConf = this.getMiniConf()
246
- let libVersionsOutput = ""
247
- state.libs.forEach((lib) => {
248
- let libraryDisplayName = lib.name
249
- if (libraryDisplayName === "eitri-luminus") {
250
- libraryDisplayName = extractSlug(miniConf[lib.name])
251
- }
252
-
253
- let version = miniConf[lib.name]
254
- if (version) {
255
- // Captura a versao da lib quando estamos usando uma url
256
- // "https://eitri.s3.amazonaws.com/eitri-app-client-0.8.0-alpha.tgz".match(/(\d+\.\d+\.\d+([-a-z]*))/)
257
- const m = version.match(/(\d+\.\d+\.\d+([-a-z]*))/)
258
- if (m) {
259
- version = m[1]
260
- }
261
- libVersionsOutput += ` ${libraryDisplayName} [${version}]`
262
- }
263
- })
264
- console.log(" ", libVersionsOutput, "\n")
265
- }
266
-
267
- async checkVersions() {
268
- try {
269
- const eitriConf = this.getMiniConf()
270
- const headers = {
271
- accept: this.config.libs.updateLibsEndpointVersion,
272
- }
273
-
274
- // somente para garantir que a pasta do usuario existe
275
- LogSuccess("1/8 ✓ Preparando ambiente de desenvolvimento")
276
- await this.http.post(`${this.serverUrl}/${this.basePath}/v2/workspace/setup`, { eitriConf }, headers)
277
-
278
- LogSuccess("2/8 ✓ Verificando permissões de publicação")
279
- const response = await this.http.put(
280
- `${this.serverUrl}/${this.basePath}/version?command=push-version`,
281
- eitriConf,
282
- headers,
283
- )
284
-
285
- LogSuccess("3/8 ✓ Ambiente de desenvolvimento preparado")
286
-
287
- eitriConf.target = response.application
288
- const availableTargets = await this.availableTargets()
289
- let libs = TargetService.getLibsFromMiniConf(eitriConf, availableTargets)
290
- LogSuccess("4/8 ✓ Ambiente pronto para compilação.")
291
-
292
- const eitriConfProperties = Object.getOwnPropertyNames(eitriConf)
293
- const clientName =
294
- eitriConfProperties.find((p) => p === libs.bifrost) || TargetService.LIBS_FOR_TARGET.MOBILE_NEW.bifrost
295
- const componentsName =
296
- eitriConfProperties.find((p) => p === libs.luminus) || TargetService.LIBS_FOR_TARGET.MOBILE_NEW.luminus
297
-
298
- const bifrostVersion = eitriConf[clientName]
299
- const luminusVersion = eitriConf[componentsName]
300
-
301
- LogSuccess(
302
- `5/8 ✓ Criando versão com as bibliotecas: ${clientName} [${bifrostVersion}] | ${componentsName} [${luminusVersion}]`,
303
- )
304
- return { target: response.target }
305
- } catch (error) {
306
- const errorMessage = this.handleErrorMessage(error)
307
- console.log(`\n\x1b[1m\x1b[31m${errorMessage}\x1b[0m`)
308
- process.exit(1)
309
- }
310
- }
311
-
312
- handleErrorMessage(error) {
313
- let errorMessage = error.message
314
- if (error.response && error.response.data && error.response.data.message) {
315
- errorMessage = error.response.data.message
316
- }
317
- return errorMessage
318
- }
319
-
320
- isDiff(miniConf, onlineVersion, packageName) {
321
- return miniConf[packageName] && onlineVersion[packageName] !== miniConf[packageName]
322
- }
323
-
324
- async getWorkspaceConnectionData(args, serverUrl) {
325
- const cookie = await this.http.getCookieSession(serverUrl)
326
- const miniConf = this.getMiniConf()
327
- const viewHtml = args.view || "index"
328
- let environment = process.env.NODE_ENV || DEFAULT_ENV
329
- if (environment === "prod") environment = "prd"
330
- let miniAppData = {
331
- developerEmail: this.userEmail,
332
- environment: environment,
333
- albCookie: cookie.cookieString(),
334
- orderId: args.orderId,
335
- shareId: args.shareId,
336
- slug: miniConf.slug,
337
- publicKey: miniConf["public-key"] || miniConf.publicKey,
338
- view: viewHtml,
339
- }
340
- // delete miniAppData.albCookie
341
- return Base64.encode(JSON.stringify(miniAppData))
342
- }
343
-
344
- /**
345
- *
346
- * @param {string} bootstrapBaseUrl
347
- */
348
- getBootstrapURL(bootstrapBaseUrl) {
349
- const LOCALHOST = "http://localhost:"
350
- if (bootstrapBaseUrl.startsWith(LOCALHOST) && process.env.NODE_ENV === "loc") {
351
- const HOST = ipv4()[0]
352
- const PORT = bootstrapBaseUrl.split(LOCALHOST)[1]
353
- return `http://${HOST}:${PORT}`
354
- }
355
- return bootstrapBaseUrl
356
- }
357
-
358
- async getNewWorkspaceURL(args, setupConfig, eitriAppConf) {
359
- const qrCodeConfig = await this.getQrCodeConfig(args, setupConfig)
360
- const stateData = await this.saveShareState(qrCodeConfig, eitriAppConf)
361
- const stateId = stateData.id
362
- const miniAppUrl = `${this.qrCodeUrl}/${stateId}`
363
- return {
364
- miniAppConf: {
365
- ...qrCodeConfig,
366
- shareId: stateId,
367
- },
368
- miniAppUrl,
369
- }
370
- }
371
-
372
- async saveShareState(qrCodeConfig, eitriAppConf) {
373
- const createWorkspaceStateUrl = `${this.serverUrl}/${this.basePath}/share`
374
- const requestBody = {
375
- id: uuidv4(),
376
- state: {
377
- ...qrCodeConfig,
378
- eitriAppId: eitriAppConf?.id || "",
379
- organizationId: eitriAppConf?.organizationId || "",
380
- applicationId: eitriAppConf?.applicationId || "",
381
- },
382
- }
383
- const response = await this.http.post(createWorkspaceStateUrl, requestBody)
384
- return response.data
385
- }
386
-
387
- async getQrCodeConfig(args, setupConfig) {
388
- args = args || {}
389
- const cookie = await this.http.getCookieSession(this.serverUrl)
390
- let cid
391
- const miniAppConf = this.getMiniConf()
392
- const view = (args.view || "index") + ".html"
393
- const initializationParams = args.initializationParams
394
- const orderId = args.orderId
395
-
396
- if (cookie) {
397
- cid = Base64.encode(cookie.cookieString())
398
- }
399
-
400
- const config = {
401
- developerEmail: this.userEmail,
402
- publicKey: miniAppConf["public-key"],
403
- metadata: miniAppConf["metadata"],
404
- slug: miniAppConf["slug"],
405
- title: miniAppConf["title"],
406
- permissions: miniAppConf["permissions"],
407
- miniAppBootstrapUrl: this.getBootstrapURL(setupConfig.eitriAppBootstrapURL),
408
- developmentDeeplink: setupConfig.developmentDeeplink,
409
- initializationParams,
410
- orderId,
411
- view,
412
- extras: {
413
- cid, // superapp joga tudo do extras na query string do bootstrapUrl .... Pq ja nao mandamos na queryString ja daqui?
414
- },
415
- }
416
-
417
- if (process.env.APP_START_WORKSPACE_CONFIG) {
418
- const startAppsConfig = await this.getEitriStartAppsWorkspacesConfig()
419
- if (startAppsConfig) {
420
- config.focusedEitriApp = startAppsConfig.focusedEitriApp
421
- config.applicationId = startAppsConfig.applicationId
422
- config.environmentId = startAppsConfig.environmentId
423
- config.devEnvKey = startAppsConfig.devEnvKey
424
- config.workspaces = startAppsConfig.workspaces
425
- }
426
- }
427
-
428
- return config
429
- }
430
-
431
- async getEitriStartAppsWorkspacesConfig() {
432
- try {
433
- const appConfig = await this.getAppConfig()
434
- const url = `${this.vegvisir.url}${this.vegvisir.basePath}${this.vegvisir.my}`
435
- const responseWorkspaces = await this.http.get(url)
436
-
437
- const workspaces = []
438
- let focusedEitriApp = ""
439
- let workspaceFocused = ""
440
-
441
- for (const eitriApp of appConfig.eitriApps) {
442
- const eitriAppPath = eitriApp.path
443
-
444
- const eitriAppConfPath = path.resolve(process.cwd(), "..", eitriAppPath, "eitri-app.conf.js")
445
-
446
- if (fs.existsSync(eitriAppConfPath)) {
447
- const eitriAppContent = require(eitriAppConfPath)
448
- const workspaceRemoteInfo = responseWorkspaces.find((rw) => rw.name === eitriApp.workspace)
449
-
450
- if (eitriApp.focus) {
451
- focusedEitriApp = eitriAppContent.slug
452
- workspaceFocused = workspaceRemoteInfo.id
453
- }
454
-
455
- const foundryContextPath = process.env.FOUNDRY_CONTEXT_PATH || "foundry"
456
- const workspaceUrl = `https://api.eitri.tech/${foundryContextPath}/user/${workspaceRemoteInfo.id}/index.html`
457
-
458
- workspaces.push({
459
- name: eitriApp?.workspace,
460
- id: workspaceRemoteInfo?.id,
461
- url: workspaceUrl,
462
- slug: eitriAppContent?.slug,
463
- eitriAppId: eitriAppContent?.id,
464
- })
465
- } else {
466
- console.error(`Eitri-App Conf não encontrado: ${eitriAppConfPath}`)
467
- }
468
- }
469
-
470
- const fakerDevEnvKey = `dev-${new Date().getTime()}-${workspaceFocused}`
471
- return {
472
- focusedEitriApp,
473
- applicationId: appConfig?.applicationId,
474
- environmentId: appConfig?.environmentId,
475
- devEnvKey: fakerDevEnvKey,
476
- workspaces,
477
- }
478
- } catch (error) {
479
- console.error("Erro ao obter configurações do Workspaces: ", error?.message)
480
- }
481
- }
482
-
483
- getRelativePath(filePath) {
484
- return filePath
485
- .replace(this.folder2watch, "")
486
- .replace(this.folder2watch.replace(/\\/g, "/"), "")
487
- .replace(process.cwd(), "")
488
- }
489
-
490
- async delete(filePath) {
491
- const relPath = this.getRelativePath(filePath)
492
- const url = `${this.serverUrl}/${this.basePath}/fileupload`
493
- const params = {
494
- filepath: relPath,
495
- }
496
- const projectSize = await this.getProjectSourceFolderSize()
497
- await this.http.delete(
498
- url,
499
- {
500
- params,
501
- },
502
- {
503
- "project-size": projectSize,
504
- },
505
- )
506
- }
507
-
508
- hasAccent(fileName) {
509
- const fileRegex = /[À-ź]/g
510
- const isValidFileName = !fileRegex.test(fileName)
511
- return !isValidFileName
512
- }
513
-
514
- async upsert(filesPath, opts = {}) {
515
- return await this.upsertSequencial(filesPath, opts)
516
- }
517
-
518
- async upsertSequencial(filePath, opts = {}) {
519
- const fileName = path.basename(filePath)
520
-
521
- const { isInvalid, promise } = await this.validateFileName(fileName, filePath)
522
- if (isInvalid) return await promise
523
-
524
- const holder = this.createPromiseHolder()
525
- this.upsertQueue.push({
526
- filePath,
527
- opts,
528
- holder,
529
- requestNumber: this.requestNumber++,
530
- })
531
-
532
- const isDevMode = opts.why === WatcherOpts.SAVE
533
-
534
- if (!this.uploading) {
535
- await this.execUpsertSequencial(isDevMode)
536
- }
537
-
538
- return holder.promise
539
- }
540
-
541
- async postFile(filePath, isDevMode, opts) {
542
- const start = new Date().getTime()
543
- const relativePath = this.getRelativePath(filePath)
544
- const fileName = path.basename(filePath)
545
- if (relativePath.startsWith(this.config.hugin.watchUserDir)) {
546
- const data = {
547
- filePath,
548
- relativePath: relativePath.replace(this.config.hugin.watchUserDir, ""),
549
- isDevMode,
550
- }
551
- await huginService.postServerless(data, this.getMiniConf())
552
- } else {
553
- await this.postFormData(filePath, relativePath, opts)
554
- }
555
- return {
556
- start,
557
- relativePath,
558
- fileName,
559
- }
560
- }
561
- async execUpsertSequencial(isDevMode) {
562
- this.uploading = true
563
- for (let i = 0; i < this.upsertQueue.length; i++) {
564
- const { filePath, opts, holder, requestNumber } = this.upsertQueue[i]
565
-
566
- try {
567
- const { relativePath, start } = await this.postFile(filePath, isDevMode, opts)
568
-
569
- holder.resolve({
570
- filePath,
571
- relativePath,
572
- requestNumber,
573
- time: new Date().getTime() - start,
574
- })
575
- } catch (e) {
576
- holder.reject(e)
577
- break // na duvida se deve abortar a fila toda
578
- }
579
- }
580
- this.upsertQueue = []
581
- this.uploading = false
582
- }
583
-
584
- async validateFileName(fileName, filePath) {
585
- const hasAccent = this.hasAccent(fileName)
586
- let promise
587
- if (hasAccent) {
588
- const message = ` - No nome do arquivo possui um ou mais caracteres não permitidos: ${fileName}`
589
- console.log(message)
590
-
591
- promise = Promise.resolve({
592
- filePath,
593
- relativePath: this.getRelativePath(filePath),
594
- time: 0,
595
- requestNumber: this.requestNumber++,
596
- message,
597
- })
598
- }
599
- return {
600
- isInvalid: hasAccent,
601
- promise,
602
- }
603
- }
604
-
605
- createPromiseHolder() {
606
- const holder = {}
607
- holder.promise = new Promise((resolve, reject) => {
608
- holder.resolve = resolve
609
- holder.reject = reject
610
- })
611
- return holder
612
- }
613
-
614
- async postFormData(filePath, relativePath, opts) {
615
- let conf = this.getMiniConf()
616
- const formData = new FormData()
617
- formData.append("filepath", relativePath)
618
- formData.append("why", opts.why || "")
619
- formData.append("file", fs.createReadStream(filePath))
620
- formData.append("miniAppVersion", conf.version)
621
- if (opts.forceTranspile) {
622
- formData.append("forceTranspile", opts.forceTranspile)
623
- }
624
- const url = `${this.serverUrl}/${this.basePath}/fileupload`
625
- const projectSize = await this.getProjectSourceFolderSize()
626
- return await this.http.postForm(url, formData, {
627
- "project-size": projectSize,
628
- })
629
- }
630
-
631
- getEnvCode() {
632
- if (!this.publishing) {
633
- return "ws"
634
- }
635
- if (["dev", "loc"].includes(process.env.NODE_ENV)) {
636
- return "dev"
637
- } else {
638
- return "hml"
639
- }
640
- }
641
-
642
- async isSynchronized() {
643
- const res = await Promise.all([
644
- this.hashFolder.calculate(),
645
- this.http.get(`${this.serverUrl}/${this.basePath}/fileupload`),
646
- ])
647
- const folderHashValue = res[0]["hash"]
648
- const serverHash = res[1]["hash"]
649
- return folderHashValue === serverHash
650
- }
651
-
652
- async rmAllServerFiles() {
653
- await this.delete("/")
654
- }
655
-
656
- async listFilesInCorrectOrder() {
657
- const allFiles = await this.walk(this.folder2watch)
658
- const componentsPath = path.join(this.folder2watch, "components")
659
- const componentTagRegExp = new RegExp(`${componentsPath}/[^/]+.jsx`)
660
- const filesWithoutComponentTags = allFiles.filter((fileName) => {
661
- return !fileName.match(componentTagRegExp)
662
- })
663
- let files = filesWithoutComponentTags.sort((a, b) => {
664
- if (a.includes("components") && !b.includes("components")) return -1
665
- if (!a.includes("components") && b.includes("components")) return 1
666
- if (a.includes("folder.hash")) return 1
667
- if (b.includes("folder.hash")) return -1
668
- return 0
669
- })
670
- const tagsFiles = await new TagTree().tagsFilesSorted(componentsPath)
671
- files = tagsFiles.map((fileName) => path.join(componentsPath, fileName)).concat(files)
672
- return files
673
- }
674
-
675
- async getAllResourceFiles(resources) {
676
- let allFiles = []
677
- resources.forEach(async (dir) => {
678
- const files = await this.walk(dir)
679
- allFiles.push(...files)
680
- })
681
- return allFiles
682
- }
683
-
684
- async preUpsert(componentsFiles, opts) {
685
- for (const filePath of componentsFiles) {
686
- await this.upsertSequencial(filePath, opts)
687
- }
688
- }
689
-
690
- async uploadZip(isDevMode) {
691
- const admZip = new AdmZip()
692
- await this.mkdirs([this.folder2watch, ...this.resourceFolders2watch])
693
- await this.rmAllServerFiles()
694
- await this.hashFolder.updateHashFile()
695
- const allFiles = await this.listFilesInCorrectOrder()
696
- const files = allFiles.filter((f) => !f.endsWith("folder.hash"))
697
- const folderHash = allFiles.filter((f) => f.endsWith("folder.hash"))
698
-
699
- const hasServerless = files.find((file) => file.includes(this.config.hugin.watchUserDir))
700
- if (hasServerless) {
701
- const serverlessFolderPath = path.join(this.folder2watch, this.config.hugin.watchUserDir)
702
-
703
- const serverlessZip = new AdmZip()
704
- serverlessZip.addLocalFolder(serverlessFolderPath, undefined, (fileName) => fileName.includes("."))
705
- const now = Date.now()
706
- const tempZip = path.join(os.tmpdir(), `eitri-serverless-${now}.zip`)
707
- await serverlessZip.writeZipPromise(tempZip, { overwrite: true, perm: 777 })
708
-
709
- const data = {
710
- filePath: tempZip,
711
- // No upload do Zip é ignorado
712
- relativePath: tempZip,
713
- isDevMode,
714
- }
715
- await huginService.postServerless(data, this.getMiniConf())
716
- }
717
-
718
- admZip.addFile("__files_order.txt", allFiles.map((f) => f.split(this.folder2watch)[1].replace(/\\/g, "/")).join("\n"))
719
- admZip.addLocalFolder("./src")
720
-
721
- const platform = process.platform
722
-
723
- const zipPath = await this.resolveOs(platform)
724
- admZip.writeZip(zipPath)
725
- await this.sendZip(zipPath)
726
-
727
- await this.transpile(folderHash)
728
- }
729
-
730
- async uploadCleanZip(isDevMode) {
731
- const admZip = new AdmZip()
732
- await this.mkdirs([this.folder2watch, ...this.resourceFolders2watch])
733
- await this.rmAllServerFiles()
734
- await this.hashFolder.updateHashFile()
735
- const allFiles = await this.listFilesInCorrectOrder()
736
- const filesWithoutTestJSAndTestTS = allFiles.filter((file) => !file.endsWith(".test.js") && !file.endsWith(".test.ts"))
737
- const files = filesWithoutTestJSAndTestTS.filter((f) => !f.endsWith("folder.hash"))
738
- const folderHash = filesWithoutTestJSAndTestTS.filter((f) => f.endsWith("folder.hash"))
739
-
740
- const hasServerless = files.find((file) => file.includes(this.config.hugin.watchUserDir))
741
- if (hasServerless) {
742
- const serverlessFolderPath = path.join(this.folder2watch, this.config.hugin.watchUserDir)
743
-
744
- const serverlessZip = new AdmZip()
745
- serverlessZip.addLocalFolder(serverlessFolderPath, undefined, (fileName) => fileName.includes("."))
746
- const now = Date.now()
747
- const tempZip = path.join(os.tmpdir(), `eitri-serverless-${now}.zip`)
748
- await serverlessZip.writeZipPromise(tempZip, { overwrite: true, perm: 777 })
749
-
750
- const data = {
751
- filePath: tempZip,
752
- // No upload do Zip é ignorado
753
- relativePath: tempZip,
754
- isDevMode,
755
- }
756
- await huginService.postServerless(data, this.getMiniConf())
757
- }
758
-
759
- admZip.addFile(
760
- "__files_order.txt",
761
- filesWithoutTestJSAndTestTS.map((f) => f.split(this.folder2watch)[1].replace(/\\/g, "/")).join("\n"),
762
- )
763
- admZip.addLocalFolder("./src")
764
-
765
- const platform = process.platform
766
-
767
- const zipPath = await this.resolveOs(platform)
768
- admZip.writeZip(zipPath)
769
- await this.sendZip(zipPath)
770
-
771
- await this.transpile(folderHash)
772
- }
773
-
774
- async resolveOs(platform) {
775
- let tempDir = ""
776
- if (tempFolderPath[platform]) {
777
- tempDir = await tempFolderPath[platform]()
778
- } else {
779
- tempDir = "."
780
- }
781
- return tempDir + "/miniApp.zip"
782
- }
783
-
784
- async sendFiles(publishMessage) {
785
- const miniConf = this.getMiniConf()
786
- const formData = new FormData()
787
-
788
- formData.append("miniAppName", miniConf.name || "sem nome")
789
- formData.append("miniAppSlug", miniConf.slug || "sem-slug")
790
- formData.append("miniAppTitle", miniConf.title || "Sem Titulo")
791
- formData.append("miniAppVersion", miniConf.miniAppVersion || miniConf.version || "v1")
792
- formData.append("organizationName", miniConf.organization.name)
793
- formData.append("publishMessage", publishMessage || "")
794
-
795
- const url = `${this.serverUrl}/${this.basePath}/publish?async=true`
796
- const projectSize = await this.getProjectSourceFolderSize()
797
- await this.http.postForm(url, formData, {
798
- "project-size": projectSize,
799
- })
800
- }
801
-
802
- async sendZip(zip) {
803
- const formData = new FormData()
804
- formData.append("file", fs.createReadStream(zip))
805
- const url = `${this.serverUrl}/${this.basePath}/uploadAll`
806
- const projectSize = await this.getProjectSourceFolderSize()
807
- await this.http.postForm(url, formData, {
808
- "project-size": projectSize,
809
- })
810
- }
811
-
812
- async transpile(files) {
813
- if (files.length > 0) {
814
- return await this.upsert(...files, {
815
- why: "uploadAll",
816
- log: false,
817
- })
818
- }
819
- }
820
-
821
- mkdirs(dirnames) {
822
- return new Promise((resolve, reject) => {
823
- dirnames.forEach((dirname) => {
824
- fs.mkdir(dirname, { recursive: true }, (err) => {
825
- if (err) {
826
- return reject(err)
827
- }
828
- resolve()
829
- })
830
- })
831
- })
832
- }
833
-
834
- async getFileNames(dir) {
835
- const folder = path.resolve(this.folder2watch, dir)
836
- const fileList = await this.walk(folder)
837
-
838
- const fileNames = fileList.map((filePath) => {
839
- return path.basename(filePath)
840
- })
841
-
842
- return fileNames
843
- }
844
-
845
- async walk(dir) {
846
- let results = []
847
- const list = fs.readdirSync(dir)
848
- for (let i = 0; i < list.length; i++) {
849
- let file = list[i]
850
- file = path.join(dir, file)
851
- const stat = fs.statSync(file)
852
- if (stat && stat.isDirectory()) {
853
- /* Recurse into a subdirectory */
854
- results = results.concat(await this.walk(file))
855
- } else {
856
- /* Is a file */
857
- results.push(file)
858
- }
859
- }
860
- return results
861
- }
862
-
863
- async pushVersionAsJson(args) {
864
- let headers = {}
865
- if (this.config.apiVersion && this.config.apiVersion.v2Header) {
866
- headers = {
867
- accept: this.config.apiVersion.v2Header,
868
- }
869
- }
870
- const miniConf = this.getMiniConf()
871
- const body = {
872
- miniConf,
873
- buildMessage: args.message,
874
- cliVersion: packageJson.version,
875
- eitriAppType: args.shared ? EitriAppType.SHARED : EitriAppType.APPLICATION,
876
- }
877
- const url = `${this.serverUrl}/${this.basePath}/publish?async=true`
878
- await this.http.post(url, body, headers)
879
- }
880
-
881
- async create(conf) {
882
- const url = `${this.serverUrl}/${this.basePath}/create`
883
- return await this.http
884
- .post(url, conf)
885
- .then((res) => res.data)
886
- .catch((err) => {
887
- if (
888
- err.isAxiosError &&
889
- err.response &&
890
- err.response.status === 409 &&
891
- err.response.data &&
892
- err.response.data.error
893
- ) {
894
- console.log("Error: " + err.response.data.error)
895
- let dupError = new Error(err.response.data.error)
896
- dupError.isDuplicatedError = true
897
- dupError.field = err.response.data.field
898
- throw dupError
899
- }
900
- console.log(err.message)
901
- if (err && err.response) {
902
- console.log(err.response.data)
903
- }
904
- throw err
905
- })
906
- }
907
-
908
- async applyRolloutEnvironmentIfNeeded() {
909
- const start = Date.now()
910
- try {
911
- const { slug } = this.getMiniConf()
912
- const url = `${this.serverUrl}/${this.basePath}/users/miniapps/${slug}/actions/WORKSPACE_ROLLOUT`
913
- const response = await this.http.get(url)
914
- if (response.result) {
915
- process.env["NODE_ENV"] = "beta"
916
- this.rollout = response.result
917
-
918
- console.log("\n")
919
- console.log("\t╔═══════════════════════════════════════╗")
920
- console.log("\t║ Atenção: Utilizando Beta Workspace ║")
921
- console.log("\t╚═══════════════════════════════════════╝\n")
922
- }
923
- } catch (e) {
924
- if (process.env.LOG_LEVEL === "full") {
925
- console.log(e)
926
- }
927
- }
928
-
929
- if (process.env.LOG_LEVEL === "full") {
930
- console.log("Check rollout time", Date.now() - start)
931
- }
932
- }
933
-
934
- isRollout() {
935
- return this.rollout
936
- }
937
-
938
- // bff
939
- async availableTargets() {
940
- if (this.getTargets().length === 0) {
941
- const targets = await new EitriAppManager(this.blindGuardian).findAllApplications()
942
- this.setTargets(targets)
943
- return targets
944
- }
945
- return this.getTargets()
946
- }
947
-
948
- // local
949
- getKnownAvailableTargets() {
950
- return this.config.target.knownTargets
951
- }
952
-
953
- async getDefaultTarget() {
954
- await this.availableTargets()
955
- return this.getTargets().find((value) => value.default)
956
- }
957
-
958
- // client http configurado conforme as necessidades do workspace
959
- getHttp() {
960
- return this.http
961
- }
962
-
963
- async comparePermissions(target) {
964
- const miniConf = this.getMiniConf()
965
- const permissions = miniConf.permissions || []
966
- const permissionsWithTarget = permissions.map((permission) => ({
967
- ...permission,
968
- target,
969
- }))
970
- const slug = miniConf.slug
971
- const { data } = await this.http.post(
972
- `${this.serverUrl}/${this.basePath}/miniapps/${slug}/permissions/compare`,
973
- permissionsWithTarget,
974
- )
975
- const addedPermissions = []
976
- const removedPermissions = []
977
- if (data.diffCount > 0) {
978
- data.result.forEach((result) => {
979
- if (result.status === "added") {
980
- addedPermissions.push(result.entity.permission)
981
- } else {
982
- removedPermissions.push(result.entity.permission)
983
- }
984
- })
985
- }
986
- return { addedPermissions, removedPermissions }
987
- }
988
-
989
- async clean() {
990
- await this.getHttp().delete(`${this.serverUrl}/${this.basePath}/sources`, {})
991
- }
992
-
993
- compressCode(code) {
994
- const { SERVERLESS_CODE_COMPRESSION: compressionType, LOG_LEVEL } = process.env
995
-
996
- let compressedCode,
997
- codeLength = code.length
998
- let maxPreviewLenth = 50
999
- let previewLength = codeLength > maxPreviewLenth ? maxPreviewLenth : codeLength
1000
-
1001
- if (compressionType === "base64") {
1002
- compressedCode = this.toBase64(code)
1003
-
1004
- if (LOG_LEVEL === "full") {
1005
- console.log(
1006
- `Enviando arquivo sem compactacao em base64: ${code.substring(0, previewLength)}, codeLenth: ${codeLength}`,
1007
- )
1008
- }
1009
- } else if (compressionType === "none") {
1010
- if (LOG_LEVEL === "full") {
1011
- console.log(
1012
- `Enviando arquivo sem qualquer compressao: ${code.substring(0, previewLength)}, codeLenth: ${codeLength}`,
1013
- )
1014
- }
1015
- } else if (!compressionType || compressionType === "shrink") {
1016
- compressedCode = compressToBase64(code)
1017
-
1018
- if (LOG_LEVEL === "full") {
1019
- console.log(
1020
- `File preview: ${code.substring(0, previewLength)}, Before compression: ${codeLength}, After compression: ${compressedCode.length
1021
- }`,
1022
- )
1023
- }
1024
- }
1025
-
1026
- return {
1027
- code: compressedCode || code,
1028
- compressionType: compressionType || "shrink",
1029
- }
1030
- }
1031
-
1032
- toBase64(content) {
1033
- return Buffer.from(content).toString("base64")
1034
- }
1035
-
1036
- getFolderHashPath() {
1037
- const folderHashPath = path.join(this.folder2watch, "folder.hash")
1038
- return folderHashPath
1039
- }
1040
- }
1041
-
1042
- module.exports = {
1043
- workspace: new Workspace(new BlindGuardian(), new HashFolder()),
1044
- Workspace,
1045
- }