Skip to content

Commit 0343255

Browse files
committed
get files recursively for qb deploy, forcefully require Node 8+, run
everything through prettier, and update README
1 parent cddd2fe commit 0343255

15 files changed

Lines changed: 1542 additions & 685 deletions

README.md

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,30 @@
33

44
Writing custom code inside QuickBase sucks. Copy/pasting from your editor sucks. This simple command line tool lets you easily upload your local code files to a QuickBase application so you don't have to do either of those.
55

6-
### Installation
7-
Requirements: [Node.js](https://nodejs.org/en/) and [Git](https://git-scm.com/).
6+
## Installation
7+
Requirements: [Node.js](https://nodejs.org/en/) >= 8
88

99
```bash
1010
npm install -g quickbase-cli
1111
```
1212

13-
### Usage
14-
quickbase-cli can be used on it's own for basic QuickBase code pages, or in conjunction with modern cli tools (angular cli, create-react-app, vue cli, etc.) for an improved QuickBase development workflow.
13+
## Usage
14+
quickbase-cli can be used for basic QuickBase code page development. It's possible to use quickbase-cli with modern SPA cli tools (angular cli, create-react-app, vue cli, etc.), but there are some pretty significant caveats. Check out the `qb deploy` command options (`-x` specifically) for details.
1515

1616
There are three commands available for quickbase-cli:
1717
- qb init
1818
- qb deploy
1919
- qb new
2020

21-
#### qb init
21+
### qb init
2222
```bash
2323
qb init
2424
```
25+
**This is required in order to use the `qb deploy` command.**
2526

26-
Initialize an existing app with quickbase-cli functionality. Respond to the prompts to create a config file called `quickbase-cli.config.js` which is used by other quickbase-cli commands. Below are the prompts:
27+
Initialize an existing app with quickbase-cli functionality. Respond to the prompts to create a config file called `quickbase-cli.config.js` which is used by other quickbase-cli commands. Run `qb init` from the root of your application, as the config file will be placed wherever the command is run.
28+
29+
Below are the prompts (see the [Notes](#notes) below for an important advisory re: entering your QuickBase password when prompted):
2730

2831
```javascript
2932
{
@@ -52,15 +55,11 @@ Initialize an existing app with quickbase-cli functionality. Respond to the prom
5255
}
5356
```
5457

55-
Run `qb init` from the root of your application, as the config file will be placed wherever the command is run.
56-
57-
See the [Notes](#notes) below for an important advisory re: entering your QuickBase password when prompted.
58-
59-
#### qb deploy
58+
### qb deploy
6059
```bash
6160
qb deploy [options] <file path or directory>
6261

63-
# example
62+
# examples
6463
qb deploy -w app/index.js
6564
qb deploy -x dist/
6665
qb deploy -wx build/bundle.js
@@ -70,11 +69,13 @@ This will upload the file(s) at `<file path or directory>` to the QuickBase appl
7069

7170
**If no `<file path or directory>` is given then the current directory will be deployed.**
7271

73-
There are two optional flags that can be passed to qb deploy. You can use them individually or multiple at a time:
72+
**THAT WAS AN IMPORTANT FACT, PAY ATTENTION WHEN RUNNING `qb deploy` -- DON'T UPLOAD YOUR NODE_MODULES DIRECTORY TO QUICKBASE...**
73+
74+
There are two optional flags that can be passed to `qb deploy`. You can use them individually or multiple at a time:
7475
- `-w` (or `--watch`): watch for changes to `<file path or directory>` and deploy to QuickBase on change. After the initial deploy only the file that changes will be uploaded to QuickBase.
75-
- `-x` (or `--replace`): If you pass a directory to `qb deploy` then all .html files will run through a regex to replace asset file includes (i.e. `<script src="bundle.js"></script>` and/or `<link href="bundle.css"/>`) with their new QuickBase urls (`<script src="realm.quickbase.com/db/dbayemay?a=dbpage&pageID=123"></script>`)
76+
- `-x` (or `--replace`): If you pass a directory to `qb deploy` then all .html files will run through a regex to replace asset file includes (i.e. `<script src="bundle.js"></script>` and/or `<link href="bundle.css"/>`) with their new QuickBase urls (`<script src="realm.quickbase.com/db/dbayemay?a=dbpage&pageID=123"></script>`). **Only .html files will have asset paths replaced, which means any asset paths inside your javascript (including React `<img />` src attributes) won't be replaced.** This is a good chunk of effort to implement efficiently, so I'll leave that as a potential path to greatness for anyone willing to put in the effort (PRs are always welcome).
7677

77-
#### qb new
78+
### qb new (mostly useless)
7879
```bash
7980
qb new <github-repo> <project-name>
8081

@@ -87,8 +88,10 @@ This command will start a new application by cloning a Github repo from `<github
8788
For now this is only a wrapper around `git clone`. After you pull down a repo you will need to run `qb init` if the app doesn't have a `quickbase-cli.config.js` file in it already. The end goal is to have starter-template repos available for quick and easy kick off.
8889

8990

90-
### Notes
91+
## Notes
9192

9293
* Instead of exposing your password for the `quickbase-cli.config.js` file you can rely on an environment variable called `QUICKBASE_CLI_PASSWORD`. If you have that variable defined and leave the `password` empty when prompted the `qb deploy` command will use it instead. Always practice safe passwords.
9394

94-
* Moves are being made to add cool shit like a build process, global defaults, awesome starter templates, and pulling down existing code files from QuickBase. They're not out yet, so for now you're on your own.
95+
* ~~Moves are being made to add cool shit like a build process, global defaults, awesome starter templates, and pulling down existing code files from QuickBase. They're not out yet, so for now you're on your own.~~
96+
97+
* I no longer work with QuickBase applications, so the cool shit I had planned won't happen unless someone submits some dope ass pull requests.

bin/qb-deploy.js

Lines changed: 76 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -3,93 +3,118 @@
33
// TODO:
44
// confirm files w/user before uploading?
55

6-
let ApiClient = require('../lib/api')
7-
let fs = require('fs')
8-
let path = require('path')
9-
let program = require('commander')
10-
let watch = require('chokidar').watch
6+
const fs = require('fs');
7+
const path = require('path');
8+
const program = require('commander');
9+
const watch = require('chokidar').watch;
10+
11+
const ApiClient = require('../lib/api');
12+
const { getFiles } = require('../lib/get-files');
1113

1214
program
1315
.option('-w, --watch', 'deploy files on change')
14-
.option('-x --replace', 'replace css and js file paths inside html file with their QuickBase url')
15-
.parse(process.argv)
16-
17-
let sourceArg = program.args[0] || '.'
18-
let configPath = require('../lib/find-config')(sourceArg)
19-
let config = require(configPath)
20-
let api = new ApiClient(config)
16+
.option(
17+
'-x --replace',
18+
'replace css and js file paths inside html file with their QuickBase url'
19+
)
20+
.parse(process.argv);
2121

22-
const CONFIG_FILE_NAME = 'quickbase-cli.config.js'
22+
const sourceArg = program.args[0] || '.';
23+
const configPath = require('../lib/find-config')(sourceArg);
24+
const config = require(configPath);
25+
const api = new ApiClient(config);
2326

24-
qbDeploy(sourceArg)
27+
qbDeploy(sourceArg);
2528

2629
if (program.watch) {
27-
console.log(`Watching for file changes in ${sourceArg}`)
30+
console.log(`Watching for file changes in ${sourceArg}`);
2831

29-
watch(sourceArg, {}).on('change', (fileName) => {
30-
console.log(`\nChange detected in ${fileName}. Deploying...`)
31-
qbDeploy(fileName)
32-
})
32+
watch(sourceArg, {}).on('change', fileName => {
33+
console.log(`\nChange detected in ${fileName}. Deploying...`);
34+
qbDeploy(fileName);
35+
});
3336
}
3437

3538
function qbDeploy(source) {
36-
let isFile = fs.statSync(source).isFile()
39+
let isFile = fs.statSync(source).isFile();
3740

3841
if (isFile) {
3942
return uploadToQuickbase(source)
40-
.then(res => console.log(`Successfully uploaded to QuickBase:\n\t${source}`))
41-
.catch(err => console.error(err))
43+
.then(res =>
44+
console.log(`Successfully uploaded to QuickBase:\n=> ${source}`)
45+
)
46+
.catch(err => console.error(err));
4247
}
4348

4449
if (!isFile) {
45-
let allFiles = fs.readdirSync(source).filter(file => file.charAt(0) != '.' && file != CONFIG_FILE_NAME)
46-
let htmlFiles = allFiles.filter(file => path.extname(file) == '.html').map(file => path.join(source, file))
47-
let assetFiles = allFiles.filter(file => path.extname(file) != '.html').map(file => path.join(source, file))
48-
49-
let uploadHtmlFiles = program.replace
50-
? replaceUrlsAndUpload(htmlFiles, assetFiles)
51-
: htmlFiles.map(htmlFile => uploadToQuickbase(htmlFile))
52-
let uploadAssetFiles = assetFiles.map(assetFile => uploadToQuickbase(assetFile))
53-
let uploadAllFiles = uploadHtmlFiles.concat(uploadAssetFiles)
54-
55-
return Promise.all(uploadAllFiles)
56-
.then(res => console.log(`Successfully uploaded to QuickBase:\n\t${allFiles.join("\n\t")}`))
57-
.catch(err => console.error(err))
50+
getFiles(source).then(files => {
51+
const { htmlFiles, assetFiles } = files;
52+
53+
const uploadHtmlFiles = program.replace
54+
? replaceUrlsAndUpload(htmlFiles, assetFiles)
55+
: htmlFiles.map(htmlFile => uploadToQuickbase(htmlFile));
56+
57+
const uploadAssetFiles = assetFiles.map(assetFile =>
58+
uploadToQuickbase(assetFile)
59+
);
60+
61+
const uploadAllFiles = uploadHtmlFiles.concat(uploadAssetFiles);
62+
63+
return Promise.all(uploadAllFiles)
64+
.then(res =>
65+
console.log(
66+
`Successfully uploaded to QuickBase:\n=> ${htmlFiles
67+
.concat(assetFiles)
68+
.join('\n=> ')}`
69+
)
70+
)
71+
.catch(err => console.error(err));
72+
});
5873
}
5974
}
6075

6176
function uploadToQuickbase(file, fileContents) {
62-
let fileName = path.basename(file)
63-
let codePageName
77+
let fileName = path.basename(file);
78+
let codePageName;
6479

6580
if (!fileContents) {
66-
fileContents = fs.readFileSync(file, 'utf-8')
81+
fileContents = fs.readFileSync(file, 'utf-8');
6782
}
6883

6984
if (config.appName) {
70-
codePageName = `${config.appName}-${fileName}`
85+
codePageName = `${config.appName}-${fileName}`;
7186
} else {
72-
codePageName = fileName
87+
codePageName = fileName;
7388
}
7489

75-
return api.uploadPage(codePageName, fileContents)
90+
return api.uploadPage(codePageName, fileContents);
7691
}
7792

7893
function replaceUrlsAndUpload(htmlFiles, assetFiles) {
7994
return htmlFiles.map(htmlFile => {
80-
let htmlContents = fs.readFileSync(htmlFile, 'utf-8')
95+
let htmlContent = fs.readFileSync(htmlFile, 'utf-8');
8196

8297
assetFiles.forEach(assetFile => {
83-
assetFile = path.basename(assetFile)
84-
assetFileTagRegExp =
85-
86-
htmlContents = htmlContents.replace(new RegExp(assetFile, 'g'), generateCustomPageUrl(assetFile))
87-
})
88-
89-
return uploadToQuickbase(htmlFile, htmlContents)
90-
})
98+
const fileName = path.basename(assetFile);
99+
const regex = new RegExp(`("|')[^"]*${fileName}("|')`, 'g');
100+
101+
htmlContent = htmlContent.replace(
102+
regex,
103+
generateCustomPageUrl(path.basename(assetFile))
104+
);
105+
});
106+
107+
console.log(htmlContent);
108+
return uploadToQuickbase(htmlFile, htmlContent);
109+
});
91110
}
92111

93112
function generateCustomPageUrl(fileName) {
94-
return `https://${config.realm}.quickbase.com/db/${config.dbid}?a=dbpage&pagename=${config.appName}-${fileName}`
113+
const suffix = config.appName
114+
? `${config.appName}-${fileName}`
115+
: `${fileName}`;
116+
117+
return `"https://${config.realm}.quickbase.com/db/${
118+
config.dbid
119+
}?a=dbpage&pagename=${suffix}"`;
95120
}

bin/qb-init.js

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
#!/usr/bin/env node
22

3-
let fs = require('fs')
4-
let generateConfig = require('../lib/generate-config')
5-
let inquirer = require('inquirer')
3+
let fs = require('fs');
4+
let generateConfig = require('../lib/generate-config');
5+
let inquirer = require('inquirer');
66

77
const QUESTIONS = [
88
{
@@ -13,7 +13,8 @@ const QUESTIONS = [
1313
{
1414
type: 'password',
1515
name: 'password',
16-
message: 'QuickBase password (leave blank to use the QUICKBASE_CLI_PASSWORD environment variable):'
16+
message:
17+
'QuickBase password (leave blank to use the QUICKBASE_CLI_PASSWORD environment variable):'
1718
},
1819
{
1920
type: 'input',
@@ -33,18 +34,23 @@ const QUESTIONS = [
3334
{
3435
type: 'input',
3536
name: 'appName',
36-
message: 'Code page prefix (leave blank to disable prefixing uploaded pages):'
37+
message:
38+
'Code page prefix (leave blank to disable prefixing uploaded pages):'
3739
}
38-
]
40+
];
3941

40-
qbInit()
42+
qbInit();
4143

4244
function qbInit() {
43-
inquirer.prompt(QUESTIONS).then(answers => {
44-
return generateConfig(answers)
45-
}).then(() => {
46-
console.log('quickbase-cli.config.js generated successfuly.')
47-
}).catch(err => {
48-
console.error(err)
49-
})
45+
inquirer
46+
.prompt(QUESTIONS)
47+
.then(answers => {
48+
return generateConfig(answers);
49+
})
50+
.then(() => {
51+
console.log('quickbase-cli.config.js generated successfuly.');
52+
})
53+
.catch(err => {
54+
console.error(err);
55+
});
5056
}

bin/qb-new.js

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,23 @@
55
// prompt user if no quickbase-cli.config.js file is found?
66
// default github username/repo? (global .qbcli config file a la .npmrc)?
77

8-
let args = require('commander').parse(process.argv).args
9-
let gitClone = require('../lib/git-clone')
8+
let args = require('commander').parse(process.argv).args;
9+
let gitClone = require('../lib/git-clone');
1010

11-
let template = args[0]
12-
let projectName = args[1]
11+
let template = args[0];
12+
let projectName = args[1];
1313

1414
if (!template) {
15-
console.error('template required')
16-
process.exit(1)
15+
console.error('template required');
16+
process.exit(1);
1717
}
1818

19-
qbNew(template, projectName)
19+
qbNew(template, projectName);
2020

2121
function qbNew(template, projectName) {
22-
gitClone(template, projectName).then(res => {
23-
console.log(`New project created.`)
24-
}).catch(err => console.error(err))
25-
}
22+
gitClone(template, projectName)
23+
.then(res => {
24+
console.log(`New project created.`);
25+
})
26+
.catch(err => console.error(err));
27+
}

bin/qb.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,19 @@
11
#!/usr/bin/env node
22

3+
const nodeVersion = Number(process.version.match(/^v(\d+\.\d+)/)[1]);
4+
5+
if (nodeVersion < 8) {
6+
console.log(
7+
`*** quickbase-cli > 2.0 requires Node.js version >= 8. Please upgrade. ***`
8+
);
9+
10+
process.exit(1);
11+
}
12+
313
require('commander')
414
.version(require('../package').version)
515
.usage('<command> [options]')
616
.command('new [repo] [projectName]', 'generate a new project from a template')
717
.command('init', 'add quickbase-cli functionality to an existing project')
818
.command('deploy [path]', 'upload a project to quickbase')
9-
.parse(process.argv)
19+
.parse(process.argv);

test/index.html renamed to demo/index.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
<head>
44
<meta charset="utf-8">
55
<title>quickbase-cli</title>
6-
<link rel="stylesheet" href="main.css">
6+
<link rel="stylesheet" href="static/main.css">
77
</head>
88
<body>
9-
<h1>Hello, world!</h1>
9+
<h1>Hello, world</h1>
1010

11-
<script src="bundle.js"></script>
11+
<script src="static/bundle.js"></script>
1212
</body>
1313
</html>
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)