@amritk/generate-parsers 0.19.3 → 0.19.4
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.
|
@@ -10,6 +10,7 @@ import { generateDiscriminatedUnionValidation } from "./generate-discriminated-u
|
|
|
10
10
|
import { generateEnumCaseInsensitiveCoercion, generateEnumCheck } from "./generate-enum-check.js";
|
|
11
11
|
import { generateNonDiscriminatedUnionValidation } from "./generate-non-discriminated-union-validation.js";
|
|
12
12
|
import { generateSchemaChecks } from "./generate-schema-checks.js";
|
|
13
|
+
import { generateUniqueItemsCheck } from "./generate-unique-items-check.js";
|
|
13
14
|
const getInstanceCoercion = (accessor, instanceOf, defaultValue) => {
|
|
14
15
|
if (instanceOf === "Date")
|
|
15
16
|
return `((_d) => Number.isNaN(_d.getTime()) ? ${defaultValue} : _d)(new Date(${accessor} as string | number | Date))`;
|
|
@@ -55,7 +56,7 @@ const prefixItemsCapsLength = (schema) => {
|
|
|
55
56
|
if (!isSchemaObject(schema))
|
|
56
57
|
return false;
|
|
57
58
|
const s = schema;
|
|
58
|
-
return s["items"] === false || s["additionalItems"] === false;
|
|
59
|
+
return (Object.hasOwn(s, "items") ? s["items"] : void 0) === false || (Object.hasOwn(s, "additionalItems") ? s["additionalItems"] : void 0) === false;
|
|
59
60
|
};
|
|
60
61
|
const singleTypeCheck = (accessor, type) => {
|
|
61
62
|
switch (type) {
|
|
@@ -259,7 +260,7 @@ const generateValidationExpression = (key, schema, defaultValue, isRequired, roo
|
|
|
259
260
|
checks.push(`${accessor}.length <= ${schema.maxItems}`);
|
|
260
261
|
}
|
|
261
262
|
if (hasUniqueItems(schema) && schema.uniqueItems === true) {
|
|
262
|
-
checks.push(
|
|
263
|
+
checks.push(generateUniqueItemsCheck(accessor, schema));
|
|
263
264
|
}
|
|
264
265
|
break;
|
|
265
266
|
}
|
|
@@ -7,17 +7,17 @@ const collectImports = (schema, options) => {
|
|
|
7
7
|
const typesOnly = options?.typesOnly === true;
|
|
8
8
|
const importExt = options?.importExt ?? "js";
|
|
9
9
|
const importMap = /* @__PURE__ */ new Map();
|
|
10
|
-
for (const [filename, typeName] of collectImportTargets(schema, options)) {
|
|
10
|
+
for (const [filename, { typeName, typeOnly }] of collectImportTargets(schema, options)) {
|
|
11
11
|
const importPath = getImportPathForFilename(filename, importExt);
|
|
12
|
-
const importStatement = typesOnly ? `import type { ${typeName} } from '${importPath}';` : `import { type ${typeName}, parse${typeName}, validate${typeName}Shape } from '${importPath}';`;
|
|
12
|
+
const importStatement = typesOnly || typeOnly ? `import type { ${typeName} } from '${importPath}';` : `import { type ${typeName}, parse${typeName}, validate${typeName}Shape } from '${importPath}';`;
|
|
13
13
|
importMap.set(filename, importStatement);
|
|
14
14
|
}
|
|
15
15
|
return Array.from(importMap.values()).sort();
|
|
16
16
|
};
|
|
17
17
|
const collectImportTypeNames = (schema, options) => {
|
|
18
18
|
const names = /* @__PURE__ */ new Set();
|
|
19
|
-
for (const [,
|
|
20
|
-
names.add(typeName);
|
|
19
|
+
for (const [, target] of collectImportTargets(schema, options))
|
|
20
|
+
names.add(target.typeName);
|
|
21
21
|
return names;
|
|
22
22
|
};
|
|
23
23
|
const collectImportTargets = (schema, options) => {
|
|
@@ -25,6 +25,8 @@ const collectImportTargets = (schema, options) => {
|
|
|
25
25
|
const rootSchema = options?.rootSchema;
|
|
26
26
|
const typeSuffix = options?.typeSuffix;
|
|
27
27
|
const refs = /* @__PURE__ */ new Set();
|
|
28
|
+
const valueRefs = /* @__PURE__ */ new Set();
|
|
29
|
+
let typeOnlyDepth = 0;
|
|
28
30
|
const collectRefsFromValue = (value) => {
|
|
29
31
|
if (typeof value !== "object" || value === null) {
|
|
30
32
|
return;
|
|
@@ -43,21 +45,34 @@ const collectImportTargets = (schema, options) => {
|
|
|
43
45
|
const isPropertyFragment = isUri && ref.includes("#/properties/");
|
|
44
46
|
if (isInternal || isUri && !isPropertyFragment) {
|
|
45
47
|
refs.add(ref);
|
|
48
|
+
if (typeOnlyDepth === 0)
|
|
49
|
+
valueRefs.add(ref);
|
|
46
50
|
}
|
|
47
51
|
return;
|
|
48
52
|
}
|
|
53
|
+
for (const keyword of ["prefixItems", "items"]) {
|
|
54
|
+
const positions = Object.hasOwn(record, keyword) ? record[keyword] : void 0;
|
|
55
|
+
if (!Array.isArray(positions))
|
|
56
|
+
continue;
|
|
57
|
+
typeOnlyDepth++;
|
|
58
|
+
for (const item of positions) {
|
|
59
|
+
collectRefsFromValue(item);
|
|
60
|
+
}
|
|
61
|
+
if (Object.hasOwn(record, "additionalItems"))
|
|
62
|
+
collectRefsFromValue(record["additionalItems"]);
|
|
63
|
+
typeOnlyDepth--;
|
|
64
|
+
}
|
|
49
65
|
if (hasAdditionalProperties(record) && hasRef(record.additionalProperties)) {
|
|
50
66
|
collectRefsFromValue(record.additionalProperties);
|
|
51
67
|
return;
|
|
52
68
|
}
|
|
53
|
-
if (record.type === "array" && hasItems(record) && hasRef(record.items)) {
|
|
69
|
+
if (record.type === "array" && hasItems(record) && !Array.isArray(record.items) && hasRef(record.items)) {
|
|
54
70
|
collectRefsFromValue(record.items);
|
|
55
71
|
return;
|
|
56
72
|
}
|
|
57
|
-
if ("properties"
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
collectRefsFromValue(props[key]);
|
|
73
|
+
if (Object.hasOwn(record, "properties") && typeof record.properties === "object" && record.properties !== null) {
|
|
74
|
+
for (const value2 of Object.values(record.properties)) {
|
|
75
|
+
collectRefsFromValue(value2);
|
|
61
76
|
}
|
|
62
77
|
}
|
|
63
78
|
if (hasOneOf(record)) {
|
|
@@ -75,22 +90,24 @@ const collectImportTargets = (schema, options) => {
|
|
|
75
90
|
collectRefsFromValue(item);
|
|
76
91
|
}
|
|
77
92
|
}
|
|
78
|
-
if (hasItems(record)) {
|
|
93
|
+
if (hasItems(record) && !Array.isArray(record.items)) {
|
|
79
94
|
collectRefsFromValue(record.items);
|
|
80
95
|
}
|
|
81
96
|
if (hasAdditionalProperties(record)) {
|
|
82
97
|
collectRefsFromValue(record.additionalProperties);
|
|
83
98
|
}
|
|
84
|
-
if ("patternProperties"
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
collectRefsFromValue(patternProps[key]);
|
|
99
|
+
if (Object.hasOwn(record, "patternProperties") && typeof record.patternProperties === "object" && record.patternProperties !== null) {
|
|
100
|
+
for (const value2 of Object.values(record.patternProperties)) {
|
|
101
|
+
collectRefsFromValue(value2);
|
|
88
102
|
}
|
|
89
103
|
}
|
|
90
|
-
if ("
|
|
104
|
+
if (Object.hasOwn(record, "if")) {
|
|
105
|
+
collectRefsFromValue(record.if);
|
|
106
|
+
}
|
|
107
|
+
if (Object.hasOwn(record, "then")) {
|
|
91
108
|
collectRefsFromValue(record.then);
|
|
92
109
|
}
|
|
93
|
-
if ("else"
|
|
110
|
+
if (Object.hasOwn(record, "else")) {
|
|
94
111
|
collectRefsFromValue(record.else);
|
|
95
112
|
}
|
|
96
113
|
};
|
|
@@ -101,26 +118,39 @@ const collectImportTargets = (schema, options) => {
|
|
|
101
118
|
const isPropertyFragment = isUri && ref.includes("#/properties/");
|
|
102
119
|
if (isInternal || isUri && !isPropertyFragment) {
|
|
103
120
|
refs.add(ref);
|
|
121
|
+
valueRefs.add(ref);
|
|
104
122
|
}
|
|
105
123
|
}
|
|
106
|
-
if (typeof schema === "object" && schema !== null && "properties"
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
collectRefsFromValue(properties[key]);
|
|
124
|
+
if (typeof schema === "object" && schema !== null && Object.hasOwn(schema, "properties") && typeof schema.properties === "object" && schema.properties !== null) {
|
|
125
|
+
for (const value of Object.values(schema.properties)) {
|
|
126
|
+
collectRefsFromValue(value);
|
|
110
127
|
}
|
|
111
128
|
}
|
|
112
|
-
if (typeof schema === "object" && schema !== null && "additionalProperties"
|
|
129
|
+
if (typeof schema === "object" && schema !== null && Object.hasOwn(schema, "additionalProperties")) {
|
|
113
130
|
collectRefsFromValue(schema.additionalProperties);
|
|
114
131
|
}
|
|
115
|
-
if (typeof schema === "object" && schema !== null && "patternProperties"
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
collectRefsFromValue(patternProps[key]);
|
|
132
|
+
if (typeof schema === "object" && schema !== null && Object.hasOwn(schema, "patternProperties") && typeof schema.patternProperties === "object" && schema.patternProperties !== null) {
|
|
133
|
+
for (const value of Object.values(schema.patternProperties)) {
|
|
134
|
+
collectRefsFromValue(value);
|
|
119
135
|
}
|
|
120
136
|
}
|
|
121
|
-
if (typeof schema === "object" && schema !== null && hasItems(schema)) {
|
|
137
|
+
if (typeof schema === "object" && schema !== null && hasItems(schema) && !Array.isArray(schema.items)) {
|
|
122
138
|
collectRefsFromValue(schema.items);
|
|
123
139
|
}
|
|
140
|
+
if (typeof schema === "object" && schema !== null) {
|
|
141
|
+
const record = schema;
|
|
142
|
+
for (const keyword of ["prefixItems", "items"]) {
|
|
143
|
+
const positions = Object.hasOwn(record, keyword) ? record[keyword] : void 0;
|
|
144
|
+
if (!Array.isArray(positions))
|
|
145
|
+
continue;
|
|
146
|
+
typeOnlyDepth++;
|
|
147
|
+
for (const item of positions)
|
|
148
|
+
collectRefsFromValue(item);
|
|
149
|
+
if (Object.hasOwn(record, "additionalItems"))
|
|
150
|
+
collectRefsFromValue(record["additionalItems"]);
|
|
151
|
+
typeOnlyDepth--;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
124
154
|
if (typeof schema === "object" && schema !== null && hasOneOf(schema)) {
|
|
125
155
|
for (const item of schema.oneOf) {
|
|
126
156
|
collectRefsFromValue(item);
|
|
@@ -136,13 +166,13 @@ const collectImportTargets = (schema, options) => {
|
|
|
136
166
|
collectRefsFromValue(item);
|
|
137
167
|
}
|
|
138
168
|
}
|
|
139
|
-
if (typeof schema === "object" && schema !== null && "if"
|
|
169
|
+
if (typeof schema === "object" && schema !== null && Object.hasOwn(schema, "if")) {
|
|
140
170
|
collectRefsFromValue(schema.if);
|
|
141
171
|
}
|
|
142
|
-
if (typeof schema === "object" && schema !== null && "then"
|
|
172
|
+
if (typeof schema === "object" && schema !== null && Object.hasOwn(schema, "then")) {
|
|
143
173
|
collectRefsFromValue(schema.then);
|
|
144
174
|
}
|
|
145
|
-
if (typeof schema === "object" && schema !== null && "else"
|
|
175
|
+
if (typeof schema === "object" && schema !== null && Object.hasOwn(schema, "else")) {
|
|
146
176
|
collectRefsFromValue(schema.else);
|
|
147
177
|
}
|
|
148
178
|
const targets = /* @__PURE__ */ new Map();
|
|
@@ -156,7 +186,8 @@ const collectImportTargets = (schema, options) => {
|
|
|
156
186
|
if (selfFilename !== void 0 && filename === selfFilename) {
|
|
157
187
|
continue;
|
|
158
188
|
}
|
|
159
|
-
targets.
|
|
189
|
+
const typeOnly = !valueRefs.has(ref) && (targets.get(filename)?.typeOnly ?? true);
|
|
190
|
+
targets.set(filename, { typeName, typeOnly });
|
|
160
191
|
}
|
|
161
192
|
return targets;
|
|
162
193
|
};
|
|
@@ -26,8 +26,8 @@ const defaultMatchesType = (value, schema) => {
|
|
|
26
26
|
const MAX_FALLBACK_ITEMS = 32;
|
|
27
27
|
const arrayFallback = (schema) => {
|
|
28
28
|
const record = schema;
|
|
29
|
-
const positions = Array.isArray(record["prefixItems"]) ? record["prefixItems"] : Array.isArray(record["items"]) ? record["items"] : [];
|
|
30
|
-
const tail = Array.isArray(record["items"]) ? record["additionalItems"] : record["items"];
|
|
29
|
+
const positions = Array.isArray(Object.hasOwn(record, "prefixItems") ? record["prefixItems"] : void 0) ? Object.hasOwn(record, "prefixItems") ? record["prefixItems"] : void 0 : Array.isArray(Object.hasOwn(record, "items") ? record["items"] : void 0) ? Object.hasOwn(record, "items") ? record["items"] : void 0 : [];
|
|
30
|
+
const tail = Array.isArray(Object.hasOwn(record, "items") ? record["items"] : void 0) ? Object.hasOwn(record, "additionalItems") ? record["additionalItems"] : void 0 : Object.hasOwn(record, "items") ? record["items"] : void 0;
|
|
31
31
|
const minItems = typeof record["minItems"] === "number" ? record["minItems"] : 0;
|
|
32
32
|
const wanted = minItems > MAX_FALLBACK_ITEMS ? Math.min(minItems, positions.length) : minItems;
|
|
33
33
|
if (wanted === 0)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@amritk/generate-parsers",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.4",
|
|
4
4
|
"description": "Generate TypeScript parsers and type definitions from JSON Schemas.",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -56,10 +56,10 @@
|
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
58
|
"json-schema-typed": "^8.0.1",
|
|
59
|
-
"@amritk/helpers": "^0.15.
|
|
59
|
+
"@amritk/helpers": "^0.15.4"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
|
-
"@amritk/generate-markdown": "^0.4.
|
|
62
|
+
"@amritk/generate-markdown": "^0.4.9",
|
|
63
63
|
"@sinclair/typebox": "^0.34.49",
|
|
64
64
|
"ajv": "^8.17.1",
|
|
65
65
|
"zod": "^4.4.3"
|