@budibase/cli 2.3.20 → 2.3.21-alpha.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 (70) hide show
  1. package/dist/analytics/Client.js +32 -0
  2. package/dist/analytics/index.js +55 -0
  3. package/dist/backups/index.js +119 -0
  4. package/dist/backups/objectStore.js +82 -0
  5. package/dist/backups/utils.js +110 -0
  6. package/dist/constants.js +9 -0
  7. package/dist/core/db.js +55 -0
  8. package/dist/environment.js +4 -0
  9. package/dist/events.js +13 -0
  10. package/dist/exec.js +49 -0
  11. package/dist/hosting/genUser.js +32 -0
  12. package/dist/hosting/index.js +21 -0
  13. package/dist/hosting/init.js +117 -0
  14. package/dist/hosting/makeFiles.js +143 -0
  15. package/dist/hosting/start.js +63 -0
  16. package/dist/hosting/status.js +30 -0
  17. package/dist/hosting/stop.js +30 -0
  18. package/dist/hosting/types.js +2 -0
  19. package/dist/hosting/update.js +58 -0
  20. package/dist/hosting/utils.js +125 -0
  21. package/dist/hosting/watch.js +47 -0
  22. package/dist/index.js +36 -0
  23. package/dist/options.js +14 -0
  24. package/dist/plugins/index.js +199 -0
  25. package/dist/plugins/skeleton.js +75 -0
  26. package/dist/prebuilds.js +46 -0
  27. package/dist/questions.js +58 -0
  28. package/dist/structures/Command.js +75 -0
  29. package/dist/structures/ConfigManager.js +39 -0
  30. package/dist/tsconfig.build.tsbuildinfo +1 -0
  31. package/dist/utils.js +126 -0
  32. package/package.json +20 -10
  33. package/src/analytics/Client.ts +33 -0
  34. package/src/analytics/{index.js → index.ts} +7 -10
  35. package/src/backups/{index.js → index.ts} +19 -19
  36. package/src/backups/{objectStore.js → objectStore.ts} +9 -9
  37. package/src/backups/{utils.js → utils.ts} +33 -28
  38. package/src/constants.ts +4 -0
  39. package/src/core/{db.js → db.ts} +8 -7
  40. package/src/{environment.js → environment.ts} +1 -0
  41. package/src/events.ts +11 -0
  42. package/src/{exec.js → exec.ts} +7 -7
  43. package/src/hosting/{genUser.js → genUser.ts} +4 -3
  44. package/src/hosting/{index.js → index.ts} +10 -12
  45. package/src/hosting/{init.js → init.ts} +20 -19
  46. package/src/hosting/{makeFiles.js → makeFiles.ts} +23 -21
  47. package/src/hosting/{start.js → start.ts} +6 -10
  48. package/src/hosting/{status.js → status.ts} +4 -8
  49. package/src/hosting/{stop.js → stop.ts} +4 -8
  50. package/src/hosting/types.ts +4 -0
  51. package/src/hosting/{update.js → update.ts} +10 -10
  52. package/src/hosting/{utils.js → utils.ts} +26 -23
  53. package/src/hosting/{watch.js → watch.ts} +7 -6
  54. package/src/{index.js → index.ts} +5 -5
  55. package/src/options.ts +8 -0
  56. package/src/plugins/{index.js → index.ts} +27 -25
  57. package/src/plugins/{skeleton.js → skeleton.ts} +14 -9
  58. package/src/{prebuilds.js → prebuilds.ts} +7 -6
  59. package/src/{questions.js → questions.ts} +6 -6
  60. package/src/structures/{Command.js → Command.ts} +29 -14
  61. package/src/structures/{ConfigManager.js → ConfigManager.ts} +7 -7
  62. package/src/utils.ts +112 -0
  63. package/start.sh +3 -0
  64. package/tsconfig.build.json +24 -0
  65. package/tsconfig.json +30 -0
  66. package/src/analytics/Client.js +0 -32
  67. package/src/constants.js +0 -25
  68. package/src/events.js +0 -11
  69. package/src/options.js +0 -8
  70. package/src/utils.js +0 -106
@@ -1,20 +1,20 @@
1
- const {
1
+ import {
2
2
  checkDockerConfigured,
3
3
  checkInitComplete,
4
- downloadFiles,
4
+ downloadDockerCompose,
5
5
  handleError,
6
6
  getServices,
7
- } = require("./utils")
8
- const { confirmation } = require("../questions")
9
- const compose = require("docker-compose")
10
- const { COMPOSE_PATH } = require("./makeFiles")
11
- const { info, success } = require("../utils")
12
- const { start } = require("./start")
7
+ } from "./utils"
8
+ import { confirmation } from "../questions"
9
+ import compose from "docker-compose"
10
+ import { COMPOSE_PATH } from "./makeFiles"
11
+ import { info, success } from "../utils"
12
+ import { start } from "./start"
13
13
 
14
14
  const BB_COMPOSE_SERVICES = ["app-service", "worker-service", "proxy-service"]
15
15
  const BB_SINGLE_SERVICE = ["budibase"]
16
16
 
17
- exports.update = async () => {
17
+ export async function update() {
18
18
  const { services } = getServices(COMPOSE_PATH)
19
19
  const isSingle = Object.keys(services).length === 1
20
20
  await checkDockerConfigured()
@@ -23,7 +23,7 @@ exports.update = async () => {
23
23
  !isSingle &&
24
24
  (await confirmation("Do you wish to update you docker-compose.yaml?"))
25
25
  ) {
26
- await downloadFiles()
26
+ await downloadDockerCompose()
27
27
  }
28
28
  await handleError(async () => {
29
29
  const status = await compose.ps()
@@ -1,24 +1,24 @@
1
- const { lookpath } = require("lookpath")
2
- const fs = require("fs")
3
- const makeFiles = require("./makeFiles")
4
- const { logErrorToFile, downloadFile, error } = require("../utils")
5
- const yaml = require("yaml")
1
+ import { lookpath } from "lookpath"
2
+ import fs from "fs"
3
+ import * as makeFiles from "./makeFiles"
4
+ import { logErrorToFile, downloadFile, error } from "../utils"
5
+ import yaml from "yaml"
6
+ import { DockerCompose } from "./types"
6
7
 
7
8
  const ERROR_FILE = "docker-error.log"
8
- const FILE_URLS = [
9
- "https://raw.githubusercontent.com/Budibase/budibase/master/hosting/docker-compose.yaml",
10
- ]
9
+ const COMPOSE_URL =
10
+ "https://raw.githubusercontent.com/Budibase/budibase/master/hosting/docker-compose.yaml"
11
11
 
12
- exports.downloadFiles = async () => {
13
- const promises = []
14
- for (let url of FILE_URLS) {
15
- const fileName = url.split("/").slice(-1)[0]
16
- promises.push(downloadFile(url, `./${fileName}`))
12
+ export async function downloadDockerCompose() {
13
+ const fileName = COMPOSE_URL.split("/").slice(-1)[0]
14
+ try {
15
+ await downloadFile(COMPOSE_URL, `./${fileName}`)
16
+ } catch (err) {
17
+ console.error(error(`Failed to retrieve compose file - ${err}`))
17
18
  }
18
- await Promise.all(promises)
19
19
  }
20
20
 
21
- exports.checkDockerConfigured = async () => {
21
+ export async function checkDockerConfigured() {
22
22
  const error =
23
23
  "docker/docker-compose has not been installed, please follow instructions at: https://docs.budibase.com/docs/docker-compose"
24
24
  const docker = await lookpath("docker")
@@ -28,7 +28,7 @@ exports.checkDockerConfigured = async () => {
28
28
  }
29
29
  }
30
30
 
31
- exports.checkInitComplete = () => {
31
+ export function checkInitComplete() {
32
32
  if (
33
33
  !fs.existsSync(makeFiles.ENV_PATH) &&
34
34
  !fs.existsSync(makeFiles.COMPOSE_PATH)
@@ -37,10 +37,10 @@ exports.checkInitComplete = () => {
37
37
  }
38
38
  }
39
39
 
40
- exports.handleError = async func => {
40
+ export async function handleError(func: Function) {
41
41
  try {
42
42
  await func()
43
- } catch (err) {
43
+ } catch (err: any) {
44
44
  if (err && err.err) {
45
45
  logErrorToFile(ERROR_FILE, err.err)
46
46
  }
@@ -48,14 +48,14 @@ exports.handleError = async func => {
48
48
  }
49
49
  }
50
50
 
51
- exports.getServices = path => {
51
+ export function getServices(path: string) {
52
52
  const dockerYaml = fs.readFileSync(path, "utf8")
53
53
  const parsedYaml = yaml.parse(dockerYaml)
54
54
  return { yaml: parsedYaml, services: parsedYaml.services }
55
55
  }
56
56
 
57
- exports.getAppService = path => {
58
- const { yaml, services } = exports.getServices(path),
57
+ export function getAppService(path: string) {
58
+ const { yaml, services } = getServices(path),
59
59
  serviceList = Object.keys(services)
60
60
  let service
61
61
  if (services["app-service"]) {
@@ -66,14 +66,17 @@ exports.getAppService = path => {
66
66
  return { yaml, service }
67
67
  }
68
68
 
69
- exports.updateDockerComposeService = updateFn => {
69
+ export function updateDockerComposeService(
70
+ // eslint-disable-next-line no-unused-vars
71
+ updateFn: (service: DockerCompose) => void
72
+ ) {
70
73
  const opts = ["docker-compose.yaml", "docker-compose.yml"]
71
74
  const dockerFilePath = opts.find(name => fs.existsSync(name))
72
75
  if (!dockerFilePath) {
73
76
  console.log(error("Unable to locate docker-compose YAML."))
74
77
  return
75
78
  }
76
- const { yaml: parsedYaml, service } = exports.getAppService(dockerFilePath)
79
+ const { yaml: parsedYaml, service } = getAppService(dockerFilePath)
77
80
  if (!service) {
78
81
  console.log(
79
82
  error(
@@ -1,9 +1,10 @@
1
- const { resolve } = require("path")
2
- const fs = require("fs")
3
- const { error, success } = require("../utils")
4
- const { updateDockerComposeService } = require("./utils")
1
+ import { resolve } from "path"
2
+ import fs from "fs"
3
+ import { error, success } from "../utils"
4
+ import { updateDockerComposeService } from "./utils"
5
+ import { DockerCompose } from "./types"
5
6
 
6
- exports.watchPlugins = async (pluginPath, silent) => {
7
+ export async function watchPlugins(pluginPath: string, silent: boolean) {
7
8
  const PLUGIN_PATH = "/plugins"
8
9
  // get absolute path
9
10
  pluginPath = resolve(pluginPath)
@@ -15,7 +16,7 @@ exports.watchPlugins = async (pluginPath, silent) => {
15
16
  )
16
17
  return
17
18
  }
18
- updateDockerComposeService(service => {
19
+ updateDockerComposeService((service: DockerCompose) => {
19
20
  // set environment variable
20
21
  service.environment["PLUGINS_DIR"] = PLUGIN_PATH
21
22
  // add volumes to parsed yaml
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- require("./prebuilds")
3
- require("./environment")
2
+ import "./prebuilds"
3
+ import "./environment"
4
+ import { getCommands } from "./options"
5
+ import { Command } from "commander"
6
+ import { getHelpDescription } from "./utils"
4
7
  const json = require("../package.json")
5
- const { getCommands } = require("./options")
6
- const { Command } = require("commander")
7
- const { getHelpDescription } = require("./utils")
8
8
 
9
9
  // add hosting config
10
10
  async function init() {
package/src/options.ts ADDED
@@ -0,0 +1,8 @@
1
+ import analytics from "./analytics"
2
+ import hosting from "./hosting"
3
+ import backups from "./backups"
4
+ import plugins from "./plugins"
5
+
6
+ export function getCommands() {
7
+ return [hosting, analytics, backups, plugins]
8
+ }
@@ -1,18 +1,22 @@
1
- const Command = require("../structures/Command")
2
- const { CommandWords, AnalyticsEvents, InitTypes } = require("../constants")
3
- const { getSkeleton, fleshOutSkeleton } = require("./skeleton")
4
- const questions = require("../questions")
5
- const fs = require("fs")
6
- const { PLUGIN_TYPE_ARR } = require("@budibase/types")
7
- const { plugins } = require("@budibase/backend-core")
8
- const { runPkgCommand } = require("../exec")
9
- const { join } = require("path")
10
- const { success, error, info, moveDirectory } = require("../utils")
11
- const { captureEvent } = require("../events")
1
+ import { Command } from "../structures/Command"
2
+ import { CommandWord, AnalyticsEvent, InitType } from "../constants"
3
+ import { getSkeleton, fleshOutSkeleton } from "./skeleton"
4
+ import * as questions from "../questions"
5
+ import fs from "fs"
6
+ import { PluginType, PLUGIN_TYPE_ARR } from "@budibase/types"
7
+ import { plugins } from "@budibase/backend-core"
8
+ import { runPkgCommand } from "../exec"
9
+ import { join } from "path"
10
+ import { success, error, info, moveDirectory } from "../utils"
11
+ import { captureEvent } from "../events"
12
+ import { GENERATED_USER_EMAIL } from "../constants"
13
+ import { init as hostingInit } from "../hosting/init"
14
+ import { start as hostingStart } from "../hosting/start"
12
15
  const fp = require("find-free-port")
13
- const { GENERATED_USER_EMAIL } = require("../constants")
14
- const { init: hostingInit } = require("../hosting/init")
15
- const { start: hostingStart } = require("../hosting/start")
16
+
17
+ type PluginOpts = {
18
+ init?: PluginType
19
+ }
16
20
 
17
21
  function checkInPlugin() {
18
22
  if (!fs.existsSync("package.json")) {
@@ -27,7 +31,7 @@ function checkInPlugin() {
27
31
  }
28
32
  }
29
33
 
30
- async function askAboutTopLevel(name) {
34
+ async function askAboutTopLevel(name: string) {
31
35
  const files = fs.readdirSync(process.cwd())
32
36
  // we are in an empty git repo, don't ask
33
37
  if (files.find(file => file === ".git")) {
@@ -45,8 +49,8 @@ async function askAboutTopLevel(name) {
45
49
  }
46
50
  }
47
51
 
48
- async function init(opts) {
49
- const type = opts["init"] || opts
52
+ async function init(opts: PluginOpts) {
53
+ const type = opts["init"] || (opts as PluginType)
50
54
  if (!type || !PLUGIN_TYPE_ARR.includes(type)) {
51
55
  console.log(
52
56
  error(
@@ -82,7 +86,7 @@ async function init(opts) {
82
86
  } else {
83
87
  console.log(info(`Plugin created in directory "${name}"`))
84
88
  }
85
- captureEvent(AnalyticsEvents.PluginInit, {
89
+ captureEvent(AnalyticsEvent.PluginInit, {
86
90
  type,
87
91
  name,
88
92
  description,
@@ -109,7 +113,7 @@ async function verify() {
109
113
  version = pkgJson.version
110
114
  plugins.validate(schemaJson)
111
115
  return { name, version }
112
- } catch (err) {
116
+ } catch (err: any) {
113
117
  if (err && err.message && err.message.includes("not valid JSON")) {
114
118
  console.log(error(`schema.json is not valid JSON: ${err.message}`))
115
119
  } else {
@@ -120,7 +124,7 @@ async function verify() {
120
124
 
121
125
  async function build() {
122
126
  const verified = await verify()
123
- if (!verified.name) {
127
+ if (!verified?.name) {
124
128
  return
125
129
  }
126
130
  console.log(success("Verified!"))
@@ -132,7 +136,7 @@ async function build() {
132
136
 
133
137
  async function watch() {
134
138
  const verified = await verify()
135
- if (!verified.name) {
139
+ if (!verified?.name) {
136
140
  return
137
141
  }
138
142
  const output = join("dist", `${verified.name}-${verified.version}.tar.gz`)
@@ -150,7 +154,7 @@ async function dev() {
150
154
  const [port] = await fp(10000)
151
155
  const password = "admin"
152
156
  await hostingInit({
153
- init: InitTypes.QUICK,
157
+ init: InitType.QUICK,
154
158
  single: true,
155
159
  watchPluginDir: pluginDir,
156
160
  genUser: password,
@@ -168,7 +172,7 @@ async function dev() {
168
172
  console.log(success("Password: ") + info(password))
169
173
  }
170
174
 
171
- const command = new Command(`${CommandWords.PLUGIN}`)
175
+ export default new Command(`${CommandWord.PLUGIN}`)
172
176
  .addHelp(
173
177
  "Custom plugins for Budibase, init, build and verify your components and datasources with this tool."
174
178
  )
@@ -192,5 +196,3 @@ const command = new Command(`${CommandWords.PLUGIN}`)
192
196
  "Run a development environment which automatically watches the current directory.",
193
197
  dev
194
198
  )
195
-
196
- exports.command = command
@@ -1,21 +1,21 @@
1
- const fetch = require("node-fetch")
1
+ import fetch from "node-fetch"
2
+ import fs from "fs"
3
+ import os from "os"
4
+ import { join } from "path"
5
+ import { processStringSync } from "@budibase/string-templates"
2
6
  const download = require("download")
3
- const fs = require("fs")
4
- const os = require("os")
5
- const { join } = require("path")
6
7
  const tar = require("tar")
7
- const { processStringSync } = require("@budibase/string-templates")
8
8
 
9
9
  const HBS_FILES = ["package.json.hbs", "schema.json.hbs", "README.md.hbs"]
10
10
 
11
- async function getSkeletonUrl(type) {
11
+ async function getSkeletonUrl(type: string) {
12
12
  const resp = await fetch(
13
13
  "https://api.github.com/repos/budibase/budibase-skeleton/releases/latest"
14
14
  )
15
15
  if (resp.status >= 300) {
16
16
  throw new Error("Failed to retrieve skeleton metadata")
17
17
  }
18
- const json = await resp.json()
18
+ const json = (await resp.json()) as { assets: any[] }
19
19
  for (let asset of json["assets"]) {
20
20
  if (asset.name && asset.name.includes(type)) {
21
21
  return asset["browser_download_url"]
@@ -24,7 +24,7 @@ async function getSkeletonUrl(type) {
24
24
  throw new Error("No skeleton found in latest release.")
25
25
  }
26
26
 
27
- exports.getSkeleton = async (type, name) => {
27
+ export async function getSkeleton(type: string, name: string) {
28
28
  const url = await getSkeletonUrl(type)
29
29
  const tarballFile = join(os.tmpdir(), "skeleton.tar.gz")
30
30
 
@@ -40,7 +40,12 @@ exports.getSkeleton = async (type, name) => {
40
40
  fs.rmSync(tarballFile)
41
41
  }
42
42
 
43
- exports.fleshOutSkeleton = async (type, name, description, version) => {
43
+ export async function fleshOutSkeleton(
44
+ type: string,
45
+ name: string,
46
+ description: string,
47
+ version: string
48
+ ) {
44
49
  for (let file of HBS_FILES) {
45
50
  const oldFile = join(name, file),
46
51
  newFile = join(name, file.substring(0, file.length - 4))
@@ -1,7 +1,8 @@
1
- const os = require("os")
2
- const { join } = require("path")
3
- const fs = require("fs")
4
- const { error } = require("./utils")
1
+ import os from "os"
2
+ import { join } from "path"
3
+ import fs from "fs"
4
+ import { error } from "./utils"
5
+
5
6
  const PREBUILDS = "prebuilds"
6
7
  const ARCH = `${os.platform()}-${os.arch()}`
7
8
  const PREBUILD_DIR = join(process.execPath, "..", PREBUILDS, ARCH)
@@ -26,8 +27,8 @@ function checkForBinaries() {
26
27
  }
27
28
  }
28
29
 
29
- function cleanup(evt) {
30
- if (!isNaN(evt)) {
30
+ function cleanup(evt?: number) {
31
+ if (evt && !isNaN(evt)) {
31
32
  return
32
33
  }
33
34
  if (evt) {
@@ -1,6 +1,6 @@
1
1
  const inquirer = require("inquirer")
2
2
 
3
- exports.confirmation = async question => {
3
+ export async function confirmation(question: string) {
4
4
  const config = {
5
5
  type: "confirm",
6
6
  message: question,
@@ -10,8 +10,8 @@ exports.confirmation = async question => {
10
10
  return (await inquirer.prompt(config)).confirmation
11
11
  }
12
12
 
13
- exports.string = async (question, defaultString = null) => {
14
- const config = {
13
+ export async function string(question: string, defaultString?: string) {
14
+ const config: any = {
15
15
  type: "input",
16
16
  name: "string",
17
17
  message: question,
@@ -22,12 +22,12 @@ exports.string = async (question, defaultString = null) => {
22
22
  return (await inquirer.prompt(config)).string
23
23
  }
24
24
 
25
- exports.number = async (question, defaultNumber) => {
26
- const config = {
25
+ export async function number(question: string, defaultNumber?: number) {
26
+ const config: any = {
27
27
  type: "input",
28
28
  name: "number",
29
29
  message: question,
30
- validate: value => {
30
+ validate: (value: string) => {
31
31
  let valid = !isNaN(parseFloat(value))
32
32
  return valid || "Please enter a number"
33
33
  },
@@ -1,19 +1,31 @@
1
- const {
1
+ import {
2
2
  getSubHelpDescription,
3
3
  getHelpDescription,
4
4
  error,
5
5
  capitaliseFirstLetter,
6
- } = require("../utils")
6
+ } from "../utils"
7
7
 
8
- class Command {
9
- constructor(command, func = null) {
8
+ type CommandOpt = {
9
+ command: string
10
+ help: string
11
+ func?: Function
12
+ extras: any[]
13
+ }
14
+
15
+ export class Command {
16
+ command: string
17
+ opts: CommandOpt[]
18
+ func?: Function
19
+ help?: string
20
+
21
+ constructor(command: string, func?: Function) {
10
22
  // if there are options, need to just get the command name
11
23
  this.command = command
12
24
  this.opts = []
13
25
  this.func = func
14
26
  }
15
27
 
16
- convertToCommander(lookup) {
28
+ convertToCommander(lookup: string) {
17
29
  const parts = lookup.toLowerCase().split("-")
18
30
  // camel case, separate out first
19
31
  const first = parts.shift()
@@ -22,21 +34,26 @@ class Command {
22
34
  .join("")
23
35
  }
24
36
 
25
- addHelp(help) {
37
+ addHelp(help: string) {
26
38
  this.help = help
27
39
  return this
28
40
  }
29
41
 
30
- addSubOption(command, help, func, extras = []) {
42
+ addSubOption(
43
+ command: string,
44
+ help: string,
45
+ func?: Function,
46
+ extras: any[] = []
47
+ ) {
31
48
  this.opts.push({ command, help, func, extras })
32
49
  return this
33
50
  }
34
51
 
35
- configure(program) {
52
+ configure(program: any) {
36
53
  const thisCmd = this
37
54
  let command = program.command(thisCmd.command)
38
55
  if (this.help) {
39
- command = command.description(getHelpDescription(thisCmd.help))
56
+ command = command.description(getHelpDescription(thisCmd.help!))
40
57
  }
41
58
  for (let opt of thisCmd.opts) {
42
59
  command = command.option(opt.command, getSubHelpDescription(opt.help))
@@ -45,7 +62,7 @@ class Command {
45
62
  "--help",
46
63
  getSubHelpDescription(`Get help with ${this.command} options`)
47
64
  )
48
- command.action(async options => {
65
+ command.action(async (options: Record<string, string>) => {
49
66
  try {
50
67
  let executed = false,
51
68
  found = false
@@ -53,7 +70,7 @@ class Command {
53
70
  let lookup = opt.command.split(" ")[0].replace("--", "")
54
71
  // need to handle how commander converts watch-plugin-dir to watchPluginDir
55
72
  lookup = this.convertToCommander(lookup)
56
- found = !executed && options[lookup]
73
+ found = !executed && !!options[lookup]
57
74
  if (found && opt.func) {
58
75
  const input =
59
76
  Object.keys(options).length > 1 ? options : options[lookup]
@@ -69,11 +86,9 @@ class Command {
69
86
  console.log(error(`Unknown ${this.command} option.`))
70
87
  command.help()
71
88
  }
72
- } catch (err) {
89
+ } catch (err: any) {
73
90
  console.log(error(err))
74
91
  }
75
92
  })
76
93
  }
77
94
  }
78
-
79
- module.exports = Command
@@ -3,7 +3,9 @@ const path = require("path")
3
3
  const os = require("os")
4
4
  const { error } = require("../utils")
5
5
 
6
- class ConfigManager {
6
+ export class ConfigManager {
7
+ path: string
8
+
7
9
  constructor() {
8
10
  this.path = path.join(os.homedir(), ".budibase.json")
9
11
  if (!fs.existsSync(this.path)) {
@@ -24,26 +26,24 @@ class ConfigManager {
24
26
  }
25
27
  }
26
28
 
27
- set config(json) {
29
+ set config(json: any) {
28
30
  fs.writeFileSync(this.path, JSON.stringify(json))
29
31
  }
30
32
 
31
- getValue(key) {
33
+ getValue(key: string) {
32
34
  return this.config[key]
33
35
  }
34
36
 
35
- setValue(key, value) {
37
+ setValue(key: string, value: any) {
36
38
  this.config = {
37
39
  ...this.config,
38
40
  [key]: value,
39
41
  }
40
42
  }
41
43
 
42
- removeKey(key) {
44
+ removeKey(key: string) {
43
45
  const updated = { ...this.config }
44
46
  delete updated[key]
45
47
  this.config = updated
46
48
  }
47
49
  }
48
-
49
- module.exports = ConfigManager
package/src/utils.ts ADDED
@@ -0,0 +1,112 @@
1
+ import chalk from "chalk"
2
+ import fs from "fs"
3
+ import path from "path"
4
+ import { join } from "path"
5
+ import fetch from "node-fetch"
6
+ const progress = require("cli-progress")
7
+
8
+ export function downloadFile(url: string, filePath: string) {
9
+ return new Promise((resolve, reject) => {
10
+ filePath = path.resolve(filePath)
11
+ fetch(url, {
12
+ method: "GET",
13
+ })
14
+ .then(response => {
15
+ const writer = fs.createWriteStream(filePath)
16
+ if (response.body) {
17
+ response.body.pipe(writer)
18
+ response.body.on("end", resolve)
19
+ response.body.on("error", reject)
20
+ } else {
21
+ throw new Error(
22
+ `Unable to retrieve docker-compose file - ${response.status}`
23
+ )
24
+ }
25
+ })
26
+ .catch(err => {
27
+ throw err
28
+ })
29
+ })
30
+ }
31
+
32
+ export async function httpCall(url: string, method: string) {
33
+ const response = await fetch(url, {
34
+ method,
35
+ })
36
+ return response.body
37
+ }
38
+
39
+ export function getHelpDescription(str: string) {
40
+ return chalk.cyan(str)
41
+ }
42
+
43
+ export function getSubHelpDescription(str: string) {
44
+ return chalk.green(str)
45
+ }
46
+
47
+ export function error(err: string | number) {
48
+ process.exitCode = -1
49
+ return chalk.red(`Error - ${err}`)
50
+ }
51
+
52
+ export function success(str: string) {
53
+ return chalk.green(str)
54
+ }
55
+
56
+ export function info(str: string) {
57
+ return chalk.cyan(str)
58
+ }
59
+
60
+ export function logErrorToFile(file: string, error: string) {
61
+ fs.writeFileSync(path.resolve(`./${file}`), `Budibase Error\n${error}`)
62
+ }
63
+
64
+ export function parseEnv(env: string) {
65
+ const lines = env.toString().split("\n")
66
+ let result: Record<string, string> = {}
67
+ for (const line of lines) {
68
+ const match = line.match(/^([^=:#]+?)[=:](.*)/)
69
+ if (match) {
70
+ result[match[1].trim()] = match[2].trim()
71
+ }
72
+ }
73
+ return result
74
+ }
75
+
76
+ export function progressBar(total: number) {
77
+ const bar = new progress.SingleBar({}, progress.Presets.shades_classic)
78
+ bar.start(total, 0)
79
+ return bar
80
+ }
81
+
82
+ export function checkSlashesInUrl(url: string) {
83
+ return url.replace(/(https?:\/\/)|(\/)+/g, "$1$2")
84
+ }
85
+
86
+ export function moveDirectory(oldPath: string, newPath: string) {
87
+ const files = fs.readdirSync(oldPath)
88
+ // check any file exists already
89
+ for (let file of files) {
90
+ if (fs.existsSync(join(newPath, file))) {
91
+ throw new Error(
92
+ "Unable to remove top level directory - some skeleton files already exist."
93
+ )
94
+ }
95
+ }
96
+ for (let file of files) {
97
+ fs.renameSync(join(oldPath, file), join(newPath, file))
98
+ }
99
+ fs.rmdirSync(oldPath)
100
+ }
101
+
102
+ export function capitaliseFirstLetter(str: string) {
103
+ return str.charAt(0).toUpperCase() + str.slice(1)
104
+ }
105
+
106
+ export function stringifyToDotEnv(json: Record<string, string | number>) {
107
+ let str = ""
108
+ for (let [key, value] of Object.entries(json)) {
109
+ str += `${key}=${value}\n`
110
+ }
111
+ return str
112
+ }
package/start.sh ADDED
@@ -0,0 +1,3 @@
1
+ #!/bin/bash
2
+ dir="$(dirname -- "$(readlink -f "${BASH_SOURCE}")")"
3
+ ${dir}/node_modules/ts-node/dist/bin.js ${dir}/src/index.ts $@