Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 7 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@
"version": "0.4.0",
"description": "Easily translate JSON into type definitions",
"main": "dist/index.js",
"bin": {
"json2struct": "./dist/index.js"
},
"types": "dist/index.d.ts",
"files": [
"dist"
],
"bin": "./dist/cli.js",
"scripts": {
"start": "node dist/index.js",
"start": "node dist/cli.js",
"build": "tsc",
"build:clean": "tsc --build --clean && npm run build",
"format": "prettier --ignore-path .gitignore --write .",
"format:check": "prettier --check --ignore-path .gitignore --write .",
"lint": "eslint --ext \".js,.mjs,.ts,.d.ts\" --ignore-path .gitignore .",
Expand Down
61 changes: 61 additions & 0 deletions src/cli.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/usr/bin/env node

import fs from 'fs/promises';

import { Command, Option } from '@commander-js/extra-typings';

import { convertToLanguage, SupportedLanguage } from './';
import { tokenize } from './tokenizer';

const program = new Command();

program
.name('json2struct')
.description('Easily translate JSON into type definitions')
.version('0.4.0')
.configureOutput({
writeOut: (str) => process.stdout.write(`[OUT] ${str}`),
writeErr: (str) => process.stdout.write(`[ERR] ${str}`),
outputError: (str, write) => write(`\x1b[31m${str}\x1b[0m`),
});

program
.command('convert <input>', { isDefault: true })
.description('Convert JSON file to type file')
.option('-o --output <output-file>')
.option('--overwrite')
.addOption(
new Option('-l --language <output-language>')
.choices<SupportedLanguage[]>(['typescript', 'python', 'julia'])
.default('typescript')
)
.action(async (inputPath, args) => {
console.info(`\u001b[32mjson2struct: Converting ${inputPath} to ${args.language}:\u001b[0m`);

if (!args?.output?.length && args?.overwrite) {
program.error('--overwrite options requires an output path');
return;
}

const fileContent = await fs.readFile(inputPath);

const json = JSON.parse(fileContent.toString());

const tokens = tokenize(json);

const generatedStruct = convertToLanguage((args?.language as SupportedLanguage) ?? 'typescript', tokens);

if (args.output?.length) {
if (args?.overwrite) {
await fs.writeFile(args.output, generatedStruct);
} else {
await fs.appendFile(args.output, generatedStruct);
}
}

console.info(generatedStruct);
});

program.addHelpCommand();

program.parse();
73 changes: 16 additions & 57 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
#!/usr/bin/env node

import fs from 'fs/promises';
import { generateJuliaStruct, generatePythonStruct, generateTypeScriptType } from './languages';
import { Token, tokenize } from './tokenizer';

import { Command, Option } from '@commander-js/extra-typings';
export * from './languages';
export * from './tokenizer';

import { generateJuliaStruct } from './languages/julia';
import { generatePythonStruct } from './languages/python';
import { generateTypeScriptType } from './languages/typescript';
import { Token, tokenize } from './tokenizer';
export type SupportedLanguage = 'typescript' | 'python' | 'julia';

function convertToLanguage(language: string, token: Token) {
export function convertToLanguage(language: SupportedLanguage, token: Token) {
switch (language) {
case 'typescript':
return generateTypeScriptType(token);
Expand All @@ -25,53 +22,15 @@ function convertToLanguage(language: string, token: Token) {
}
}

const program = new Command();

program
.name('json2struct')
.description('Easily translate JSON into type definitions')
.version('0.4.0')
.configureOutput({
writeOut: (str) => process.stdout.write(`[OUT] ${str}`),
writeErr: (str) => process.stdout.write(`[ERR] ${str}`),
outputError: (str, write) => write(`\x1b[31m${str}\x1b[0m`),
});

program
.command('convert <input>', { isDefault: true })
.description('Convert JSON file to type file')
.option('-o --output <output-file>')
.option('--overwrite')
.addOption(
new Option('-l --language <output-language>').choices(['typescript', 'python', 'julia']).default('typescript')
)
.action(async (inputPath, args) => {
console.info(`\u001b[32mjson2struct: Converting ${inputPath} to ${args.language}:\u001b[0m`);

if (!args?.output?.length && args?.overwrite) {
program.error('--overwrite options requires an output path');
return;
}

const fileContent = await fs.readFile(inputPath);
/**
*
* @param language the language to translate to
* @param json unparsed json string
*/
export default function json2struct(language: string, json: string) {
const parsedJson = JSON.parse(json);

const json = JSON.parse(fileContent.toString());
const tokens = tokenize(parsedJson);

const tokens = tokenize(json);

const generatedStruct = convertToLanguage(args?.language ?? 'typescript', tokens);

if (args.output?.length) {
if (args?.overwrite) {
await fs.writeFile(args.output, generatedStruct);
} else {
await fs.appendFile(args.output, generatedStruct);
}
}

console.info(generatedStruct);
});

program.addHelpCommand();

program.parse();
return convertToLanguage(language as SupportedLanguage, tokens);
}
3 changes: 3 additions & 0 deletions src/languages/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { generateTypeScriptType } from './typescript';
export { generatePythonStruct } from './python';
export { generateJuliaStruct } from './julia';
3 changes: 2 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
"declaration": true,
"declarationMap": true,
"lib": ["es6", "es2015"],
"resolveJsonModule": true
"resolveJsonModule": true,
"skipLibCheck": true
},
"include": ["src/"],
"exclude": ["src/__tests__/**", "**/**/*.test.ts"]
Expand Down