@amritk/generate-parsers 0.16.3 → 0.17.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/dist/generators/assert-supported-keywords.js +45 -72
- package/dist/generators/build-schema.js +56 -168
- package/dist/generators/generate-default-from-pattern.js +24 -31
- package/dist/generators/generate-discriminated-union-validation.js +27 -47
- package/dist/generators/generate-enum-check.js +27 -61
- package/dist/generators/generate-files.js +54 -83
- package/dist/generators/generate-non-discriminated-union-validation.js +24 -26
- package/dist/generators/generate-parser-function.d.ts +12 -0
- package/dist/generators/generate-parser-function.js +1132 -1711
- package/dist/generators/generate-schema-checks.js +216 -250
- package/dist/generators/generate-strict-assertion.js +311 -447
- package/dist/generators/generate-type-checks.js +287 -460
- package/dist/generators/generate-validation-expression.js +300 -439
- package/dist/generators/subschema-match.js +201 -266
- package/dist/helpers/apply-schema-extensions.js +18 -49
- package/dist/helpers/collect-helpers.js +58 -71
- package/dist/helpers/collect-imports.js +161 -237
- package/dist/helpers/find-discriminator.js +23 -29
- package/dist/helpers/get-default-value.js +76 -96
- package/dist/helpers/get-discriminator-value.js +16 -17
- package/dist/index.js +4 -1
- package/package.json +4 -4
|
@@ -1,104 +1,84 @@
|
|
|
1
|
-
import { getMjstPrimitive } from
|
|
2
|
-
import { hasAllOf, hasAnyOf, hasConst, hasDefault, hasEnum, hasExamples, hasOneOf, hasPattern, hasProperties, hasRequired, hasType, isSchemaObject
|
|
3
|
-
import { generateDefaultFromPattern } from
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
import { getMjstPrimitive } from "@amritk/helpers/mjst-extension";
|
|
2
|
+
import { hasAllOf, hasAnyOf, hasConst, hasDefault, hasEnum, hasExamples, hasOneOf, hasPattern, hasProperties, hasRequired, hasType, isSchemaObject } from "@amritk/helpers/schema-guards";
|
|
3
|
+
import { generateDefaultFromPattern } from "../generators/generate-default-from-pattern.js";
|
|
4
|
+
const getDefaultValue = (schema) => {
|
|
5
|
+
if (!isSchemaObject(schema)) {
|
|
6
|
+
return "undefined";
|
|
7
|
+
}
|
|
8
|
+
if (hasDefault(schema)) {
|
|
9
|
+
return JSON.stringify(schema.default);
|
|
10
|
+
}
|
|
11
|
+
if (hasConst(schema)) {
|
|
12
|
+
return JSON.stringify(schema.const);
|
|
13
|
+
}
|
|
14
|
+
if (hasEnum(schema) && schema.enum.length > 0) {
|
|
15
|
+
return JSON.stringify(schema.enum[0]);
|
|
16
|
+
}
|
|
17
|
+
if (hasExamples(schema) && schema.examples.length > 0) {
|
|
18
|
+
return JSON.stringify(schema.examples[0]);
|
|
19
|
+
}
|
|
20
|
+
if (hasOneOf(schema) && schema.oneOf.length > 0) {
|
|
21
|
+
const firstSchema = schema.oneOf[0];
|
|
22
|
+
if (firstSchema !== void 0) {
|
|
23
|
+
return getDefaultValue(firstSchema);
|
|
12
24
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
25
|
+
}
|
|
26
|
+
if (hasAnyOf(schema) && schema.anyOf.length > 0) {
|
|
27
|
+
const firstSchema = schema.anyOf[0];
|
|
28
|
+
if (firstSchema !== void 0) {
|
|
29
|
+
return getDefaultValue(firstSchema);
|
|
16
30
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
31
|
+
}
|
|
32
|
+
if (hasAllOf(schema) && schema.allOf.length > 0) {
|
|
33
|
+
const firstSchema = schema.allOf[0];
|
|
34
|
+
if (firstSchema !== void 0) {
|
|
35
|
+
return getDefaultValue(firstSchema);
|
|
20
36
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
if (firstSchema !== undefined) {
|
|
39
|
-
return getDefaultValue(firstSchema);
|
|
37
|
+
}
|
|
38
|
+
if (getMjstPrimitive(schema) === "bigint") {
|
|
39
|
+
return "0n";
|
|
40
|
+
}
|
|
41
|
+
const rawType = schema["type"];
|
|
42
|
+
if (Array.isArray(rawType) && rawType.length > 0 && typeof rawType[0] === "string") {
|
|
43
|
+
return getDefaultValue({ ...schema, type: rawType[0] });
|
|
44
|
+
}
|
|
45
|
+
if (!hasType(schema)) {
|
|
46
|
+
return "undefined";
|
|
47
|
+
}
|
|
48
|
+
switch (schema.type) {
|
|
49
|
+
case "string": {
|
|
50
|
+
if (hasPattern(schema)) {
|
|
51
|
+
const patternDefault = generateDefaultFromPattern(schema.pattern);
|
|
52
|
+
if (patternDefault) {
|
|
53
|
+
return patternDefault;
|
|
40
54
|
}
|
|
55
|
+
}
|
|
56
|
+
return '""';
|
|
41
57
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
58
|
+
case "number":
|
|
59
|
+
case "integer":
|
|
60
|
+
return "0";
|
|
61
|
+
case "boolean":
|
|
62
|
+
return "false";
|
|
63
|
+
case "null":
|
|
64
|
+
return "null";
|
|
65
|
+
case "array":
|
|
66
|
+
return "[]";
|
|
67
|
+
case "object": {
|
|
68
|
+
if (hasProperties(schema) && hasRequired(schema)) {
|
|
69
|
+
const props = schema.properties;
|
|
70
|
+
const required = schema.required.filter((key) => Object.hasOwn(props, key));
|
|
71
|
+
const defaults = required.map((key) => getDefaultValue(props[key]));
|
|
72
|
+
if (defaults.length > 0 && !defaults.includes("undefined")) {
|
|
73
|
+
return `{ ${required.map((key, i) => `${JSON.stringify(key)}: ${defaults[i]}`).join(", ")} }`;
|
|
47
74
|
}
|
|
75
|
+
}
|
|
76
|
+
return "{}";
|
|
48
77
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
// violating both `required` and the declared type. Derive the default from the
|
|
56
|
-
// first listed type so the fallback is a valid member.
|
|
57
|
-
const rawType = schema['type'];
|
|
58
|
-
if (Array.isArray(rawType) && rawType.length > 0 && typeof rawType[0] === 'string') {
|
|
59
|
-
return getDefaultValue({ ...schema, type: rawType[0] });
|
|
60
|
-
}
|
|
61
|
-
if (!hasType(schema)) {
|
|
62
|
-
return 'undefined';
|
|
63
|
-
}
|
|
64
|
-
switch (schema.type) {
|
|
65
|
-
case 'string': {
|
|
66
|
-
if (hasPattern(schema)) {
|
|
67
|
-
const patternDefault = generateDefaultFromPattern(schema.pattern);
|
|
68
|
-
if (patternDefault) {
|
|
69
|
-
return patternDefault;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
return '""';
|
|
73
|
-
}
|
|
74
|
-
case 'number':
|
|
75
|
-
case 'integer':
|
|
76
|
-
return '0';
|
|
77
|
-
case 'boolean':
|
|
78
|
-
return 'false';
|
|
79
|
-
case 'null':
|
|
80
|
-
return 'null';
|
|
81
|
-
case 'array':
|
|
82
|
-
return '[]';
|
|
83
|
-
case 'object': {
|
|
84
|
-
// A bare `{}` omits required properties, leaving the default invalid against
|
|
85
|
-
// its own type. Populate each required property with its own default so the
|
|
86
|
-
// fallback object is itself a valid instance.
|
|
87
|
-
if (hasProperties(schema) && hasRequired(schema)) {
|
|
88
|
-
const props = schema.properties;
|
|
89
|
-
const required = schema.required.filter((key) => Object.hasOwn(props, key));
|
|
90
|
-
const defaults = required.map((key) => getDefaultValue(props[key]));
|
|
91
|
-
// A required property whose schema has no concrete default (a `$ref` we
|
|
92
|
-
// can't resolve here, or a type-less schema) would otherwise emit
|
|
93
|
-
// `"key": undefined` — i.e. a *missing* required key. Don't build a
|
|
94
|
-
// partial object with holes; fall back to a bare `{}` for the whole node.
|
|
95
|
-
if (defaults.length > 0 && !defaults.includes('undefined')) {
|
|
96
|
-
return `{ ${required.map((key, i) => `${JSON.stringify(key)}: ${defaults[i]}`).join(', ')} }`;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
return '{}';
|
|
100
|
-
}
|
|
101
|
-
default:
|
|
102
|
-
return 'undefined';
|
|
103
|
-
}
|
|
78
|
+
default:
|
|
79
|
+
return "undefined";
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
export {
|
|
83
|
+
getDefaultValue
|
|
104
84
|
};
|
|
@@ -1,19 +1,18 @@
|
|
|
1
|
-
import { hasConst, hasEnum, hasProperties, isObjectSchema, isSchemaObject } from
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
if (hasEnum(propSchema) && propSchema.enum.length === 1) {
|
|
14
|
-
return propSchema.enum[0];
|
|
15
|
-
}
|
|
16
|
-
}
|
|
1
|
+
import { hasConst, hasEnum, hasProperties, isObjectSchema, isSchemaObject } from "@amritk/helpers/schema-guards";
|
|
2
|
+
const getDiscriminatorValue = (schema, discriminatorKey) => {
|
|
3
|
+
if (isObjectSchema(schema) && hasProperties(schema)) {
|
|
4
|
+
const propSchema = schema.properties[discriminatorKey];
|
|
5
|
+
if (propSchema && isSchemaObject(propSchema)) {
|
|
6
|
+
if (hasConst(propSchema)) {
|
|
7
|
+
return propSchema.const;
|
|
8
|
+
}
|
|
9
|
+
if (hasEnum(propSchema) && propSchema.enum.length === 1) {
|
|
10
|
+
return propSchema.enum[0];
|
|
11
|
+
}
|
|
17
12
|
}
|
|
18
|
-
|
|
13
|
+
}
|
|
14
|
+
return null;
|
|
15
|
+
};
|
|
16
|
+
export {
|
|
17
|
+
getDiscriminatorValue
|
|
19
18
|
};
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@amritk/generate-parsers",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"description": "Generate TypeScript parsers and type definitions from JSON Schemas.",
|
|
5
5
|
"module": "./dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"access": "public"
|
|
30
30
|
},
|
|
31
31
|
"scripts": {
|
|
32
|
-
"build": "tsgo -p tsconfig.build.json && tsc-alias -p tsconfig.build.json -f",
|
|
32
|
+
"build": "tsgo -p tsconfig.build.json && tsc-alias -p tsconfig.build.json -f && node ../../scripts/strip-comments.mjs",
|
|
33
33
|
"types:check": "tsgo -p . --noEmit",
|
|
34
34
|
"test": "NODE_ENV=production vitest run --root ../.. generate-parsers",
|
|
35
35
|
"generate-readme": "bun run ./scripts/generate-readme.ts",
|
|
@@ -48,8 +48,8 @@
|
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
50
|
"json-schema-typed": "^8.0.1",
|
|
51
|
-
"@amritk/helpers": "0.13.
|
|
52
|
-
"@amritk/generate-markdown": "0.4.
|
|
51
|
+
"@amritk/helpers": "0.13.3",
|
|
52
|
+
"@amritk/generate-markdown": "0.4.3"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@sinclair/typebox": "^0.34.49",
|