Socket
Socket
Sign inDemoInstall

json-schema-to-typescript

Package Overview
Dependencies
Maintainers
1
Versions
114
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

json-schema-to-typescript - npm Package Compare versions

Comparing version 8.1.0 to 8.2.0

4

CHANGELOG.md
# Changelog
## 8.2.0
- a0257d8 Add support for directories and globs as inputs (#238)
## 8.1.0

@@ -4,0 +8,0 @@

@@ -42,5 +42,22 @@ #!/usr/bin/env node

var fs_1 = require("mz/fs");
var _mkdirp = require("mkdirp");
var _glob = require("glob");
var isGlob = require("is-glob");
var util_1 = require("util");
var path_1 = require("path");
var stdin = require("stdin");
var index_1 = require("./index");
var utils_1 = require("./utils");
// Promisify mkdirp & glob
var mkdirp = function (path) {
return new Promise(function (res, rej) {
_mkdirp(path, function (err, made) {
if (err)
rej(err);
else
res(made === null ? undefined : made);
});
});
};
var glob = util_1.promisify(_glob);
main(minimist(process.argv.slice(2), {

@@ -55,5 +72,5 @@ alias: {

return __awaiter(this, void 0, void 0, function () {
var argIn, argOut, schema, _a, _b, ts, e_1;
return __generator(this, function (_c) {
switch (_c.label) {
var argIn, argOut, ISGLOB, ISDIR, e_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:

@@ -65,23 +82,34 @@ if (argv.help) {

argIn = argv._[0] || argv.input;
argOut = argv._[1] || argv.output;
_c.label = 1;
argOut = argv._[1] || argv.output // the output can be omitted so this can be undefined
;
ISGLOB = isGlob(argIn);
ISDIR = isDir(argIn);
if ((ISGLOB || ISDIR) && argOut && argOut.includes('.d.ts')) {
throw new ReferenceError("You have specified a single file " + argOut + " output for a multi file input " + argIn + ". This feature is not yet supported, refer to issue #272 (https://github.com/bcherny/json-schema-to-typescript/issues/272)");
}
_a.label = 1;
case 1:
_c.trys.push([1, 5, , 6]);
_b = (_a = JSON).parse;
return [4 /*yield*/, readInput(argIn)];
_a.trys.push([1, 8, , 9]);
if (!ISGLOB) return [3 /*break*/, 3];
return [4 /*yield*/, processGlob(argIn, argOut, argv)];
case 2:
schema = _b.apply(_a, [_c.sent()]);
return [4 /*yield*/, index_1.compile(schema, argIn, argv)];
_a.sent();
return [3 /*break*/, 7];
case 3:
ts = _c.sent();
return [4 /*yield*/, writeOutput(ts, argOut)];
if (!ISDIR) return [3 /*break*/, 5];
return [4 /*yield*/, processDir(argIn, argOut, argv)];
case 4:
_c.sent();
return [3 /*break*/, 6];
case 5:
e_1 = _c.sent();
_a.sent();
return [3 /*break*/, 7];
case 5: return [4 /*yield*/, processFile(argIn, argOut, argv)];
case 6:
_a.sent();
_a.label = 7;
case 7: return [3 /*break*/, 9];
case 8:
e_1 = _a.sent();
console.error(cli_color_1.whiteBright.bgRedBright('error'), e_1);
process.exit(1);
return [3 /*break*/, 6];
case 6: return [2 /*return*/];
return [3 /*break*/, 9];
case 9: return [2 /*return*/];
}

@@ -91,2 +119,94 @@ });

}
// check if path is an existing directory
function isDir(path) {
return fs_1.existsSync(path) && fs_1.lstatSync(path).isDirectory();
}
function processGlob(argIn, argOut, argv) {
return __awaiter(this, void 0, void 0, function () {
var files;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, glob(argIn)]; // execute glob pattern match
case 1:
files = _a.sent() // execute glob pattern match
;
if (files.length === 0) {
throw ReferenceError("You passed a glob pattern \"" + argIn + "\", but there are no files that match that pattern in " + process.cwd());
}
if (!(argOut && !fs_1.existsSync(argOut))) return [3 /*break*/, 3];
return [4 /*yield*/, mkdirp(argOut)];
case 2:
_a.sent();
_a.label = 3;
case 3: return [4 /*yield*/, Promise.all(files.map(function (file) {
var outPath = argOut && argOut + "/" + path_1.basename(file, '.json') + ".d.ts";
return processFile(file, outPath, argv);
}))];
case 4:
_a.sent();
return [2 /*return*/];
}
});
});
}
function processDir(argIn, argOut, argv) {
return __awaiter(this, void 0, void 0, function () {
var files;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
files = getPaths(argIn);
return [4 /*yield*/, Promise.all(files.map(function (file) {
if (!argOut) {
return processFile(file, argOut, argv);
}
else {
var outPath = utils_1.pathTransform(argOut, file);
if (!isDir(path_1.dirname(outPath))) {
_mkdirp.sync(path_1.dirname(outPath));
}
outPath = outPath.replace('.json', '.d.ts');
return processFile(file, outPath, argv);
}
}))];
case 1:
_a.sent();
return [2 /*return*/];
}
});
});
}
function processFile(argIn, argOut, argv) {
return __awaiter(this, void 0, void 0, function () {
var schema, _a, _b, ts;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
_b = (_a = JSON).parse;
return [4 /*yield*/, readInput(argIn)];
case 1:
schema = _b.apply(_a, [_c.sent()]);
return [4 /*yield*/, index_1.compile(schema, argIn, argv)];
case 2:
ts = _c.sent();
if (!!argOut) return [3 /*break*/, 3];
process.stdout.write(ts);
return [3 /*break*/, 5];
case 3: return [4 /*yield*/, fs_1.writeFile(argOut, ts)];
case 4: return [2 /*return*/, _c.sent()];
case 5: return [2 /*return*/];
}
});
});
}
function getPaths(path, paths) {
if (paths === void 0) { paths = []; }
if (fs_1.existsSync(path) && fs_1.lstatSync(path).isDirectory()) {
fs_1.readdirSync(path_1.resolve(path)).forEach(function (item) { return getPaths(path_1.join(path, item), paths); });
}
else {
paths.push(path);
}
return paths;
}
function readInput(argIn) {

@@ -98,14 +218,2 @@ if (!argIn) {

}
function writeOutput(ts, argOut) {
if (!argOut) {
try {
process.stdout.write(ts);
return Promise.resolve();
}
catch (err) {
return Promise.reject(err);
}
}
return fs_1.writeFile(argOut, ts);
}
function printHelp() {

@@ -112,0 +220,0 @@ var pkg = require('../../package.json');

@@ -31,1 +31,2 @@ import { JSONSchema } from './types/JSONSchema';

export declare function escapeBlockComment(schema: JSONSchema): void;
export declare function pathTransform(o: string, i: string): string;

@@ -231,2 +231,23 @@ "use strict";

exports.escapeBlockComment = escapeBlockComment;
/*
the following logic determines the out path by comparing the in path to the users specified out path.
For example, if input directory MultiSchema looks like:
MultiSchema/foo/a.json
MultiSchema/bar/fuzz/c.json
MultiSchema/bar/d.json
And the user wants the outputs to be in MultiSchema/Out, then this code will be able to map the inner directories foo, bar, and fuzz into the intended Out directory like so:
MultiSchema/Out/foo/a.json
MultiSchema/Out/bar/fuzz/c.json
MultiSchema/Out/bar/d.json
*/
function pathTransform(o, i) {
var outPathList = o.split('/');
var inPathList = i.split('/');
var intersection = outPathList.filter(function (x) { return inPathList.includes(x); });
var symmetricDifference = outPathList
.filter(function (x) { return !inPathList.includes(x); })
.concat(inPathList.filter(function (x) { return !outPathList.includes(x); }));
return path_1.join.apply(void 0, intersection.concat(symmetricDifference));
}
exports.pathTransform = pathTransform;
//# sourceMappingURL=utils.js.map

10

package.json
{
"name": "json-schema-to-typescript",
"version": "8.1.0",
"version": "8.2.0",
"description": "compile json schema to typescript typings",

@@ -48,6 +48,9 @@ "main": "dist/src/index.js",

"dependencies": {
"@types/is-glob": "^4.0.1",
"@types/json-schema": "^7.0.3",
"@types/node": ">=4.5.0",
"@types/mkdirp": "^0.5.2",
"@types/prettier": "^1.16.1",
"cli-color": "^1.4.0",
"glob": "^7.1.4",
"is-glob": "^4.0.1",
"json-schema-ref-parser": "^6.1.0",

@@ -57,2 +60,3 @@ "json-stringify-safe": "^5.0.1",

"minimist": "^1.2.0",
"mkdirp": "^0.5.1",
"mz": "^2.7.0",

@@ -64,5 +68,7 @@ "prettier": "^1.19.1",

"@types/cli-color": "^0.3.29",
"@types/glob": "^7.1.1",
"@types/lodash": "^4.14.121",
"@types/minimist": "^1.2.0",
"@types/mz": "0.0.32",
"@types/node": "^12.12.29",
"@typescript-eslint/eslint-plugin": "^2.9.0",

@@ -69,0 +75,0 @@ "@typescript-eslint/parser": "^2.9.0",

@@ -97,3 +97,3 @@ # json-schema-to-typescript [![Build Status][build]](https://circleci.com/gh/bcherny/json-schema-to-typescript) [![npm]](https://www.npmjs.com/package/json-schema-to-typescript) [![mit]](https://opensource.org/licenses/MIT)

A simple CLI utility is provided with this package.
A CLI utility is provided with this package.

@@ -121,2 +121,67 @@ ```sh

The CLI supports directory of definitions as well. It supports directory paths, glob patterns, and output directories.
Example 1: Directory of type definitions to an output directory
Input Directory
```
schemas /
| a.json
| b.json
```
```sh
json2ts -i schemas/ -o types/
```
Output Directory
```
types /
| a.d.ts
| b.d.ts
```
Example 2: Directory to pipe out
Input Directory
```
schemas /
| a.json
| b.json
```
```sh
json2ts -i schemas/
```
Example 3: Nested input directory mapped to nested output
Input Directory
```
schemas /
foo /
| a.json
bar /
| b.json
fuzz /
c.json
buzz /
d.json
```
```sh
json2ts -i schemas/ -o types/
```
Output Directory
```
types /
foo /
| a.d.ts
bar /
| b.d.ts
fuzz /
c.d.ts
buzz /
d.d.ts
```
## Tests

@@ -123,0 +188,0 @@

#!/usr/bin/env node
import {whiteBright} from 'cli-color'
import {JSONSchema4} from 'json-schema'
import minimist = require('minimist')
import {readFile, writeFile} from 'mz/fs'
import {resolve} from 'path'
import {readFile, writeFile, existsSync, lstatSync, readdirSync} from 'mz/fs'
import * as _mkdirp from 'mkdirp'
import * as _glob from 'glob'
import isGlob = require('is-glob')
import {promisify} from 'util'
import {join, resolve, dirname, basename} from 'path'
import stdin = require('stdin')
import {compile, Options} from './index'
import {pathTransform} from './utils'
// Promisify mkdirp & glob
const mkdirp = (path: string): Promise<_mkdirp.Made> =>
new Promise((res, rej) => {
_mkdirp(path, (err, made) => {
if (err) rej(err)
else res(made === null ? undefined : made)
})
})
const glob = promisify(_glob)
main(

@@ -28,8 +43,22 @@ minimist(process.argv.slice(2), {

const argIn: string = argv._[0] || argv.input
const argOut: string = argv._[1] || argv.output
const argOut: string | undefined = argv._[1] || argv.output // the output can be omitted so this can be undefined
const ISGLOB = isGlob(argIn)
const ISDIR = isDir(argIn)
if ((ISGLOB || ISDIR) && argOut && argOut.includes('.d.ts')) {
throw new ReferenceError(
`You have specified a single file ${argOut} output for a multi file input ${argIn}. This feature is not yet supported, refer to issue #272 (https://github.com/bcherny/json-schema-to-typescript/issues/272)`
)
}
try {
const schema: JSONSchema4 = JSON.parse(await readInput(argIn))
const ts = await compile(schema, argIn, argv as Partial<Options>)
await writeOutput(ts, argOut)
// Process input as either glob, directory, or single file
if (ISGLOB) {
await processGlob(argIn, argOut, argv as Partial<Options>)
} else if (ISDIR) {
await processDir(argIn, argOut, argv as Partial<Options>)
} else {
await processFile(argIn, argOut, argv as Partial<Options>)
}
} catch (e) {

@@ -41,2 +70,68 @@ console.error(whiteBright.bgRedBright('error'), e)

// check if path is an existing directory
function isDir(path: string): boolean {
return existsSync(path) && lstatSync(path).isDirectory()
}
async function processGlob(argIn: string, argOut: string | undefined, argv: Partial<Options>) {
const files = await glob(argIn) // execute glob pattern match
if (files.length === 0) {
throw ReferenceError(
`You passed a glob pattern "${argIn}", but there are no files that match that pattern in ${process.cwd()}`
)
}
// create output directory if it does not exist
if (argOut && !existsSync(argOut)) {
await mkdirp(argOut)
}
await Promise.all(
files.map(file => {
const outPath = argOut && `${argOut}/${basename(file, '.json')}.d.ts`
return processFile(file, outPath, argv)
})
)
}
async function processDir(argIn: string, argOut: string | undefined, argv: Partial<Options>) {
const files = getPaths(argIn)
await Promise.all(
files.map(file => {
if (!argOut) {
return processFile(file, argOut, argv)
} else {
let outPath = pathTransform(argOut, file)
if (!isDir(dirname(outPath))) {
_mkdirp.sync(dirname(outPath))
}
outPath = outPath.replace('.json', '.d.ts')
return processFile(file, outPath, argv)
}
})
)
}
async function processFile(argIn: string, argOut: string | undefined, argv: Partial<Options>): Promise<void> {
const schema = JSON.parse(await readInput(argIn))
const ts = await compile(schema, argIn, argv)
if (!argOut) {
process.stdout.write(ts)
} else {
return await writeFile(argOut, ts)
}
}
function getPaths(path: string, paths: string[] = []) {
if (existsSync(path) && lstatSync(path).isDirectory()) {
readdirSync(resolve(path)).forEach(item => getPaths(join(path, item), paths))
} else {
paths.push(path)
}
return paths
}
function readInput(argIn?: string) {

@@ -49,14 +144,2 @@ if (!argIn) {

function writeOutput(ts: string, argOut: string): Promise<void> {
if (!argOut) {
try {
process.stdout.write(ts)
return Promise.resolve()
} catch (err) {
return Promise.reject(err)
}
}
return writeFile(argOut, ts)
}
function printHelp() {

@@ -63,0 +146,0 @@ const pkg = require('../../package.json')

import {whiteBright} from 'cli-color'
import {deburr, isPlainObject, mapValues, trim, upperFirst} from 'lodash'
import {basename, extname} from 'path'
import {basename, extname, join} from 'path'
import {JSONSchema} from './types/JSONSchema'

@@ -224,1 +224,24 @@

}
/*
the following logic determines the out path by comparing the in path to the users specified out path.
For example, if input directory MultiSchema looks like:
MultiSchema/foo/a.json
MultiSchema/bar/fuzz/c.json
MultiSchema/bar/d.json
And the user wants the outputs to be in MultiSchema/Out, then this code will be able to map the inner directories foo, bar, and fuzz into the intended Out directory like so:
MultiSchema/Out/foo/a.json
MultiSchema/Out/bar/fuzz/c.json
MultiSchema/Out/bar/d.json
*/
export function pathTransform(o: string, i: string): string {
const outPathList = o.split('/')
const inPathList = i.split('/')
const intersection = outPathList.filter(x => inPathList.includes(x))
const symmetricDifference = outPathList
.filter(x => !inPathList.includes(x))
.concat(inPathList.filter(x => !outPathList.includes(x)))
return join(...intersection, ...symmetricDifference)
}

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc