@budibase/cli 2.3.18-alpha.3 → 2.3.18-alpha.30
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/dist/analytics/Client.js +32 -0
- package/dist/analytics/index.js +55 -0
- package/dist/backups/index.js +119 -0
- package/dist/backups/objectStore.js +82 -0
- package/dist/backups/utils.js +110 -0
- package/dist/constants.js +9 -0
- package/dist/core/db.js +55 -0
- package/dist/environment.js +4 -0
- package/dist/events.js +13 -0
- package/dist/exec.js +49 -0
- package/dist/hosting/genUser.js +32 -0
- package/dist/hosting/index.js +21 -0
- package/dist/hosting/init.js +117 -0
- package/dist/hosting/makeFiles.js +143 -0
- package/dist/hosting/start.js +63 -0
- package/dist/hosting/status.js +30 -0
- package/dist/hosting/stop.js +30 -0
- package/dist/hosting/types.js +2 -0
- package/dist/hosting/update.js +58 -0
- package/dist/hosting/utils.js +125 -0
- package/dist/hosting/watch.js +47 -0
- package/dist/index.js +36 -0
- package/dist/options.js +14 -0
- package/dist/plugins/index.js +199 -0
- package/dist/plugins/skeleton.js +75 -0
- package/dist/prebuilds.js +46 -0
- package/dist/questions.js +58 -0
- package/dist/structures/Command.js +75 -0
- package/dist/structures/ConfigManager.js +39 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/dist/utils.js +126 -0
- package/package.json +20 -11
- package/src/analytics/Client.ts +33 -0
- package/src/analytics/{index.js → index.ts} +7 -10
- package/src/backups/{index.js → index.ts} +19 -19
- package/src/backups/{objectStore.js → objectStore.ts} +9 -9
- package/src/backups/{utils.js → utils.ts} +24 -19
- package/src/constants.ts +4 -0
- package/src/core/{db.js → db.ts} +8 -7
- package/src/{environment.js → environment.ts} +1 -0
- package/src/events.ts +11 -0
- package/src/{exec.js → exec.ts} +7 -7
- package/src/hosting/{genUser.js → genUser.ts} +4 -3
- package/src/hosting/{index.js → index.ts} +10 -12
- package/src/hosting/{init.js → init.ts} +20 -19
- package/src/hosting/{makeFiles.js → makeFiles.ts} +23 -21
- package/src/hosting/{start.js → start.ts} +6 -10
- package/src/hosting/{status.js → status.ts} +4 -8
- package/src/hosting/{stop.js → stop.ts} +4 -8
- package/src/hosting/types.ts +4 -0
- package/src/hosting/{update.js → update.ts} +10 -10
- package/src/hosting/{utils.js → utils.ts} +26 -23
- package/src/hosting/{watch.js → watch.ts} +7 -6
- package/src/{index.js → index.ts} +5 -5
- package/src/options.ts +8 -0
- package/src/plugins/{index.js → index.ts} +27 -25
- package/src/plugins/{skeleton.js → skeleton.ts} +14 -9
- package/src/{prebuilds.js → prebuilds.ts} +7 -6
- package/src/{questions.js → questions.ts} +6 -6
- package/src/structures/{Command.js → Command.ts} +29 -14
- package/src/structures/{ConfigManager.js → ConfigManager.ts} +7 -7
- package/src/utils.ts +112 -0
- package/start.sh +3 -0
- package/tsconfig.build.json +24 -0
- package/tsconfig.json +30 -0
- package/src/analytics/Client.js +0 -32
- package/src/constants.js +0 -25
- package/src/events.js +0 -11
- package/src/options.js +0 -8
- package/src/utils.js +0 -106
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.AnalyticsClient = void 0;
|
|
7
|
+
const posthog_node_1 = __importDefault(require("posthog-node"));
|
|
8
|
+
const constants_1 = require("../constants");
|
|
9
|
+
const ConfigManager_1 = require("../structures/ConfigManager");
|
|
10
|
+
class AnalyticsClient {
|
|
11
|
+
constructor() {
|
|
12
|
+
this.client = new posthog_node_1.default(constants_1.POSTHOG_TOKEN, {});
|
|
13
|
+
this.configManager = new ConfigManager_1.ConfigManager();
|
|
14
|
+
}
|
|
15
|
+
capture(event) {
|
|
16
|
+
if (this.configManager.config.analyticsDisabled)
|
|
17
|
+
return;
|
|
18
|
+
this.client.capture(event);
|
|
19
|
+
}
|
|
20
|
+
enable() {
|
|
21
|
+
this.configManager.removeKey("analyticsDisabled");
|
|
22
|
+
this.client.capture({ event: constants_1.AnalyticsEvent.OptIn, distinctId: "cli" });
|
|
23
|
+
}
|
|
24
|
+
disable() {
|
|
25
|
+
this.client.capture({ event: constants_1.AnalyticsEvent.OptOut, distinctId: "cli" });
|
|
26
|
+
this.configManager.setValue("analyticsDisabled", true);
|
|
27
|
+
}
|
|
28
|
+
status() {
|
|
29
|
+
return this.configManager.config.analyticsDisabled ? "disabled" : "enabled";
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
exports.AnalyticsClient = AnalyticsClient;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const Command_1 = require("../structures/Command");
|
|
13
|
+
const constants_1 = require("../constants");
|
|
14
|
+
const utils_1 = require("../utils");
|
|
15
|
+
const Client_1 = require("./Client");
|
|
16
|
+
const client = new Client_1.AnalyticsClient();
|
|
17
|
+
function optOut() {
|
|
18
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
19
|
+
try {
|
|
20
|
+
// opt them out
|
|
21
|
+
client.disable();
|
|
22
|
+
console.log((0, utils_1.success)("Successfully opted out of Budibase analytics. You can opt in at any time by running 'budi analytics opt-in'"));
|
|
23
|
+
}
|
|
24
|
+
catch (err) {
|
|
25
|
+
console.log((0, utils_1.error)(`Error opting out of Budibase analytics. Please try again later - ${err}`));
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
function optIn() {
|
|
30
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
31
|
+
try {
|
|
32
|
+
// opt them in
|
|
33
|
+
client.enable();
|
|
34
|
+
console.log((0, utils_1.success)("Successfully opted in to Budibase analytics. Thank you for helping us make Budibase better!"));
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
console.log((0, utils_1.error)("Error opting in to Budibase analytics. Please try again later."));
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
function status() {
|
|
42
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
43
|
+
try {
|
|
44
|
+
console.log((0, utils_1.success)(`Budibase analytics ${client.status()}`));
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
console.log((0, utils_1.error)("Error fetching analytics status. Please try again later."));
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
exports.default = new Command_1.Command(`${constants_1.CommandWord.ANALYTICS}`)
|
|
52
|
+
.addHelp("Control the analytics you send to Budibase.")
|
|
53
|
+
.addSubOption("--optin", "Opt in to sending analytics to Budibase", optIn)
|
|
54
|
+
.addSubOption("--optout", "Opt out of sending analytics to Budibase.", optOut)
|
|
55
|
+
.addSubOption("--status", "Check whether you are currently opted in to Budibase analytics.", status);
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const Command_1 = require("../structures/Command");
|
|
16
|
+
const constants_1 = require("../constants");
|
|
17
|
+
const fs_1 = __importDefault(require("fs"));
|
|
18
|
+
const path_1 = require("path");
|
|
19
|
+
const db_1 = require("../core/db");
|
|
20
|
+
const utils_1 = require("../utils");
|
|
21
|
+
const utils_2 = require("./utils");
|
|
22
|
+
const objectStore_1 = require("./objectStore");
|
|
23
|
+
const tar = require("tar");
|
|
24
|
+
function exportBackup(opts) {
|
|
25
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26
|
+
const envFile = opts.env || undefined;
|
|
27
|
+
let filename = opts["export"] || opts;
|
|
28
|
+
if (typeof filename !== "string") {
|
|
29
|
+
filename = `backup-${new Date().toISOString()}.tar.gz`;
|
|
30
|
+
}
|
|
31
|
+
const config = yield (0, utils_2.getConfig)(envFile);
|
|
32
|
+
const dbList = (yield (0, db_1.getAllDbs)(config["COUCH_DB_URL"]));
|
|
33
|
+
const { Remote, Local } = (0, utils_2.getPouches)(config);
|
|
34
|
+
if (fs_1.default.existsSync(utils_2.TEMP_DIR)) {
|
|
35
|
+
fs_1.default.rmSync(utils_2.TEMP_DIR, { recursive: true });
|
|
36
|
+
}
|
|
37
|
+
const couchDir = (0, path_1.join)(utils_2.TEMP_DIR, utils_2.COUCH_DIR);
|
|
38
|
+
fs_1.default.mkdirSync(utils_2.TEMP_DIR);
|
|
39
|
+
fs_1.default.mkdirSync(couchDir);
|
|
40
|
+
console.log("CouchDB Export");
|
|
41
|
+
const bar = (0, utils_1.progressBar)(dbList.length);
|
|
42
|
+
let count = 0;
|
|
43
|
+
for (let db of dbList) {
|
|
44
|
+
bar.update(++count);
|
|
45
|
+
const remote = new Remote(db);
|
|
46
|
+
const local = new Local((0, path_1.join)(utils_2.TEMP_DIR, utils_2.COUCH_DIR, db));
|
|
47
|
+
yield (0, utils_2.replication)(remote, local);
|
|
48
|
+
}
|
|
49
|
+
bar.stop();
|
|
50
|
+
console.log("S3 Export");
|
|
51
|
+
yield (0, objectStore_1.exportObjects)();
|
|
52
|
+
tar.create({
|
|
53
|
+
sync: true,
|
|
54
|
+
gzip: true,
|
|
55
|
+
file: filename,
|
|
56
|
+
cwd: (0, path_1.join)(utils_2.TEMP_DIR),
|
|
57
|
+
}, [utils_2.COUCH_DIR, utils_2.MINIO_DIR]);
|
|
58
|
+
fs_1.default.rmSync(utils_2.TEMP_DIR, { recursive: true });
|
|
59
|
+
console.log(`Generated export file - ${filename}`);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
function importBackup(opts) {
|
|
63
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
64
|
+
const envFile = opts.env || undefined;
|
|
65
|
+
const filename = opts["import"] || opts;
|
|
66
|
+
const config = yield (0, utils_2.getConfig)(envFile);
|
|
67
|
+
if (!filename || !fs_1.default.existsSync(filename)) {
|
|
68
|
+
console.error("Cannot import without specifying a valid file to import");
|
|
69
|
+
process.exit(-1);
|
|
70
|
+
}
|
|
71
|
+
if (fs_1.default.existsSync(utils_2.TEMP_DIR)) {
|
|
72
|
+
fs_1.default.rmSync(utils_2.TEMP_DIR, { recursive: true });
|
|
73
|
+
}
|
|
74
|
+
fs_1.default.mkdirSync(utils_2.TEMP_DIR);
|
|
75
|
+
tar.extract({
|
|
76
|
+
sync: true,
|
|
77
|
+
cwd: (0, path_1.join)(utils_2.TEMP_DIR),
|
|
78
|
+
file: filename,
|
|
79
|
+
});
|
|
80
|
+
const { Remote, Local } = (0, utils_2.getPouches)(config);
|
|
81
|
+
const dbList = fs_1.default.readdirSync((0, path_1.join)(utils_2.TEMP_DIR, utils_2.COUCH_DIR));
|
|
82
|
+
console.log("CouchDB Import");
|
|
83
|
+
const bar = (0, utils_1.progressBar)(dbList.length);
|
|
84
|
+
let count = 0;
|
|
85
|
+
for (let db of dbList) {
|
|
86
|
+
bar.update(++count);
|
|
87
|
+
const remote = new Remote(db);
|
|
88
|
+
const local = new Local((0, path_1.join)(utils_2.TEMP_DIR, utils_2.COUCH_DIR, db));
|
|
89
|
+
yield (0, utils_2.replication)(local, remote);
|
|
90
|
+
}
|
|
91
|
+
bar.stop();
|
|
92
|
+
console.log("MinIO Import");
|
|
93
|
+
yield (0, objectStore_1.importObjects)();
|
|
94
|
+
// finish by letting the system know that a restore has occurred
|
|
95
|
+
try {
|
|
96
|
+
yield (0, utils_1.httpCall)(`http://localhost:${config.MAIN_PORT}/api/system/restored`, "POST");
|
|
97
|
+
}
|
|
98
|
+
catch (err) {
|
|
99
|
+
// ignore error - it will be an older system
|
|
100
|
+
}
|
|
101
|
+
console.log("Import complete");
|
|
102
|
+
fs_1.default.rmSync(utils_2.TEMP_DIR, { recursive: true });
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
function pickOne(opts) {
|
|
106
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
107
|
+
if (opts["import"]) {
|
|
108
|
+
return importBackup(opts);
|
|
109
|
+
}
|
|
110
|
+
else if (opts["export"]) {
|
|
111
|
+
return exportBackup(opts);
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
exports.default = new Command_1.Command(`${constants_1.CommandWord.BACKUPS}`)
|
|
116
|
+
.addHelp("Allows building backups of Budibase, as well as importing a backup to a new instance.")
|
|
117
|
+
.addSubOption("--export [filename]", "Export a backup from an existing Budibase installation.", exportBackup)
|
|
118
|
+
.addSubOption("--import [filename]", "Import a backup to a new Budibase installation.", importBackup)
|
|
119
|
+
.addSubOption("--env [envFile]", "Provide an environment variable file to configure the CLI.", pickOne);
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.importObjects = exports.exportObjects = void 0;
|
|
16
|
+
const backend_core_1 = require("@budibase/backend-core");
|
|
17
|
+
const fs_1 = __importDefault(require("fs"));
|
|
18
|
+
const path_1 = require("path");
|
|
19
|
+
const utils_1 = require("./utils");
|
|
20
|
+
const utils_2 = require("../utils");
|
|
21
|
+
const { ObjectStoreBuckets, ObjectStore, retrieve, uploadDirectory, makeSureBucketExists, } = backend_core_1.objectStore;
|
|
22
|
+
const bucketList = Object.values(ObjectStoreBuckets);
|
|
23
|
+
function exportObjects() {
|
|
24
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
25
|
+
const path = (0, path_1.join)(utils_1.TEMP_DIR, utils_1.MINIO_DIR);
|
|
26
|
+
fs_1.default.mkdirSync(path);
|
|
27
|
+
let fullList = [];
|
|
28
|
+
let errorCount = 0;
|
|
29
|
+
for (let bucket of bucketList) {
|
|
30
|
+
const client = ObjectStore(bucket);
|
|
31
|
+
try {
|
|
32
|
+
yield client.headBucket().promise();
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
errorCount++;
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
const list = (yield client.listObjectsV2().promise());
|
|
39
|
+
fullList = fullList.concat(list.Contents.map(el => (Object.assign(Object.assign({}, el), { bucket }))));
|
|
40
|
+
}
|
|
41
|
+
if (errorCount === bucketList.length) {
|
|
42
|
+
throw new Error("Unable to access MinIO/S3 - check environment config.");
|
|
43
|
+
}
|
|
44
|
+
const bar = (0, utils_2.progressBar)(fullList.length);
|
|
45
|
+
let count = 0;
|
|
46
|
+
for (let object of fullList) {
|
|
47
|
+
const filename = object.Key;
|
|
48
|
+
const data = yield retrieve(object.bucket, filename);
|
|
49
|
+
const possiblePath = filename.split("/");
|
|
50
|
+
if (possiblePath.length > 1) {
|
|
51
|
+
const dirs = possiblePath.slice(0, possiblePath.length - 1);
|
|
52
|
+
fs_1.default.mkdirSync((0, path_1.join)(path, object.bucket, ...dirs), { recursive: true });
|
|
53
|
+
}
|
|
54
|
+
fs_1.default.writeFileSync((0, path_1.join)(path, object.bucket, ...possiblePath), data);
|
|
55
|
+
bar.update(++count);
|
|
56
|
+
}
|
|
57
|
+
bar.stop();
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
exports.exportObjects = exportObjects;
|
|
61
|
+
function importObjects() {
|
|
62
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
63
|
+
const path = (0, path_1.join)(utils_1.TEMP_DIR, utils_1.MINIO_DIR);
|
|
64
|
+
const buckets = fs_1.default.readdirSync(path);
|
|
65
|
+
let total = 0;
|
|
66
|
+
buckets.forEach(bucket => {
|
|
67
|
+
const files = fs_1.default.readdirSync((0, path_1.join)(path, bucket));
|
|
68
|
+
total += files.length;
|
|
69
|
+
});
|
|
70
|
+
const bar = (0, utils_2.progressBar)(total);
|
|
71
|
+
let count = 0;
|
|
72
|
+
for (let bucket of buckets) {
|
|
73
|
+
const client = ObjectStore(bucket);
|
|
74
|
+
yield makeSureBucketExists(client, bucket);
|
|
75
|
+
const files = yield uploadDirectory(bucket, (0, path_1.join)(path, bucket), "/");
|
|
76
|
+
count += files.length;
|
|
77
|
+
bar.update(count);
|
|
78
|
+
}
|
|
79
|
+
bar.stop();
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
exports.importObjects = importObjects;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.getPouches = exports.replication = exports.getConfig = exports.loadEnvironment = exports.askQuestions = exports.checkURLs = exports.MINIO_DIR = exports.COUCH_DIR = exports.TEMP_DIR = void 0;
|
|
16
|
+
const dotenv_1 = __importDefault(require("dotenv"));
|
|
17
|
+
const fs_1 = __importDefault(require("fs"));
|
|
18
|
+
const questions_1 = require("../questions");
|
|
19
|
+
const db_1 = require("../core/db");
|
|
20
|
+
const backend_core_1 = require("@budibase/backend-core");
|
|
21
|
+
exports.TEMP_DIR = ".temp";
|
|
22
|
+
exports.COUCH_DIR = "couchdb";
|
|
23
|
+
exports.MINIO_DIR = "minio";
|
|
24
|
+
const REQUIRED = [
|
|
25
|
+
{ value: "MAIN_PORT", default: "10000" },
|
|
26
|
+
{
|
|
27
|
+
value: "COUCH_DB_URL",
|
|
28
|
+
default: "http://budibase:budibase@localhost:10000/db/",
|
|
29
|
+
},
|
|
30
|
+
{ value: "MINIO_URL", default: "http://localhost:10000" },
|
|
31
|
+
{ value: "MINIO_ACCESS_KEY" },
|
|
32
|
+
{ value: "MINIO_SECRET_KEY" },
|
|
33
|
+
];
|
|
34
|
+
function checkURLs(config) {
|
|
35
|
+
const mainPort = config["MAIN_PORT"], username = config["COUCH_DB_USER"], password = config["COUCH_DB_PASSWORD"];
|
|
36
|
+
if (!config["COUCH_DB_URL"] && mainPort && username && password) {
|
|
37
|
+
config["COUCH_DB_URL"] = `http://${username}:${password}@localhost:${mainPort}/db/`;
|
|
38
|
+
}
|
|
39
|
+
if (!config["MINIO_URL"]) {
|
|
40
|
+
config["MINIO_URL"] = `http://localhost:${mainPort}/`;
|
|
41
|
+
}
|
|
42
|
+
return config;
|
|
43
|
+
}
|
|
44
|
+
exports.checkURLs = checkURLs;
|
|
45
|
+
function askQuestions() {
|
|
46
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
47
|
+
console.log("*** NOTE: use a .env file to load these parameters repeatedly ***");
|
|
48
|
+
let config = {};
|
|
49
|
+
for (let property of REQUIRED) {
|
|
50
|
+
config[property.value] = yield (0, questions_1.string)(property.value, property.default);
|
|
51
|
+
}
|
|
52
|
+
return config;
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
exports.askQuestions = askQuestions;
|
|
56
|
+
function loadEnvironment(path) {
|
|
57
|
+
if (!fs_1.default.existsSync(path)) {
|
|
58
|
+
throw "Unable to file specified .env file";
|
|
59
|
+
}
|
|
60
|
+
const env = fs_1.default.readFileSync(path, "utf8");
|
|
61
|
+
const config = checkURLs(dotenv_1.default.parse(env));
|
|
62
|
+
for (let required of REQUIRED) {
|
|
63
|
+
if (!config[required.value]) {
|
|
64
|
+
throw `Cannot find "${required.value}" property in .env file`;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return config;
|
|
68
|
+
}
|
|
69
|
+
exports.loadEnvironment = loadEnvironment;
|
|
70
|
+
// true is the default value passed by commander
|
|
71
|
+
function getConfig(envFile = true) {
|
|
72
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
73
|
+
let config;
|
|
74
|
+
if (envFile !== true) {
|
|
75
|
+
config = loadEnvironment(envFile);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
config = yield askQuestions();
|
|
79
|
+
}
|
|
80
|
+
// fill out environment
|
|
81
|
+
for (let key of Object.keys(config)) {
|
|
82
|
+
backend_core_1.env._set(key, config[key]);
|
|
83
|
+
}
|
|
84
|
+
return config;
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
exports.getConfig = getConfig;
|
|
88
|
+
function replication(from, to) {
|
|
89
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
90
|
+
const pouch = (0, db_1.getPouch)();
|
|
91
|
+
try {
|
|
92
|
+
yield pouch.replicate(from, to, {
|
|
93
|
+
batch_size: 1000,
|
|
94
|
+
batches_limit: 5,
|
|
95
|
+
// @ts-ignore
|
|
96
|
+
style: "main_only",
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
catch (err) {
|
|
100
|
+
throw new Error(`Replication failed - ${JSON.stringify(err)}`);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
exports.replication = replication;
|
|
105
|
+
function getPouches(config) {
|
|
106
|
+
const Remote = (0, db_1.getPouch)(config["COUCH_DB_URL"]);
|
|
107
|
+
const Local = (0, db_1.getPouch)();
|
|
108
|
+
return { Remote, Local };
|
|
109
|
+
}
|
|
110
|
+
exports.getPouches = getPouches;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GENERATED_USER_EMAIL = exports.POSTHOG_TOKEN = exports.AnalyticsEvent = exports.InitType = exports.CommandWord = void 0;
|
|
4
|
+
var types_1 = require("@budibase/types");
|
|
5
|
+
Object.defineProperty(exports, "CommandWord", { enumerable: true, get: function () { return types_1.CommandWord; } });
|
|
6
|
+
Object.defineProperty(exports, "InitType", { enumerable: true, get: function () { return types_1.InitType; } });
|
|
7
|
+
Object.defineProperty(exports, "AnalyticsEvent", { enumerable: true, get: function () { return types_1.AnalyticsEvent; } });
|
|
8
|
+
exports.POSTHOG_TOKEN = "phc_yGOn4i7jWKaCTapdGR6lfA4AvmuEQ2ijn5zAVSFYPlS";
|
|
9
|
+
exports.GENERATED_USER_EMAIL = "admin@admin.com";
|
package/dist/core/db.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.getAllDbs = exports.getPouch = void 0;
|
|
16
|
+
const pouchdb_1 = __importDefault(require("pouchdb"));
|
|
17
|
+
const utils_1 = require("../utils");
|
|
18
|
+
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
19
|
+
/**
|
|
20
|
+
* Fully qualified URL including username and password, or nothing for local
|
|
21
|
+
*/
|
|
22
|
+
function getPouch(url) {
|
|
23
|
+
let POUCH_DB_DEFAULTS;
|
|
24
|
+
if (!url) {
|
|
25
|
+
POUCH_DB_DEFAULTS = {
|
|
26
|
+
prefix: undefined,
|
|
27
|
+
adapter: "leveldb",
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
POUCH_DB_DEFAULTS = {
|
|
32
|
+
prefix: url,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
const replicationStream = require("pouchdb-replication-stream");
|
|
36
|
+
pouchdb_1.default.plugin(replicationStream.plugin);
|
|
37
|
+
// @ts-ignore
|
|
38
|
+
pouchdb_1.default.adapter("writableStream", replicationStream.adapters.writableStream);
|
|
39
|
+
return pouchdb_1.default.defaults(POUCH_DB_DEFAULTS);
|
|
40
|
+
}
|
|
41
|
+
exports.getPouch = getPouch;
|
|
42
|
+
function getAllDbs(url) {
|
|
43
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
44
|
+
const response = yield (0, node_fetch_1.default)((0, utils_1.checkSlashesInUrl)(encodeURI(`${url}/_all_dbs`)), {
|
|
45
|
+
method: "GET",
|
|
46
|
+
});
|
|
47
|
+
if (response.status === 200) {
|
|
48
|
+
return yield response.json();
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
throw "Cannot connect to CouchDB instance";
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
exports.getAllDbs = getAllDbs;
|
package/dist/events.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.captureEvent = void 0;
|
|
4
|
+
const Client_1 = require("./analytics/Client");
|
|
5
|
+
const client = new Client_1.AnalyticsClient();
|
|
6
|
+
function captureEvent(event, properties) {
|
|
7
|
+
client.capture({
|
|
8
|
+
distinctId: "cli",
|
|
9
|
+
event,
|
|
10
|
+
properties,
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
exports.captureEvent = captureEvent;
|
package/dist/exec.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.runPkgCommand = exports.utilityInstalled = exports.exec = void 0;
|
|
16
|
+
const util_1 = __importDefault(require("util"));
|
|
17
|
+
const runCommand = util_1.default.promisify(require("child_process").exec);
|
|
18
|
+
function exec(command, dir = "./") {
|
|
19
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
20
|
+
const { stdout } = yield runCommand(command, { cwd: dir });
|
|
21
|
+
return stdout;
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
exports.exec = exec;
|
|
25
|
+
function utilityInstalled(utilName) {
|
|
26
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
27
|
+
try {
|
|
28
|
+
yield exec(`${utilName} --version`);
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
exports.utilityInstalled = utilityInstalled;
|
|
37
|
+
function runPkgCommand(command, dir = "./") {
|
|
38
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
39
|
+
const yarn = yield exports.utilityInstalled("yarn");
|
|
40
|
+
const npm = yield exports.utilityInstalled("npm");
|
|
41
|
+
if (!yarn && !npm) {
|
|
42
|
+
throw new Error("Must have yarn or npm installed to run build.");
|
|
43
|
+
}
|
|
44
|
+
const npmCmd = command === "install" ? `npm ${command}` : `npm run ${command}`;
|
|
45
|
+
const cmd = yarn ? `yarn ${command} --ignore-engines` : npmCmd;
|
|
46
|
+
yield exports.exec(cmd, dir);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
exports.runPkgCommand = runPkgCommand;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.generateUser = void 0;
|
|
13
|
+
const { success } = require("../utils");
|
|
14
|
+
const { updateDockerComposeService } = require("./utils");
|
|
15
|
+
const randomString = require("randomstring");
|
|
16
|
+
const { GENERATED_USER_EMAIL } = require("../constants");
|
|
17
|
+
function generateUser(password, silent) {
|
|
18
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
19
|
+
const email = GENERATED_USER_EMAIL;
|
|
20
|
+
if (!password) {
|
|
21
|
+
password = randomString.generate({ length: 6 });
|
|
22
|
+
}
|
|
23
|
+
updateDockerComposeService((service) => {
|
|
24
|
+
service.environment["BB_ADMIN_USER_EMAIL"] = email;
|
|
25
|
+
service.environment["BB_ADMIN_USER_PASSWORD"] = password;
|
|
26
|
+
});
|
|
27
|
+
if (!silent) {
|
|
28
|
+
console.log(success(`User admin credentials configured, access with email: ${email} - password: ${password}`));
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
exports.generateUser = generateUser;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const Command_1 = require("../structures/Command");
|
|
4
|
+
const constants_1 = require("../constants");
|
|
5
|
+
const init_1 = require("./init");
|
|
6
|
+
const start_1 = require("./start");
|
|
7
|
+
const stop_1 = require("./stop");
|
|
8
|
+
const status_1 = require("./status");
|
|
9
|
+
const update_1 = require("./update");
|
|
10
|
+
const genUser_1 = require("./genUser");
|
|
11
|
+
const watch_1 = require("./watch");
|
|
12
|
+
exports.default = new Command_1.Command(`${constants_1.CommandWord.HOSTING}`)
|
|
13
|
+
.addHelp("Controls self hosting on the Budibase platform.")
|
|
14
|
+
.addSubOption("--init [type]", "Configure a self hosted platform in current directory, type can be unspecified, 'quick' or 'single'.", init_1.init)
|
|
15
|
+
.addSubOption("--start", "Start the configured platform in current directory.", start_1.start)
|
|
16
|
+
.addSubOption("--status", "Check the status of currently running services.", status_1.status)
|
|
17
|
+
.addSubOption("--stop", "Stop the configured platform in the current directory.", stop_1.stop)
|
|
18
|
+
.addSubOption("--update", "Update the Budibase images to the latest version.", update_1.update)
|
|
19
|
+
.addSubOption("--watch-plugin-dir [directory]", "Add plugin directory watching to a Budibase install.", watch_1.watchPlugins)
|
|
20
|
+
.addSubOption("--gen-user", "Create an admin user automatically as part of first start.", genUser_1.generateUser)
|
|
21
|
+
.addSubOption("--single", "Specify this with init to use the single image.");
|