@budibase/cli 1.3.15-alpha.0 → 1.3.16
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 +3 -7
- package/src/constants.js +0 -1
- package/src/index.js +0 -1
- package/src/options.js +1 -2
- package/src/prebuilds.js +2 -14
- package/src/environment.js +0 -1
- package/src/exec.js +0 -27
- package/src/plugins/constants.js +0 -6
- package/src/plugins/index.js +0 -132
- package/src/plugins/skeleton.js +0 -60
- package/src/plugins/validate.js +0 -91
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@budibase/cli",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.16",
|
|
4
4
|
"description": "Budibase CLI, for developers, self hosting and migrations.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -26,18 +26,14 @@
|
|
|
26
26
|
"outputPath": "build"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@budibase/backend-core": "1.3.
|
|
30
|
-
"@budibase/string-templates": "1.3.15-alpha.0",
|
|
31
|
-
"@budibase/types": "1.3.15-alpha.0",
|
|
29
|
+
"@budibase/backend-core": "^1.3.16",
|
|
32
30
|
"axios": "0.21.2",
|
|
33
31
|
"chalk": "4.1.0",
|
|
34
32
|
"cli-progress": "3.11.2",
|
|
35
33
|
"commander": "7.1.0",
|
|
36
34
|
"docker-compose": "0.23.6",
|
|
37
35
|
"dotenv": "16.0.1",
|
|
38
|
-
"download": "8.0.0",
|
|
39
36
|
"inquirer": "8.0.0",
|
|
40
|
-
"joi": "17.6.0",
|
|
41
37
|
"lookpath": "1.1.0",
|
|
42
38
|
"node-fetch": "2",
|
|
43
39
|
"pkg": "5.7.0",
|
|
@@ -52,5 +48,5 @@
|
|
|
52
48
|
"eslint": "^7.20.0",
|
|
53
49
|
"renamer": "^4.0.0"
|
|
54
50
|
},
|
|
55
|
-
"gitHead": "
|
|
51
|
+
"gitHead": "596ee07675e4dc0882ee5bf7a84eadabe8fe54be"
|
|
56
52
|
}
|
package/src/constants.js
CHANGED
package/src/index.js
CHANGED
package/src/options.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
const analytics = require("./analytics")
|
|
2
2
|
const hosting = require("./hosting")
|
|
3
3
|
const backups = require("./backups")
|
|
4
|
-
const plugins = require("./plugins")
|
|
5
4
|
|
|
6
5
|
exports.getCommands = () => {
|
|
7
|
-
return [hosting.command, analytics.command, backups.command
|
|
6
|
+
return [hosting.command, analytics.command, backups.command]
|
|
8
7
|
}
|
package/src/prebuilds.js
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
const os = require("os")
|
|
2
2
|
const { join } = require("path")
|
|
3
3
|
const fs = require("fs")
|
|
4
|
-
const { error } = require("./utils")
|
|
5
4
|
const PREBUILDS = "prebuilds"
|
|
6
5
|
const ARCH = `${os.platform()}-${os.arch()}`
|
|
7
6
|
const PREBUILD_DIR = join(process.execPath, "..", PREBUILDS, ARCH)
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
if (!process.argv[0].includes("node")) {
|
|
11
|
-
checkForBinaries()
|
|
12
|
-
}
|
|
8
|
+
checkForBinaries()
|
|
13
9
|
|
|
14
10
|
function checkForBinaries() {
|
|
15
11
|
const readDir = join(__filename, "..", "..", PREBUILDS, ARCH)
|
|
@@ -26,15 +22,7 @@ function checkForBinaries() {
|
|
|
26
22
|
}
|
|
27
23
|
}
|
|
28
24
|
|
|
29
|
-
function cleanup(
|
|
30
|
-
if (evt && evt.errno) {
|
|
31
|
-
console.error(
|
|
32
|
-
error(
|
|
33
|
-
"Failed to run CLI command - please report with the following message:"
|
|
34
|
-
)
|
|
35
|
-
)
|
|
36
|
-
console.error(error(evt))
|
|
37
|
-
}
|
|
25
|
+
function cleanup() {
|
|
38
26
|
if (fs.existsSync(PREBUILD_DIR)) {
|
|
39
27
|
fs.rmSync(PREBUILD_DIR, { recursive: true })
|
|
40
28
|
}
|
package/src/environment.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
process.env.NO_JS = "1"
|
package/src/exec.js
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
const util = require("util")
|
|
2
|
-
const exec = util.promisify(require("child_process").exec)
|
|
3
|
-
|
|
4
|
-
exports.exec = async (command, dir = "./") => {
|
|
5
|
-
const { stdout } = await exec(command, { cwd: dir })
|
|
6
|
-
return stdout
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
exports.utilityInstalled = async utilName => {
|
|
10
|
-
try {
|
|
11
|
-
await exports.exec(`${utilName} --version`)
|
|
12
|
-
return true
|
|
13
|
-
} catch (err) {
|
|
14
|
-
return false
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
exports.runPkgCommand = async (command, dir = "./") => {
|
|
19
|
-
const yarn = await exports.utilityInstalled("yarn")
|
|
20
|
-
const npm = await exports.utilityInstalled("npm")
|
|
21
|
-
if (!yarn && !npm) {
|
|
22
|
-
throw new Error("Must have yarn or npm installed to run build.")
|
|
23
|
-
}
|
|
24
|
-
const npmCmd = command === "install" ? `npm ${command}` : `npm run ${command}`
|
|
25
|
-
const cmd = yarn ? `yarn ${command}` : npmCmd
|
|
26
|
-
await exports.exec(cmd, dir)
|
|
27
|
-
}
|
package/src/plugins/constants.js
DELETED
package/src/plugins/index.js
DELETED
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
const Command = require("../structures/Command")
|
|
2
|
-
const { CommandWords } = require("../constants")
|
|
3
|
-
const { getSkeleton, fleshOutSkeleton } = require("./skeleton")
|
|
4
|
-
const questions = require("../questions")
|
|
5
|
-
const fs = require("fs")
|
|
6
|
-
const { PLUGIN_TYPES_ARR } = require("./constants")
|
|
7
|
-
const { validate } = require("./validate")
|
|
8
|
-
const { runPkgCommand } = require("../exec")
|
|
9
|
-
const { join } = require("path")
|
|
10
|
-
const { success, error, info } = require("../utils")
|
|
11
|
-
|
|
12
|
-
function checkInPlugin() {
|
|
13
|
-
if (!fs.existsSync("package.json")) {
|
|
14
|
-
throw new Error(
|
|
15
|
-
"Please run in a plugin directory - must contain package.json"
|
|
16
|
-
)
|
|
17
|
-
}
|
|
18
|
-
if (!fs.existsSync("schema.json")) {
|
|
19
|
-
throw new Error(
|
|
20
|
-
"Please run in a plugin directory - must contain schema.json"
|
|
21
|
-
)
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
async function init(opts) {
|
|
26
|
-
const type = opts["init"] || opts
|
|
27
|
-
if (!type || !PLUGIN_TYPES_ARR.includes(type)) {
|
|
28
|
-
console.log(
|
|
29
|
-
error(
|
|
30
|
-
"Please provide a type to init, either 'component' or 'datasource'."
|
|
31
|
-
)
|
|
32
|
-
)
|
|
33
|
-
return
|
|
34
|
-
}
|
|
35
|
-
console.log(info("Lets get some details about your new plugin:"))
|
|
36
|
-
const name = await questions.string("Name", `budibase-${type}`)
|
|
37
|
-
if (fs.existsSync(name)) {
|
|
38
|
-
console.log(
|
|
39
|
-
error("Directory by plugin name already exists, pick a new name.")
|
|
40
|
-
)
|
|
41
|
-
return
|
|
42
|
-
}
|
|
43
|
-
const desc = await questions.string(
|
|
44
|
-
"Description",
|
|
45
|
-
`An amazing Budibase ${type}!`
|
|
46
|
-
)
|
|
47
|
-
const version = await questions.string("Version", "1.0.0")
|
|
48
|
-
// get the skeleton
|
|
49
|
-
console.log(info("Retrieving project..."))
|
|
50
|
-
await getSkeleton(type, name)
|
|
51
|
-
await fleshOutSkeleton(type, name, desc, version)
|
|
52
|
-
console.log(info("Installing dependencies..."))
|
|
53
|
-
await runPkgCommand("install", join(process.cwd(), name))
|
|
54
|
-
console.log(info(`Plugin created in directory "${name}"`))
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
async function verify() {
|
|
58
|
-
// will throw errors if not acceptable
|
|
59
|
-
checkInPlugin()
|
|
60
|
-
console.log(info("Verifying plugin..."))
|
|
61
|
-
const schema = fs.readFileSync("schema.json", "utf8")
|
|
62
|
-
const pkg = fs.readFileSync("package.json", "utf8")
|
|
63
|
-
let name, version
|
|
64
|
-
try {
|
|
65
|
-
const schemaJson = JSON.parse(schema)
|
|
66
|
-
const pkgJson = JSON.parse(pkg)
|
|
67
|
-
if (!pkgJson.name || !pkgJson.version || !pkgJson.description) {
|
|
68
|
-
throw new Error(
|
|
69
|
-
"package.json is missing one of 'name', 'version' or 'description'."
|
|
70
|
-
)
|
|
71
|
-
}
|
|
72
|
-
name = pkgJson.name
|
|
73
|
-
version = pkgJson.version
|
|
74
|
-
validate(schemaJson)
|
|
75
|
-
return { name, version }
|
|
76
|
-
} catch (err) {
|
|
77
|
-
if (err && err.message && err.message.includes("not valid JSON")) {
|
|
78
|
-
console.log(error(`schema.json is not valid JSON: ${err.message}`))
|
|
79
|
-
} else {
|
|
80
|
-
console.log(error(`Invalid schema/package.json: ${err.message}`))
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
async function build() {
|
|
86
|
-
const verified = await verify()
|
|
87
|
-
if (!verified.name) {
|
|
88
|
-
return
|
|
89
|
-
}
|
|
90
|
-
console.log(success("Verified!"))
|
|
91
|
-
console.log(info("Building plugin..."))
|
|
92
|
-
await runPkgCommand("build")
|
|
93
|
-
const output = join("dist", `${verified.name}-${verified.version}.tar.gz`)
|
|
94
|
-
console.log(success(`Build complete - output in: ${output}`))
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
async function watch() {
|
|
98
|
-
const verified = await verify()
|
|
99
|
-
if (!verified.name) {
|
|
100
|
-
return
|
|
101
|
-
}
|
|
102
|
-
const output = join("dist", `${verified.name}-${verified.version}.tar.gz`)
|
|
103
|
-
console.log(info(`Watching - build in: ${output}`))
|
|
104
|
-
try {
|
|
105
|
-
await runPkgCommand("watch")
|
|
106
|
-
} catch (err) {
|
|
107
|
-
// always errors when user escapes
|
|
108
|
-
console.log(success("Watch exited."))
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const command = new Command(`${CommandWords.PLUGIN}`)
|
|
113
|
-
.addHelp(
|
|
114
|
-
"Custom plugins for Budibase, init, build and verify your components and datasources with this tool."
|
|
115
|
-
)
|
|
116
|
-
.addSubOption(
|
|
117
|
-
"--init [type]",
|
|
118
|
-
"Init a new plugin project, with a type of either component or datasource.",
|
|
119
|
-
init
|
|
120
|
-
)
|
|
121
|
-
.addSubOption(
|
|
122
|
-
"--build",
|
|
123
|
-
"Build your plugin, this will verify and produce a final tarball for your project.",
|
|
124
|
-
build
|
|
125
|
-
)
|
|
126
|
-
.addSubOption(
|
|
127
|
-
"--watch",
|
|
128
|
-
"Automatically build any changes to your plugin.",
|
|
129
|
-
watch
|
|
130
|
-
)
|
|
131
|
-
|
|
132
|
-
exports.command = command
|
package/src/plugins/skeleton.js
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
const fetch = require("node-fetch")
|
|
2
|
-
const download = require("download")
|
|
3
|
-
const fs = require("fs")
|
|
4
|
-
const os = require("os")
|
|
5
|
-
const { join } = require("path")
|
|
6
|
-
const tar = require("tar")
|
|
7
|
-
const { processStringSync } = require("@budibase/string-templates")
|
|
8
|
-
|
|
9
|
-
const HBS_FILES = ["package.json.hbs", "schema.json.hbs", "README.md.hbs"]
|
|
10
|
-
|
|
11
|
-
async function getSkeletonUrl(type) {
|
|
12
|
-
const resp = await fetch(
|
|
13
|
-
"https://api.github.com/repos/budibase/budibase-skeleton/releases/latest"
|
|
14
|
-
)
|
|
15
|
-
if (resp.status >= 300) {
|
|
16
|
-
throw new Error("Failed to retrieve skeleton metadata")
|
|
17
|
-
}
|
|
18
|
-
const json = await resp.json()
|
|
19
|
-
for (let asset of json["assets"]) {
|
|
20
|
-
if (asset.name && asset.name.includes(type)) {
|
|
21
|
-
return asset["browser_download_url"]
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
throw new Error("No skeleton found in latest release.")
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
exports.getSkeleton = async (type, name) => {
|
|
28
|
-
const url = await getSkeletonUrl(type)
|
|
29
|
-
const tarballFile = join(os.tmpdir(), "skeleton.tar.gz")
|
|
30
|
-
|
|
31
|
-
// download the full skeleton tarball
|
|
32
|
-
fs.writeFileSync(tarballFile, await download(url))
|
|
33
|
-
fs.mkdirSync(name)
|
|
34
|
-
// extract it and get what we need
|
|
35
|
-
await tar.extract({
|
|
36
|
-
file: tarballFile,
|
|
37
|
-
C: name,
|
|
38
|
-
})
|
|
39
|
-
// clear up
|
|
40
|
-
fs.rmSync(tarballFile)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
exports.fleshOutSkeleton = async (type, name, description, version) => {
|
|
44
|
-
for (let file of HBS_FILES) {
|
|
45
|
-
const oldFile = join(name, file),
|
|
46
|
-
newFile = join(name, file.substring(0, file.length - 4))
|
|
47
|
-
const hbsContents = fs.readFileSync(oldFile, "utf8")
|
|
48
|
-
if (!hbsContents) {
|
|
49
|
-
continue
|
|
50
|
-
}
|
|
51
|
-
const output = processStringSync(hbsContents, {
|
|
52
|
-
name,
|
|
53
|
-
description,
|
|
54
|
-
version,
|
|
55
|
-
})
|
|
56
|
-
// write the updated file and remove the HBS file
|
|
57
|
-
fs.writeFileSync(newFile, output)
|
|
58
|
-
fs.rmSync(oldFile)
|
|
59
|
-
}
|
|
60
|
-
}
|
package/src/plugins/validate.js
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
const { PluginTypes } = require("./constants")
|
|
2
|
-
const { DatasourceFieldType, QueryType } = require("@budibase/types")
|
|
3
|
-
const joi = require("joi")
|
|
4
|
-
|
|
5
|
-
const DATASOURCE_TYPES = [
|
|
6
|
-
"Relational",
|
|
7
|
-
"Non-relational",
|
|
8
|
-
"Spreadsheet",
|
|
9
|
-
"Object store",
|
|
10
|
-
"Graph",
|
|
11
|
-
"API",
|
|
12
|
-
]
|
|
13
|
-
|
|
14
|
-
function runJoi(validator, schema) {
|
|
15
|
-
const { error } = validator.validate(schema)
|
|
16
|
-
if (error) {
|
|
17
|
-
throw error
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function validateComponent(schema) {
|
|
22
|
-
const validator = joi.object({
|
|
23
|
-
type: joi.string().allow("component").required(),
|
|
24
|
-
metadata: joi.object().unknown(true).required(),
|
|
25
|
-
hash: joi.string().optional(),
|
|
26
|
-
version: joi.string().optional(),
|
|
27
|
-
schema: joi
|
|
28
|
-
.object({
|
|
29
|
-
name: joi.string().required(),
|
|
30
|
-
settings: joi.array().items(joi.object().unknown(true)).required(),
|
|
31
|
-
})
|
|
32
|
-
.unknown(true),
|
|
33
|
-
})
|
|
34
|
-
runJoi(validator, schema)
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function validateDatasource(schema) {
|
|
38
|
-
const fieldValidator = joi.object({
|
|
39
|
-
type: joi
|
|
40
|
-
.string()
|
|
41
|
-
.allow(...Object.values(DatasourceFieldType))
|
|
42
|
-
.required(),
|
|
43
|
-
required: joi.boolean().required(),
|
|
44
|
-
default: joi.any(),
|
|
45
|
-
display: joi.string(),
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
const queryValidator = joi
|
|
49
|
-
.object({
|
|
50
|
-
type: joi.string().allow(...Object.values(QueryType)),
|
|
51
|
-
fields: joi.object().pattern(joi.string(), fieldValidator),
|
|
52
|
-
})
|
|
53
|
-
.required()
|
|
54
|
-
|
|
55
|
-
const validator = joi.object({
|
|
56
|
-
type: joi.string().allow("datasource").required(),
|
|
57
|
-
metadata: joi.object().unknown(true).required(),
|
|
58
|
-
hash: joi.string().optional(),
|
|
59
|
-
version: joi.string().optional(),
|
|
60
|
-
schema: joi.object({
|
|
61
|
-
docs: joi.string(),
|
|
62
|
-
friendlyName: joi.string().required(),
|
|
63
|
-
type: joi.string().allow(...DATASOURCE_TYPES),
|
|
64
|
-
description: joi.string().required(),
|
|
65
|
-
datasource: joi.object().pattern(joi.string(), fieldValidator).required(),
|
|
66
|
-
query: joi
|
|
67
|
-
.object({
|
|
68
|
-
create: queryValidator,
|
|
69
|
-
read: queryValidator,
|
|
70
|
-
update: queryValidator,
|
|
71
|
-
delete: queryValidator,
|
|
72
|
-
})
|
|
73
|
-
.unknown(true)
|
|
74
|
-
.required(),
|
|
75
|
-
}),
|
|
76
|
-
})
|
|
77
|
-
runJoi(validator, schema)
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
exports.validate = schema => {
|
|
81
|
-
switch (schema.type) {
|
|
82
|
-
case PluginTypes.COMPONENT:
|
|
83
|
-
validateComponent(schema)
|
|
84
|
-
break
|
|
85
|
-
case PluginTypes.DATASOURCE:
|
|
86
|
-
validateDatasource(schema)
|
|
87
|
-
break
|
|
88
|
-
default:
|
|
89
|
-
throw new Error(`Unknown plugin type - check schema.json: ${schema.type}`)
|
|
90
|
-
}
|
|
91
|
-
}
|