@budibase/cli 1.1.32-alpha.4 → 1.1.32

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@budibase/cli",
3
- "version": "1.1.32-alpha.4",
3
+ "version": "1.1.32",
4
4
  "description": "Budibase CLI, for developers, self hosting and migrations.",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -9,44 +9,29 @@
9
9
  "author": "Budibase",
10
10
  "license": "GPL-3.0",
11
11
  "scripts": {
12
- "prebuild": "rm -rf prebuilds 2> /dev/null && cp -r node_modules/leveldown/prebuilds prebuilds",
13
- "build": "yarn prebuild && renamer --find .node --replace .fake 'prebuilds/**' && pkg . --out-path build && yarn postbuild",
14
- "postbuild": "rm -rf prebuilds 2> /dev/null"
12
+ "build": "pkg . --out-path build"
15
13
  },
16
14
  "pkg": {
17
15
  "targets": [
18
- "node16-linux",
19
- "node16-win",
20
- "node16-macos"
21
- ],
22
- "assets": [
23
- "node_modules/@budibase/backend-core/dist/**/*",
24
- "prebuilds/**/*"
16
+ "node14-linux",
17
+ "node14-win",
18
+ "node14-macos"
25
19
  ],
26
20
  "outputPath": "build"
27
21
  },
28
22
  "dependencies": {
29
- "@budibase/backend-core": "1.1.32-alpha.4",
30
- "axios": "0.21.2",
31
- "chalk": "4.1.0",
32
- "cli-progress": "3.11.2",
33
- "commander": "7.1.0",
34
- "docker-compose": "0.23.6",
35
- "dotenv": "16.0.1",
36
- "inquirer": "8.0.0",
37
- "lookpath": "1.1.0",
38
- "node-fetch": "2",
39
- "pkg": "5.7.0",
23
+ "axios": "^0.21.1",
24
+ "chalk": "^4.1.0",
25
+ "commander": "^7.1.0",
26
+ "docker-compose": "^0.23.6",
27
+ "inquirer": "^8.0.0",
28
+ "lookpath": "^1.1.0",
29
+ "pkg": "^5.3.0",
40
30
  "posthog-node": "1.0.7",
41
- "pouchdb": "7.3.0",
42
- "pouchdb-replication-stream": "1.2.9",
43
- "randomstring": "1.1.5",
44
- "tar": "6.1.11"
31
+ "randomstring": "^1.1.5"
45
32
  },
46
33
  "devDependencies": {
47
- "copyfiles": "^2.4.1",
48
- "eslint": "^7.20.0",
49
- "renamer": "^4.0.0"
34
+ "eslint": "^7.20.0"
50
35
  },
51
- "gitHead": "4b774539ea2654249886264a3284332c91e9b83c"
36
+ "gitHead": "900d5de0723c1b7acf218446507d52755fdf7d83"
52
37
  }
package/src/constants.js CHANGED
@@ -1,5 +1,4 @@
1
1
  exports.CommandWords = {
2
- BACKUPS: "backups",
3
2
  HOSTING: "hosting",
4
3
  ANALYTICS: "analytics",
5
4
  HELP: "help",
package/src/index.js CHANGED
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env node
2
- require("./prebuilds")
3
2
  const { getCommands } = require("./options")
4
3
  const { Command } = require("commander")
5
4
  const { getHelpDescription } = require("./utils")
package/src/options.js CHANGED
@@ -1,7 +1,6 @@
1
1
  const analytics = require("./analytics")
2
2
  const hosting = require("./hosting")
3
- const backups = require("./backups")
4
3
 
5
4
  exports.getCommands = () => {
6
- return [hosting.command, analytics.command, backups.command]
5
+ return [hosting.command, analytics.command]
7
6
  }
@@ -39,10 +39,8 @@ class Command {
39
39
  let executed = false
40
40
  for (let opt of thisCmd.opts) {
41
41
  const lookup = opt.command.split(" ")[0].replace("--", "")
42
- if (!executed && options[lookup]) {
43
- const input =
44
- Object.keys(options).length > 1 ? options : options[lookup]
45
- await opt.func(input)
42
+ if (options[lookup]) {
43
+ await opt.func(options[lookup])
46
44
  executed = true
47
45
  }
48
46
  }
package/src/utils.js CHANGED
@@ -2,7 +2,6 @@ const chalk = require("chalk")
2
2
  const fs = require("fs")
3
3
  const axios = require("axios")
4
4
  const path = require("path")
5
- const progress = require("cli-progress")
6
5
 
7
6
  exports.downloadFile = async (url, filePath) => {
8
7
  filePath = path.resolve(filePath)
@@ -57,13 +56,3 @@ exports.parseEnv = env => {
57
56
  }
58
57
  return result
59
58
  }
60
-
61
- exports.progressBar = total => {
62
- const bar = new progress.SingleBar({}, progress.Presets.shades_classic)
63
- bar.start(total, 0)
64
- return bar
65
- }
66
-
67
- exports.checkSlashesInUrl = url => {
68
- return url.replace(/(https?:\/\/)|(\/)+/g, "$1$2")
69
- }
@@ -1,121 +0,0 @@
1
- const Command = require("../structures/Command")
2
- const { CommandWords } = require("../constants")
3
- const fs = require("fs")
4
- const { join } = require("path")
5
- const { getAllDbs } = require("../core/db")
6
- const tar = require("tar")
7
- const { progressBar } = require("../utils")
8
- const {
9
- TEMP_DIR,
10
- COUCH_DIR,
11
- MINIO_DIR,
12
- getConfig,
13
- replication,
14
- getPouches,
15
- } = require("./utils")
16
- const { exportObjects, importObjects } = require("./objectStore")
17
-
18
- async function exportBackup(opts) {
19
- const envFile = opts.env || undefined
20
- let filename = opts["export"] || opts
21
- if (typeof filename !== "string") {
22
- filename = `backup-${new Date().toISOString()}.tar.gz`
23
- }
24
- const config = await getConfig(envFile)
25
- const dbList = await getAllDbs(config["COUCH_DB_URL"])
26
- const { Remote, Local } = getPouches(config)
27
- if (fs.existsSync(TEMP_DIR)) {
28
- fs.rmSync(TEMP_DIR, { recursive: true })
29
- }
30
- const couchDir = join(TEMP_DIR, COUCH_DIR)
31
- fs.mkdirSync(TEMP_DIR)
32
- fs.mkdirSync(couchDir)
33
- console.log("CouchDB Export")
34
- const bar = progressBar(dbList.length)
35
- let count = 0
36
- for (let db of dbList) {
37
- bar.update(++count)
38
- const remote = new Remote(db)
39
- const local = new Local(join(TEMP_DIR, COUCH_DIR, db))
40
- await replication(remote, local)
41
- }
42
- bar.stop()
43
- console.log("S3 Export")
44
- await exportObjects()
45
- tar.create(
46
- {
47
- sync: true,
48
- gzip: true,
49
- file: filename,
50
- cwd: join(TEMP_DIR),
51
- },
52
- [COUCH_DIR, MINIO_DIR]
53
- )
54
- fs.rmSync(TEMP_DIR, { recursive: true })
55
- console.log(`Generated export file - ${filename}`)
56
- }
57
-
58
- async function importBackup(opts) {
59
- const envFile = opts.env || undefined
60
- const filename = opts["import"] || opts
61
- const config = await getConfig(envFile)
62
- if (!filename || !fs.existsSync(filename)) {
63
- console.error("Cannot import without specifying a valid file to import")
64
- process.exit(-1)
65
- }
66
- if (fs.existsSync(TEMP_DIR)) {
67
- fs.rmSync(TEMP_DIR, { recursive: true })
68
- }
69
- fs.mkdirSync(TEMP_DIR)
70
- tar.extract({
71
- sync: true,
72
- cwd: join(TEMP_DIR),
73
- file: filename,
74
- })
75
- const { Remote, Local } = getPouches(config)
76
- const dbList = fs.readdirSync(join(TEMP_DIR, COUCH_DIR))
77
- console.log("CouchDB Import")
78
- const bar = progressBar(dbList.length)
79
- let count = 0
80
- for (let db of dbList) {
81
- bar.update(++count)
82
- const remote = new Remote(db)
83
- const local = new Local(join(TEMP_DIR, COUCH_DIR, db))
84
- await replication(local, remote)
85
- }
86
- bar.stop()
87
- console.log("MinIO Import")
88
- await importObjects()
89
- console.log("Import complete")
90
- fs.rmSync(TEMP_DIR, { recursive: true })
91
- }
92
-
93
- async function pickOne(opts) {
94
- if (opts["import"]) {
95
- return importBackup(opts)
96
- } else if (opts["export"]) {
97
- return exportBackup(opts)
98
- }
99
- }
100
-
101
- const command = new Command(`${CommandWords.BACKUPS}`)
102
- .addHelp(
103
- "Allows building backups of Budibase, as well as importing a backup to a new instance."
104
- )
105
- .addSubOption(
106
- "--export [filename]",
107
- "Export a backup from an existing Budibase installation.",
108
- exportBackup
109
- )
110
- .addSubOption(
111
- "--import [filename]",
112
- "Import a backup to a new Budibase installation.",
113
- importBackup
114
- )
115
- .addSubOption(
116
- "--env [envFile]",
117
- "Provide an environment variable file to configure the CLI.",
118
- pickOne
119
- )
120
-
121
- exports.command = command
@@ -1,63 +0,0 @@
1
- const {
2
- ObjectStoreBuckets,
3
- ObjectStore,
4
- retrieve,
5
- uploadDirectory,
6
- makeSureBucketExists,
7
- } = require("@budibase/backend-core/objectStore")
8
- const fs = require("fs")
9
- const { join } = require("path")
10
- const { TEMP_DIR, MINIO_DIR } = require("./utils")
11
- const { progressBar } = require("../utils")
12
-
13
- const bucketList = Object.values(ObjectStoreBuckets)
14
-
15
- exports.exportObjects = async () => {
16
- const path = join(TEMP_DIR, MINIO_DIR)
17
- fs.mkdirSync(path)
18
- let fullList = []
19
- for (let bucket of bucketList) {
20
- const client = ObjectStore(bucket)
21
- try {
22
- await client.headBucket().promise()
23
- } catch (err) {
24
- continue
25
- }
26
- const list = await client.listObjectsV2().promise()
27
- fullList = fullList.concat(list.Contents.map(el => ({ ...el, bucket })))
28
- }
29
- const bar = progressBar(fullList.length)
30
- let count = 0
31
- for (let object of fullList) {
32
- const filename = object.Key
33
- const data = await retrieve(object.bucket, filename)
34
- const possiblePath = filename.split("/")
35
- if (possiblePath.length > 1) {
36
- const dirs = possiblePath.slice(0, possiblePath.length - 1)
37
- fs.mkdirSync(join(path, object.bucket, ...dirs), { recursive: true })
38
- }
39
- fs.writeFileSync(join(path, object.bucket, ...possiblePath), data)
40
- bar.update(++count)
41
- }
42
- bar.stop()
43
- }
44
-
45
- exports.importObjects = async () => {
46
- const path = join(TEMP_DIR, MINIO_DIR)
47
- const buckets = fs.readdirSync(path)
48
- let total = 0
49
- buckets.forEach(bucket => {
50
- const files = fs.readdirSync(join(path, bucket))
51
- total += files.length
52
- })
53
- const bar = progressBar(total)
54
- let count = 0
55
- for (let bucket of buckets) {
56
- const client = ObjectStore(bucket)
57
- await makeSureBucketExists(client, bucket)
58
- const files = await uploadDirectory(bucket, join(path, bucket), "/")
59
- count += files.length
60
- bar.update(count)
61
- }
62
- bar.stop()
63
- }
@@ -1,88 +0,0 @@
1
- const dotenv = require("dotenv")
2
- const fs = require("fs")
3
- const { string } = require("../questions")
4
- const { getPouch } = require("../core/db")
5
-
6
- exports.DEFAULT_COUCH = "http://budibase:budibase@localhost:10000/db/"
7
- exports.DEFAULT_MINIO = "http://localhost:10000/"
8
- exports.TEMP_DIR = ".temp"
9
- exports.COUCH_DIR = "couchdb"
10
- exports.MINIO_DIR = "minio"
11
-
12
- const REQUIRED = [
13
- { value: "MAIN_PORT", default: "10000" },
14
- { value: "COUCH_DB_URL", default: exports.DEFAULT_COUCH },
15
- { value: "MINIO_URL", default: exports.DEFAULT_MINIO },
16
- { value: "MINIO_ACCESS_KEY" },
17
- { value: "MINIO_SECRET_KEY" },
18
- ]
19
-
20
- exports.checkURLs = config => {
21
- const mainPort = config["MAIN_PORT"],
22
- username = config["COUCH_DB_USER"],
23
- password = config["COUCH_DB_PASSWORD"]
24
- if (!config["COUCH_DB_URL"] && mainPort && username && password) {
25
- config[
26
- "COUCH_DB_URL"
27
- ] = `http://${username}:${password}@localhost:${mainPort}/db/`
28
- }
29
- if (!config["MINIO_URL"]) {
30
- config["MINIO_URL"] = exports.DEFAULT_MINIO
31
- }
32
- return config
33
- }
34
-
35
- exports.askQuestions = async () => {
36
- console.log(
37
- "*** NOTE: use a .env file to load these parameters repeatedly ***"
38
- )
39
- let config = {}
40
- for (let property of REQUIRED) {
41
- config[property.value] = await string(property.value, property.default)
42
- }
43
- return config
44
- }
45
-
46
- exports.loadEnvironment = path => {
47
- if (!fs.existsSync(path)) {
48
- throw "Unable to file specified .env file"
49
- }
50
- const env = fs.readFileSync(path, "utf8")
51
- const config = exports.checkURLs(dotenv.parse(env))
52
- for (let required of REQUIRED) {
53
- if (!config[required.value]) {
54
- throw `Cannot find "${required.value}" property in .env file`
55
- }
56
- }
57
- return config
58
- }
59
-
60
- // true is the default value passed by commander
61
- exports.getConfig = async (envFile = true) => {
62
- let config
63
- if (envFile !== true) {
64
- config = exports.loadEnvironment(envFile)
65
- } else {
66
- config = await exports.askQuestions()
67
- }
68
- return config
69
- }
70
-
71
- exports.replication = (from, to) => {
72
- return new Promise((resolve, reject) => {
73
- from.replicate
74
- .to(to)
75
- .on("complete", () => {
76
- resolve()
77
- })
78
- .on("error", err => {
79
- reject(err)
80
- })
81
- })
82
- }
83
-
84
- exports.getPouches = config => {
85
- const Remote = getPouch(config["COUCH_DB_URL"])
86
- const Local = getPouch()
87
- return { Remote, Local }
88
- }
package/src/core/db.js DELETED
@@ -1,38 +0,0 @@
1
- const PouchDB = require("pouchdb")
2
- const { checkSlashesInUrl } = require("../utils")
3
- const fetch = require("node-fetch")
4
-
5
- /**
6
- * Fully qualified URL including username and password, or nothing for local
7
- */
8
- exports.getPouch = (url = undefined) => {
9
- let POUCH_DB_DEFAULTS = {}
10
- if (!url) {
11
- POUCH_DB_DEFAULTS = {
12
- prefix: undefined,
13
- adapter: "leveldb",
14
- }
15
- } else {
16
- POUCH_DB_DEFAULTS = {
17
- prefix: url,
18
- }
19
- }
20
- const replicationStream = require("pouchdb-replication-stream")
21
- PouchDB.plugin(replicationStream.plugin)
22
- PouchDB.adapter("writableStream", replicationStream.adapters.writableStream)
23
- return PouchDB.defaults(POUCH_DB_DEFAULTS)
24
- }
25
-
26
- exports.getAllDbs = async url => {
27
- const response = await fetch(
28
- checkSlashesInUrl(encodeURI(`${url}/_all_dbs`)),
29
- {
30
- method: "GET",
31
- }
32
- )
33
- if (response.status === 200) {
34
- return await response.json()
35
- } else {
36
- throw "Cannot connect to CouchDB instance"
37
- }
38
- }
package/src/prebuilds.js DELETED
@@ -1,34 +0,0 @@
1
- const os = require("os")
2
- const { join } = require("path")
3
- const fs = require("fs")
4
- const PREBUILDS = "prebuilds"
5
- const ARCH = `${os.platform()}-${os.arch()}`
6
- const PREBUILD_DIR = join(process.execPath, "..", PREBUILDS, ARCH)
7
-
8
- checkForBinaries()
9
-
10
- function checkForBinaries() {
11
- const readDir = join(__filename, "..", "..", PREBUILDS, ARCH)
12
- if (fs.existsSync(PREBUILD_DIR) || !fs.existsSync(readDir)) {
13
- return
14
- }
15
- const natives = fs.readdirSync(readDir)
16
- if (fs.existsSync(readDir)) {
17
- fs.mkdirSync(PREBUILD_DIR, { recursive: true })
18
- for (let native of natives) {
19
- const filename = `${native.split(".fake")[0]}.node`
20
- fs.cpSync(join(readDir, native), join(PREBUILD_DIR, filename))
21
- }
22
- }
23
- }
24
-
25
- function cleanup() {
26
- if (fs.existsSync(PREBUILD_DIR)) {
27
- fs.rmSync(PREBUILD_DIR, { recursive: true })
28
- }
29
- }
30
-
31
- const events = ["exit", "SIGINT", "SIGUSR1", "SIGUSR2", "uncaughtException"]
32
- events.forEach(event => {
33
- process.on(event, cleanup)
34
- })