Skip to content

Commit c48541f

Browse files
authored
feat(REACH-717): add bin to run the client from command line (#99)
Add command line client that can be executed with `yarn typeform-api`.
1 parent a74622a commit c48541f

File tree

5 files changed

+146
-3
lines changed

5 files changed

+146
-3
lines changed

.eslintignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
# output folder
22
dist/
3+
rollup.config.js

README.md

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ npm install @typeform/api-client --save
3434

3535
## Usage
3636

37-
### Initialize
37+
### In your project
3838

3939
1. Import client library
4040

@@ -72,6 +72,46 @@ typeformAPI.forms.list().then((response) => {
7272
})
7373
```
7474

75+
**Note:** You can also execute the client binary directly via command line in your project:
76+
77+
```shell
78+
yarn typeform-api <method> [params]
79+
```
80+
81+
See [next section](#via-command-line) for more details.
82+
83+
### Via command line
84+
85+
1. Clone this repo on your machine
86+
87+
2. Install all dependencies:
88+
89+
```shell
90+
yarn install
91+
```
92+
93+
3. Set your personal token as `TF_TOKEN` env variable
94+
95+
```shell
96+
export TF_TOKEN=tfp_XXXXXXXXXX
97+
```
98+
99+
4. Run the client:
100+
101+
```shell
102+
yarn typeform-api <method> [params]
103+
```
104+
105+
See [reference](#reference) for all available method names and their params.
106+
107+
Example usage:
108+
109+
```shell
110+
yarn typeform-api forms.list
111+
yarn typeform-api forms.get '{uid:"abcd1234"}'
112+
yarn typeform-api themes.list '{pageSize:3}'
113+
```
114+
75115
## Reference
76116

77117
### `createClient({token})`

package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@
1616
"semantic-release": "semantic-release",
1717
"server": "node ./tests/integration/mockServer.js",
1818
"server:dev": "nodemon ./tests/integration/mockServer.js",
19-
"publish:github": "npm config set '//npm.pkg.github.com/:_authToken' $GH_TOKEN && npm publish --registry https://npm.pkg.github.com"
19+
"publish:github": "npm config set '//npm.pkg.github.com/:_authToken' $GH_TOKEN && npm publish --registry https://npm.pkg.github.com",
20+
"typeform-api": "node ./dist/bin"
21+
},
22+
"bin": {
23+
"typeform-api": "dist/bin"
2024
},
2125
"main": "dist/index.cjs.js",
2226
"browser": "dist/typeform-api.js",

rollup.config.js

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,43 @@ const config = [
8888
terser(),
8989
],
9090
},
91+
{
92+
input: 'src/bin.ts',
93+
output: [
94+
{
95+
file: pkg.bin['typeform-api'],
96+
format: 'cjs',
97+
exports: 'named',
98+
banner: '#!/usr/bin/env node',
99+
},
100+
],
101+
onwarn(warning, warn) {
102+
// supress warning on usa of eval()
103+
// eval() in ./src/bin.ts executes code supplied by user on their own machine, which is safe
104+
if (warning.code === 'EVAL') {
105+
return
106+
}
107+
warn(warning)
108+
},
109+
plugins: [
110+
resolveModule(),
111+
commonjs({
112+
include: ['node_modules/**'],
113+
}),
114+
...plugins,
115+
],
116+
external: [
117+
'http',
118+
'https',
119+
'url',
120+
'zlib',
121+
'assert',
122+
'stream',
123+
'tty',
124+
'util',
125+
'os',
126+
],
127+
},
91128
]
92129

93-
export default config
130+
export default config

src/bin.ts

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { inspect } from 'util'
2+
3+
import { createClient } from './index'
4+
5+
const print = (message: string) => {
6+
// eslint-disable-next-line no-console
7+
console.log(message)
8+
}
9+
10+
const token = process.env.TF_TOKEN
11+
12+
if (!token) {
13+
throw new Error('Add your personal token as TF_TOKEN env variable')
14+
}
15+
16+
const typeformAPI = createClient({ token })
17+
18+
const [, , ...args] = process.argv
19+
const [methodName, methodParams] = args
20+
21+
if (!methodName || methodName === '-h' || methodName === '--help') {
22+
print('usage: typeform-api <method> [params]')
23+
print('examples: yarn api forms.list')
24+
print(' yarn api forms.get \'{uid:"abc12345"}\'')
25+
print(" yarn api themes.list '{pageSize:3}'")
26+
process.exit(0)
27+
}
28+
29+
const [property, method] = methodName.split('.')
30+
31+
// @ts-ignore
32+
if (!typeformAPI[property]?.[method]) {
33+
throw new Error(`Method ${methodName} does not exist`)
34+
}
35+
36+
let parsedParams = undefined
37+
38+
if (methodParams) {
39+
try {
40+
// this eval executes code supplied by user on their own machine, this is safe
41+
// eslint-disable-next-line no-eval
42+
eval(`parsedParams = ${methodParams}`)
43+
} catch (err) {
44+
throw new Error(`Invalid params: ${methodParams}`)
45+
}
46+
47+
if (typeof parsedParams !== 'object') {
48+
throw new Error(`Invalid params: ${methodParams}`)
49+
}
50+
}
51+
52+
print(`API: ${methodName}():`)
53+
54+
// @ts-ignore
55+
typeformAPI[property][method](parsedParams)
56+
.then((result: Object) => {
57+
print(inspect(result, { showHidden: false, depth: null, colors: true }))
58+
})
59+
.catch((err: Error) => {
60+
print(`Error: ${err.message}`)
61+
})

0 commit comments

Comments
 (0)