Skip to content

Commit cc1da8d

Browse files
committed
chore: use getOwn check instead of Object.create(null
1 parent 70a6939 commit cc1da8d

File tree

7 files changed

+18
-14
lines changed

7 files changed

+18
-14
lines changed

packages/core/src/resolve.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
isExternalValue,
1111
} from './ref-utils.js';
1212
import { isNamedType, SpecExtension } from './types/index.js';
13-
import { readFileFromUrl, parseYaml, nextTick } from './utils.js';
13+
import { readFileFromUrl, parseYaml, nextTick, getOwn } from './utils.js';
1414

1515
import type { YAMLNode, LoadOptions } from 'yaml-ast-parser';
1616
import type { NormalizedNodeType } from './types/index.js';
@@ -299,7 +299,7 @@ export async function resolveDocument(opts: {
299299

300300
for (const propName of Object.keys(node)) {
301301
let propValue = node[propName];
302-
let propType = type.properties[propName];
302+
let propType = getOwn(type.properties, propName);
303303
if (propType === undefined) propType = type.additionalProperties;
304304
if (typeof propType === 'function') propType = propType(propValue, propName);
305305
if (propType === undefined) propType = unknownType;

packages/core/src/rules/common/no-required-schema-properties-undefined.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import type { Oas2Rule, Oas3Rule } from '../../visitors.js';
44
import type { Oas3Schema, Oas3_1Schema } from '../../typings/openapi.js';
55
import type { Oas2Schema } from '../../typings/swagger.js';
66
import type { UserContext } from '../../walk.js';
7+
import { getOwn } from '../../utils.js';
78

89
export const NoRequiredSchemaPropertiesUndefined: Oas3Rule | Oas2Rule = () => {
910
return {
@@ -41,7 +42,7 @@ export const NoRequiredSchemaPropertiesUndefined: Oas3Rule | Oas2Rule = () => {
4142
const allProperties = elevateProperties(schema);
4243

4344
for (const [i, requiredProperty] of schema.required.entries()) {
44-
if (!allProperties || allProperties[requiredProperty] === undefined) {
45+
if (!allProperties || getOwn(allProperties, requiredProperty) === undefined) {
4546
report({
4647
message: `Required property '${requiredProperty}' is undefined.`,
4748
location: location.child(['required', i]),

packages/core/src/rules/common/scalar-property-missing-example.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { SpecVersion } from '../../oas-types.js';
2+
import { getOwn } from '../../utils.js';
23

34
import type { Oas2Rule, Oas3Rule } from '../../visitors.js';
45
import type { UserContext } from '../../walk.js';
@@ -14,7 +15,7 @@ export const ScalarPropertyMissingExample: Oas3Rule | Oas2Rule = () => {
1415
{ report, location, oasVersion, resolve }: UserContext
1516
) {
1617
for (const propName of Object.keys(properties)) {
17-
const propSchema = resolve(properties[propName]).node;
18+
const propSchema = resolve(getOwn(properties, propName)).node;
1819

1920
if (!propSchema || !isScalarSchema(propSchema)) {
2021
continue;

packages/core/src/rules/common/struct.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { isNamedType, SpecExtension } from '../../types/index.js';
22
import { oasTypeOf, matchesJsonSchemaType, getSuggest, validateSchemaEnumType } from '../utils.js';
33
import { isRef } from '../../ref-utils.js';
4-
import { isPlainObject } from '../../utils.js';
4+
import { getOwn, isPlainObject } from '../../utils.js';
55

66
import type { UserContext } from '../../walk.js';
77
import type {
@@ -102,7 +102,7 @@ export const Struct:
102102
const propLocation = location.child([propName]);
103103
let propValue = node[propName];
104104

105-
let propType = type.properties[propName];
105+
let propType = getOwn(type.properties, propName);
106106
if (propType === undefined) propType = type.additionalProperties;
107107
if (typeof propType === 'function') propType = propType(propValue, propName);
108108

packages/core/src/types/index.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,22 +47,22 @@ type NormalizedResolveTypeFn = (value: any, key: string) => NormalizedPropType;
4747
export function listOf(typeName: string) {
4848
return {
4949
name: `${typeName}List`,
50-
properties: Object.create(null),
50+
properties: {},
5151
items: typeName,
5252
};
5353
}
5454

5555
export function mapOf(typeName: string) {
5656
return {
5757
name: `${typeName}Map`,
58-
properties: Object.create(null),
58+
properties: {},
5959
additionalProperties: () => typeName,
6060
};
6161
}
6262

6363
export const SpecExtension: NormalizedNodeType = {
6464
name: 'SpecExtension',
65-
properties: Object.create(null),
65+
properties: {},
6666
// skip validation of additional properties for unknown extensions
6767
additionalProperties: { resolvable: true },
6868
};
@@ -98,9 +98,7 @@ export function normalizeTypes(
9898
}
9999

100100
if (type.properties) {
101-
// make sure to create a object without prototype so we don't need to check for hasOwnProperty
102-
// see https://github.com/Redocly/redocly-cli/issues/2104
103-
const mappedProps: Record<string, any> = Object.create(null);
101+
const mappedProps: Record<string, any> = {};
104102
for (const [propName, prop] of Object.entries(type.properties)) {
105103
mappedProps[propName] = resolveType(prop);
106104

packages/core/src/utils.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,10 @@ export function dequal(foo: any, bar: any): boolean {
296296
return foo !== foo && bar !== bar;
297297
}
298298

299+
export function getOwn(obj: Record<string, any>, key: string) {
300+
return obj.hasOwnProperty(key) ? obj[key] : undefined;
301+
}
302+
299303
export type CollectFn = (value: unknown) => void;
300304

301305
export type StrictObject<T extends object> = T & { [key: string]: undefined };

packages/core/src/walk.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Location, isRef } from './ref-utils.js';
2-
import { pushStack, popStack } from './utils.js';
2+
import { pushStack, popStack, getOwn } from './utils.js';
33
import { YamlParseError, makeRefId } from './resolve.js';
44
import { isNamedType, SpecExtension } from './types/index.js';
55

@@ -308,7 +308,7 @@ export function walkDocument<T extends BaseVisitor>(opts: {
308308
loc = location; // properties on the same level as $ref should resolve against original location, not target
309309
}
310310

311-
let propType = type.properties[propName];
311+
let propType = getOwn(type.properties, propName);
312312
if (propType === undefined) propType = type.additionalProperties;
313313
if (typeof propType === 'function') propType = propType(value, propName);
314314

0 commit comments

Comments
 (0)