Skip to content

Commit b5c1159

Browse files
committed
tool
0 parents  commit b5c1159

7 files changed

+211
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules/

README.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Typedefs Commandline Tool
2+
3+
Use the Typedefs JS library from the commandline.
4+
5+
**Note**: this is for the convenience of NPM users, there is nothing JS or NPM specific about the Typedefs compiler and it can be installed without NPM. See https://github.com/typedefs/typedefs for more information.
6+
7+
## Installation
8+
9+
To install this tool globally, run
10+
11+
```sh
12+
npm install -g typedefs
13+
```
14+
15+
## Usage
16+
17+
```
18+
Usage: typedefs-cli [options] [command]
19+
20+
Options:
21+
-V, --version output the version number
22+
-h, --help output usage information
23+
24+
Commands:
25+
codegen generate code from S-expression
26+
help [cmd] display help for [cmd]
27+
```
28+
29+
Using the code generator:
30+
31+
32+
```sh
33+
echo "(name Bit (+ 1 1))" | typedefs codegen --target json
34+
```
35+
36+
Options:
37+
38+
```
39+
-i, --input [filename] File to read input from
40+
-o, --output [filename] File to write output to
41+
--force Force file overwrite
42+
-t, --target [platform] Target platform: "haskell", "reasonml" or "json"
43+
```

package-lock.json

Lines changed: 23 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"name": "typedefs",
3+
"version": "0.0.1",
4+
"description": "Typedefs commandline tool",
5+
"bin": {
6+
"typedefs": "./typedefs-cli.js",
7+
"typedefs-codegen": "./typedefs-cli-codegen.js"
8+
},
9+
"repository": {
10+
"type": "git",
11+
"url": "git+https://github.com/typedefs/typedefs-cli.git"
12+
},
13+
"files": [
14+
"typedefs-cli-*.js",
15+
"util.js",
16+
"package.json",
17+
"README.md"
18+
],
19+
"keywords": [],
20+
"author": "",
21+
"license": "AGPL-3.0-or-later",
22+
"bugs": {
23+
"url": "https://github.com/typedefs/typedefs-cli/issues"
24+
},
25+
"homepage": "https://github.com/typedefs/typedefs-cli#readme",
26+
"dependencies": {
27+
"commander": "^2.20.0",
28+
"get-stdin": "^6.0.0",
29+
"typedefs-js": "^1.0.1"
30+
}
31+
}

typedefs-cli-codegen.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#!/usr/bin/env node
2+
const {program, exit_error, exit_success, get_input, put_output } = require("./util.js")
3+
const Typedefs = require("typedefs-js")
4+
5+
let help = () => console.log(`
6+
Examples:
7+
8+
# Generate JSON Schema from typedefs S-Expression
9+
echo "(name Bit (+ 1 1))" | typedefs codegen --target json
10+
`)
11+
12+
program
13+
.on('--help', help)
14+
.option('-t, --target [platform]', 'Target platform: "haskell", "reasonml" or "json"')
15+
.parse(process.argv);
16+
17+
// TODO should get this from the `ParseJS.idr` library
18+
let targets = [
19+
'haskell',
20+
'reasonml',
21+
'json'
22+
]
23+
24+
async function main () {
25+
let inputSExpression = (await get_input()).toString().trim()
26+
27+
let ty = Typedefs.parseType(inputSExpression)
28+
if(!ty) {
29+
exit_error("Failed to process input typedef")
30+
}
31+
32+
let target = program.target
33+
if(targets.indexOf(target) < 0) {
34+
exit_error(`invalid target, ${target}. Must be one of: ${targets.join(' ')}`)
35+
}
36+
37+
let result = Typedefs.generateCode(target, ty)
38+
put_output(result)
39+
exit_success()
40+
}
41+
42+
main()

typedefs-cli.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#!/usr/bin/env node
2+
let program = require('commander')
3+
4+
// load package.json to get version
5+
let path = require('path')
6+
let packageJson = require(path.join(__dirname, 'package.json'))
7+
8+
// provide title for the `ps` command
9+
process.title = 'typedefs'
10+
11+
12+
program
13+
.version(packageJson.version)
14+
.command('codegen', 'generate code from S-expression')
15+
.parse(process.argv);

util.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
let fs = require('fs')
2+
3+
// setup basic options `ioFV`
4+
const program = require('commander')
5+
.option('-i, --input [filename]', 'File to read input from')
6+
.option('-o, --output [filename]', 'File to write output to')
7+
.option('--force', 'Force file overwrite')
8+
9+
function exit_error(msg) {
10+
console.error(msg);
11+
process.exit(1);
12+
}
13+
14+
function exit_success() {
15+
process.exit(0);
16+
}
17+
18+
// only load non-empty input
19+
async function get_input () {
20+
let rawInput = await get_raw_input()
21+
if(rawInput.toString('utf8').trim() === "") {
22+
exit_error('You must pass non empty input')
23+
}
24+
return rawInput
25+
}
26+
27+
// reads the input from STDIN or file
28+
async function get_raw_input () {
29+
// read from input file
30+
let fn = program.input
31+
if (fn) {
32+
if (!fs.existsSync(fn)) {
33+
exit_error(`input file "${fn}" does not exist`)
34+
}
35+
// TODO check directory?
36+
return fs.readFileSync(fn)
37+
} else {
38+
// read from standard input
39+
return require("get-stdin").buffer()
40+
}
41+
}
42+
43+
async function put_output (out) {
44+
let fn = program.output
45+
if (fn) {
46+
if (fs.existsSync(fn) && !program.force) {
47+
exit_error(`output file "${fn}" already exists`)
48+
}
49+
return fs.writeFileSync(fn, out)
50+
} else {
51+
// write to standard output
52+
console.log(out)
53+
}
54+
}
55+
56+
module.exports = { program, exit_error, exit_success, get_input, put_output }

0 commit comments

Comments
 (0)