@lowdep/json-schema-gen 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +145 -0
- package/bin/json-schema-gen.js +268 -0
- package/package.json +45 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Rushabh Shah
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# json-schema-gen
|
|
2
|
+
|
|
3
|
+
   
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
Generate JSON Schema (draft-07) from sample JSON data. Detects string formats (email, URI, UUID, date-time), merges schemas from multiple samples, and outputs a clean schema ready for validation. Zero dependencies.
|
|
7
|
+
|
|
8
|
+
Like `quicktype` but needs no installation — and `genson` (Python) or online tools are overkill when you just need a schema.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install -g json-schema-gen
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Or without installing:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npx json-schema-gen data.json
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Example
|
|
27
|
+
|
|
28
|
+
Given `user.json`:
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
|
|
32
|
+
"name": "Alice Johnson",
|
|
33
|
+
"email": "alice@example.com",
|
|
34
|
+
"age": 32,
|
|
35
|
+
"active": true,
|
|
36
|
+
"createdAt": "2024-01-15T09:30:00Z",
|
|
37
|
+
"tags": ["admin", "user"],
|
|
38
|
+
"address": {
|
|
39
|
+
"street": "123 Main St",
|
|
40
|
+
"city": "Springfield",
|
|
41
|
+
"zip": "62701"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Running `json-schema-gen user.json --required` outputs:
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"$schema": "https://json-schema.org/draft-07/schema",
|
|
51
|
+
"type": "object",
|
|
52
|
+
"properties": {
|
|
53
|
+
"id": { "type": "string", "format": "uuid" },
|
|
54
|
+
"name": { "type": "string" },
|
|
55
|
+
"email": { "type": "string", "format": "email" },
|
|
56
|
+
"age": { "type": "integer" },
|
|
57
|
+
"active": { "type": "boolean" },
|
|
58
|
+
"createdAt": { "type": "string", "format": "date-time" },
|
|
59
|
+
"tags": { "type": "array", "items": { "type": "string" } },
|
|
60
|
+
"address": {
|
|
61
|
+
"type": "object",
|
|
62
|
+
"properties": {
|
|
63
|
+
"street": { "type": "string" },
|
|
64
|
+
"city": { "type": "string" },
|
|
65
|
+
"zip": { "type": "string" }
|
|
66
|
+
},
|
|
67
|
+
"required": ["street", "city", "zip"],
|
|
68
|
+
"additionalProperties": false
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
"required": ["id", "name", "email", "age", "active", "createdAt", "tags", "address"],
|
|
72
|
+
"additionalProperties": false
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Usage
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
json-schema-gen user.json # Basic schema
|
|
82
|
+
json-schema-gen user.json --required # Mark all fields as required
|
|
83
|
+
json-schema-gen user.json --title "User" --id "/schemas/user"
|
|
84
|
+
json-schema-gen user.json --out schema.json # Write to file
|
|
85
|
+
json-schema-gen s1.json s2.json s3.json # Merge from multiple samples
|
|
86
|
+
cat data.json | json-schema-gen - # Read from stdin
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Detected Formats
|
|
92
|
+
|
|
93
|
+
| Format | Example |
|
|
94
|
+
|---|---|
|
|
95
|
+
| `date-time` | `"2024-01-15T09:30:00Z"` |
|
|
96
|
+
| `date` | `"2024-01-15"` |
|
|
97
|
+
| `time` | `"09:30:00"` |
|
|
98
|
+
| `email` | `"user@example.com"` |
|
|
99
|
+
| `uri` | `"https://example.com"` |
|
|
100
|
+
| `uuid` | `"a1b2c3d4-e5f6-7890-abcd-ef1234567890"` |
|
|
101
|
+
| `ipv4` | `"192.168.1.1"` |
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Multi-Sample Merging
|
|
106
|
+
|
|
107
|
+
Pass multiple JSON files to infer a schema that covers all of them. Fields present in only some samples will not be marked `required`:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
json-schema-gen user1.json user2.json user3.json
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Options
|
|
116
|
+
|
|
117
|
+
| Flag | Description |
|
|
118
|
+
|---|---|
|
|
119
|
+
| `--required` | Mark all non-null fields as required |
|
|
120
|
+
| `--examples` | Include example values for string fields |
|
|
121
|
+
| `--title <name>` | Add `title` to the schema |
|
|
122
|
+
| `--id <uri>` | Add `$id` to the schema |
|
|
123
|
+
| `--out <file>` | Write output to a file |
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## License
|
|
128
|
+
|
|
129
|
+
MIT
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Keywords
|
|
134
|
+
|
|
135
|
+
`json schema generator` · `json to schema` · `quicktype alternative` · `genson alternative` · `infer schema` · `draft-07` · `generate schema` · `json schema` · `zero dependencies` · `cli`
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
<div align="center">
|
|
140
|
+
|
|
141
|
+
**Built to solve, shared to help — Rushabh Shah 🛠️✨**
|
|
142
|
+
|
|
143
|
+
<sub>One of 40+ zero-dependency developer CLI tools — no <code>node_modules</code>, ever.</sub>
|
|
144
|
+
|
|
145
|
+
</div>
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
|
|
7
|
+
const VERSION = '1.0.0';
|
|
8
|
+
|
|
9
|
+
// ─── ANSI ─────────────────────────────────────────────────────────────────────
|
|
10
|
+
const isTTY = process.stdout.isTTY;
|
|
11
|
+
const c = (code, t) => isTTY ? `\x1b[${code}m${t}\x1b[0m` : t;
|
|
12
|
+
const bold = t => c('1', t);
|
|
13
|
+
const dim = t => c('2', t);
|
|
14
|
+
const red = t => c('31', t);
|
|
15
|
+
const green = t => c('32', t);
|
|
16
|
+
const cyan = t => c('36', t);
|
|
17
|
+
const yellow = t => c('33', t);
|
|
18
|
+
|
|
19
|
+
// ─── Format detectors ─────────────────────────────────────────────────────────
|
|
20
|
+
const FORMAT_DETECTORS = [
|
|
21
|
+
{ format: 'date-time', test: v => /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?Z$/.test(v) },
|
|
22
|
+
{ format: 'date', test: v => /^\d{4}-\d{2}-\d{2}$/.test(v) },
|
|
23
|
+
{ format: 'time', test: v => /^\d{2}:\d{2}(:\d{2})?$/.test(v) },
|
|
24
|
+
{ format: 'email', test: v => /^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(v) },
|
|
25
|
+
{ format: 'uri', test: v => /^https?:\/\//.test(v) },
|
|
26
|
+
{ format: 'uuid', test: v => /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(v) },
|
|
27
|
+
{ format: 'ipv4', test: v => /^(\d{1,3}\.){3}\d{1,3}$/.test(v) },
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
function detectFormat(s) {
|
|
31
|
+
for (const { format, test } of FORMAT_DETECTORS) {
|
|
32
|
+
if (test(s)) return format;
|
|
33
|
+
}
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// ─── Schema inference ─────────────────────────────────────────────────────────
|
|
38
|
+
function inferSchema(value, opts = {}) {
|
|
39
|
+
const { allRequired = false, examples = false } = opts;
|
|
40
|
+
|
|
41
|
+
if (value === null) return { type: 'null' };
|
|
42
|
+
|
|
43
|
+
if (typeof value === 'boolean') return { type: 'boolean' };
|
|
44
|
+
|
|
45
|
+
if (typeof value === 'number') {
|
|
46
|
+
return Number.isInteger(value) ? { type: 'integer' } : { type: 'number' };
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (typeof value === 'string') {
|
|
50
|
+
const schema = { type: 'string' };
|
|
51
|
+
if (value.length > 0) {
|
|
52
|
+
const fmt = detectFormat(value);
|
|
53
|
+
if (fmt) schema.format = fmt;
|
|
54
|
+
if (examples && !fmt) schema.examples = [value];
|
|
55
|
+
}
|
|
56
|
+
return schema;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (Array.isArray(value)) {
|
|
60
|
+
if (value.length === 0) return { type: 'array', items: {} };
|
|
61
|
+
// Merge schemas of all items
|
|
62
|
+
const itemSchemas = value.map(v => inferSchema(v, opts));
|
|
63
|
+
const merged = mergeSchemas(itemSchemas);
|
|
64
|
+
return { type: 'array', items: merged };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (typeof value === 'object') {
|
|
68
|
+
const properties = {};
|
|
69
|
+
const required = [];
|
|
70
|
+
|
|
71
|
+
for (const [key, val] of Object.entries(value)) {
|
|
72
|
+
properties[key] = inferSchema(val, opts);
|
|
73
|
+
if (allRequired && val !== null && val !== undefined) {
|
|
74
|
+
required.push(key);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const schema = {
|
|
79
|
+
type: 'object',
|
|
80
|
+
properties,
|
|
81
|
+
additionalProperties: false,
|
|
82
|
+
};
|
|
83
|
+
if (required.length > 0) schema.required = required;
|
|
84
|
+
return schema;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return {};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// ─── Merge multiple schemas (for array items from multiple samples) ───────────
|
|
91
|
+
function mergeSchemas(schemas) {
|
|
92
|
+
if (schemas.length === 0) return {};
|
|
93
|
+
if (schemas.length === 1) return schemas[0];
|
|
94
|
+
|
|
95
|
+
// Check if all the same type
|
|
96
|
+
const types = [...new Set(schemas.map(s => s.type))];
|
|
97
|
+
if (types.length > 1) {
|
|
98
|
+
// Multiple types — use anyOf
|
|
99
|
+
const uniqueSchemas = deduplicateSchemas(schemas);
|
|
100
|
+
if (uniqueSchemas.length === 1) return uniqueSchemas[0];
|
|
101
|
+
return { anyOf: uniqueSchemas };
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const type = types[0];
|
|
105
|
+
|
|
106
|
+
if (type === 'object') {
|
|
107
|
+
// Merge object schemas: union all keys, mark keys missing in some as non-required
|
|
108
|
+
const allKeys = new Set(schemas.flatMap(s => Object.keys(s.properties || {})));
|
|
109
|
+
const properties = {};
|
|
110
|
+
const alwaysPresent = new Set([...allKeys]);
|
|
111
|
+
|
|
112
|
+
for (const key of allKeys) {
|
|
113
|
+
const keySchemas = schemas.filter(s => s.properties && key in s.properties).map(s => s.properties[key]);
|
|
114
|
+
if (keySchemas.length < schemas.length) alwaysPresent.delete(key);
|
|
115
|
+
properties[key] = mergeSchemas(keySchemas.length > 0 ? keySchemas : [{}]);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const merged = { type: 'object', properties, additionalProperties: false };
|
|
119
|
+
if (alwaysPresent.size > 0) merged.required = [...alwaysPresent];
|
|
120
|
+
return merged;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (type === 'array') {
|
|
124
|
+
const itemSchemas = schemas.map(s => s.items).filter(Boolean);
|
|
125
|
+
return { type: 'array', items: itemSchemas.length > 0 ? mergeSchemas(itemSchemas) : {} };
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Primitive: just return first (they're all the same type)
|
|
129
|
+
const first = schemas[0];
|
|
130
|
+
// If formats differ, drop the format
|
|
131
|
+
const formats = [...new Set(schemas.map(s => s.format).filter(Boolean))];
|
|
132
|
+
if (formats.length === 1) return first;
|
|
133
|
+
const { format, ...rest } = first;
|
|
134
|
+
return rest;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function deduplicateSchemas(schemas) {
|
|
138
|
+
const seen = new Set();
|
|
139
|
+
return schemas.filter(s => {
|
|
140
|
+
const key = JSON.stringify(s);
|
|
141
|
+
if (seen.has(key)) return false;
|
|
142
|
+
seen.add(key);
|
|
143
|
+
return true;
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// ─── Merge schemas from multiple sample files ─────────────────────────────────
|
|
148
|
+
function mergeFromSamples(samples, opts) {
|
|
149
|
+
const schemas = samples.map(v => inferSchema(v, opts));
|
|
150
|
+
return mergeSchemas(schemas);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// ─── CLI ──────────────────────────────────────────────────────────────────────
|
|
154
|
+
const args = process.argv.slice(2);
|
|
155
|
+
|
|
156
|
+
// Flags that consume the next argument as their value
|
|
157
|
+
const VALUE_FLAGS = new Set(['--id', '--title', '--out']);
|
|
158
|
+
|
|
159
|
+
function getFlag(f) {
|
|
160
|
+
const i = args.indexOf(f);
|
|
161
|
+
return i !== -1 ? args[i + 1] : null;
|
|
162
|
+
}
|
|
163
|
+
function hasFlag(f) { return args.includes(f); }
|
|
164
|
+
|
|
165
|
+
// Positional args: skip flags and their values
|
|
166
|
+
const positional = [];
|
|
167
|
+
for (let i = 0; i < args.length; i++) {
|
|
168
|
+
if (args[i].startsWith('-')) {
|
|
169
|
+
if (VALUE_FLAGS.has(args[i])) i++; // skip the next value too
|
|
170
|
+
} else {
|
|
171
|
+
positional.push(args[i]);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (hasFlag('--version') || hasFlag('-v')) {
|
|
176
|
+
console.log(`json-schema-gen v${VERSION}`); process.exit(0);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (hasFlag('--help') || hasFlag('-h') || !positional.length) {
|
|
180
|
+
console.log(`
|
|
181
|
+
${bold('json-schema-gen')} — Generate JSON Schema from sample JSON, zero dependencies
|
|
182
|
+
|
|
183
|
+
${bold('USAGE')}
|
|
184
|
+
json-schema-gen <file.json> [file2.json ...] [options]
|
|
185
|
+
|
|
186
|
+
${bold('OPTIONS')}
|
|
187
|
+
--required Mark all non-null fields as required
|
|
188
|
+
--examples Include example values for string fields
|
|
189
|
+
--id <uri> Add $id to the schema
|
|
190
|
+
--title <name> Add title to the schema
|
|
191
|
+
--out <file> Write schema to file instead of stdout
|
|
192
|
+
--pretty Pretty-print even when piped (default: always pretty)
|
|
193
|
+
--version Show version
|
|
194
|
+
|
|
195
|
+
${bold('EXAMPLES')}
|
|
196
|
+
json-schema-gen user.json
|
|
197
|
+
json-schema-gen user.json --required --title "User"
|
|
198
|
+
json-schema-gen sample1.json sample2.json # Merge multiple samples
|
|
199
|
+
json-schema-gen data.json --out schema.json
|
|
200
|
+
cat data.json | json-schema-gen - # Read from stdin
|
|
201
|
+
`);
|
|
202
|
+
process.exit(positional.length ? 0 : 1);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const allRequired = hasFlag('--required');
|
|
206
|
+
const showExamples = hasFlag('--examples');
|
|
207
|
+
const schemaId = getFlag('--id');
|
|
208
|
+
const schemaTitle = getFlag('--title');
|
|
209
|
+
const outFile = getFlag('--out');
|
|
210
|
+
|
|
211
|
+
const opts = { allRequired, examples: showExamples };
|
|
212
|
+
|
|
213
|
+
// Read all input files
|
|
214
|
+
const samples = [];
|
|
215
|
+
for (const p of positional) {
|
|
216
|
+
let raw;
|
|
217
|
+
if (p === '-') {
|
|
218
|
+
raw = fs.readFileSync('/dev/stdin', 'utf8');
|
|
219
|
+
} else {
|
|
220
|
+
const fullPath = path.resolve(p);
|
|
221
|
+
if (!fs.existsSync(fullPath)) {
|
|
222
|
+
console.error(red(`\nFile not found: ${fullPath}\n`)); process.exit(1);
|
|
223
|
+
}
|
|
224
|
+
raw = fs.readFileSync(fullPath, 'utf8');
|
|
225
|
+
}
|
|
226
|
+
try {
|
|
227
|
+
samples.push(JSON.parse(raw));
|
|
228
|
+
} catch (e) {
|
|
229
|
+
console.error(red(`\nInvalid JSON in ${p}: ${e.message}\n`)); process.exit(1);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Generate schema
|
|
234
|
+
const schema = samples.length === 1
|
|
235
|
+
? inferSchema(samples[0], opts)
|
|
236
|
+
: mergeFromSamples(samples, opts);
|
|
237
|
+
|
|
238
|
+
// Add meta fields
|
|
239
|
+
const output = {
|
|
240
|
+
$schema: 'https://json-schema.org/draft-07/schema',
|
|
241
|
+
...(schemaId ? { $id: schemaId } : {}),
|
|
242
|
+
...(schemaTitle ? { title: schemaTitle } : {}),
|
|
243
|
+
...schema,
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
const jsonStr = JSON.stringify(output, null, 2);
|
|
247
|
+
|
|
248
|
+
if (outFile) {
|
|
249
|
+
fs.writeFileSync(path.resolve(outFile), jsonStr + '\n');
|
|
250
|
+
const props = countProperties(output);
|
|
251
|
+
if (!isTTY || outFile) {
|
|
252
|
+
process.stderr.write(`\n${bold('json-schema-gen')} ${dim(outFile)}\n`);
|
|
253
|
+
process.stderr.write(dim(` ${props} propert${props === 1 ? 'y' : 'ies'} · ${positional.length} sample${positional.length > 1 ? 's' : ''}\n\n`));
|
|
254
|
+
}
|
|
255
|
+
} else {
|
|
256
|
+
console.log(jsonStr);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
function countProperties(schema, depth = 0) {
|
|
260
|
+
if (!schema || typeof schema !== 'object') return 0;
|
|
261
|
+
if (schema.type === 'object' && schema.properties) {
|
|
262
|
+
return Object.keys(schema.properties).reduce((sum, k) => sum + 1 + countProperties(schema.properties[k], depth + 1), 0);
|
|
263
|
+
}
|
|
264
|
+
if (schema.type === 'array' && schema.items) {
|
|
265
|
+
return countProperties(schema.items, depth);
|
|
266
|
+
}
|
|
267
|
+
return 0;
|
|
268
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lowdep/json-schema-gen",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Generate JSON Schema (draft-07) from sample JSON data — format detection, multi-sample merging, zero dependencies",
|
|
5
|
+
"bin": {
|
|
6
|
+
"json-schema-gen": "bin/json-schema-gen.js"
|
|
7
|
+
},
|
|
8
|
+
"keywords": [
|
|
9
|
+
"json",
|
|
10
|
+
"json-schema",
|
|
11
|
+
"schema",
|
|
12
|
+
"generator",
|
|
13
|
+
"cli",
|
|
14
|
+
"validation",
|
|
15
|
+
"zero-dependencies",
|
|
16
|
+
"json schema generator",
|
|
17
|
+
"json to schema",
|
|
18
|
+
"quicktype alternative",
|
|
19
|
+
"genson alternative",
|
|
20
|
+
"infer schema",
|
|
21
|
+
"draft-07",
|
|
22
|
+
"generate schema",
|
|
23
|
+
"json schema",
|
|
24
|
+
"zero dependencies"
|
|
25
|
+
],
|
|
26
|
+
"author": "Rushabh Shah",
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=14"
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"bin/"
|
|
33
|
+
],
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "git+https://github.com/Rushabh5000/json-schema-gen.git"
|
|
37
|
+
},
|
|
38
|
+
"bugs": {
|
|
39
|
+
"url": "https://github.com/Rushabh5000/json-schema-gen/issues"
|
|
40
|
+
},
|
|
41
|
+
"homepage": "https://github.com/Rushabh5000/json-schema-gen#readme",
|
|
42
|
+
"publishConfig": {
|
|
43
|
+
"access": "public"
|
|
44
|
+
}
|
|
45
|
+
}
|