@amritk/generate-parsers 0.11.0 → 0.11.1
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.
|
@@ -796,6 +796,40 @@ const generateObjectParser = (schema, typeName, useRefImports, suffix, logWarnin
|
|
|
796
796
|
lines.push(objectLines.join('\n'));
|
|
797
797
|
lines.push(` } as unknown as ${typeName};`);
|
|
798
798
|
};
|
|
799
|
+
// The deep-guard fast path. `{ ...input }` is the only correct shape when the
|
|
800
|
+
// guard let undeclared keys through (no known-keys term) — they must survive.
|
|
801
|
+
// But when `stripKeys` is set the guard *also* proved `_hasOnlyKnownKeys`, so
|
|
802
|
+
// the input's keys are exactly the declared properties: an explicit literal of
|
|
803
|
+
// those keys is then equivalent to the spread, and faster — a fixed-shape
|
|
804
|
+
// literal beats a generic spread, yields a stable hidden class, and produces
|
|
805
|
+
// the same declared key order as the slow path (the spread used input order).
|
|
806
|
+
// The literal shares each value by reference, exactly like the spread did, so
|
|
807
|
+
// it never re-parses an already-validated nested object. allOf merges in
|
|
808
|
+
// properties this `propInfo` list doesn't carry, so it keeps the spread.
|
|
809
|
+
const emitDeepGuardReturn = (lines) => {
|
|
810
|
+
const canLiteral = stripKeys && !(isSchemaObject(schema) && hasAllOf(schema));
|
|
811
|
+
if (!canLiteral) {
|
|
812
|
+
lines.push(` if (${deepGuard}) return { ...input } as ${typeName};`);
|
|
813
|
+
return;
|
|
814
|
+
}
|
|
815
|
+
const fields = [];
|
|
816
|
+
for (const { key, varName, isRequired, propSchema } of propInfo) {
|
|
817
|
+
if (!isSchemaObject(propSchema)) {
|
|
818
|
+
if (isRequired)
|
|
819
|
+
fields.push(` ${safeKey(key)}: undefined,`);
|
|
820
|
+
continue;
|
|
821
|
+
}
|
|
822
|
+
const accessor = shouldCacheVariable(propSchema, canFastPath, useRefImports)
|
|
823
|
+
? varName
|
|
824
|
+
: safeAccessor('input', key);
|
|
825
|
+
fields.push(isRequired
|
|
826
|
+
? ` ${safeKey(key)}: ${accessor},`
|
|
827
|
+
: ` ...(${accessor} !== undefined && { ${safeKey(key)}: ${accessor} }),`);
|
|
828
|
+
}
|
|
829
|
+
lines.push(` if (${deepGuard}) return {`);
|
|
830
|
+
lines.push(fields.join('\n'));
|
|
831
|
+
lines.push(` } as ${typeName};`);
|
|
832
|
+
};
|
|
799
833
|
const lines = [];
|
|
800
834
|
lines.push(`${exportPrefix}const ${functionName} = (input: unknown): ${typeName} => {`);
|
|
801
835
|
if (strict) {
|
|
@@ -819,7 +853,7 @@ const generateObjectParser = (schema, typeName, useRefImports, suffix, logWarnin
|
|
|
819
853
|
}
|
|
820
854
|
else {
|
|
821
855
|
if (deepGuard) {
|
|
822
|
-
lines
|
|
856
|
+
emitDeepGuardReturn(lines);
|
|
823
857
|
}
|
|
824
858
|
for (const assertionLine of assertionLines) {
|
|
825
859
|
lines.push(assertionLine);
|
|
@@ -837,7 +871,7 @@ const generateObjectParser = (schema, typeName, useRefImports, suffix, logWarnin
|
|
|
837
871
|
lines.push(...varDeclLines);
|
|
838
872
|
lines.push(...warnLines);
|
|
839
873
|
if (deepGuard) {
|
|
840
|
-
lines
|
|
874
|
+
emitDeepGuardReturn(lines);
|
|
841
875
|
}
|
|
842
876
|
emitReturn(lines, buildObjectLines(false));
|
|
843
877
|
}
|