Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/core/src/bundle/bundle-visitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ export function makeBundleVisitor({
keepUrlRefs: boolean;
componentRenamingConflicts?: RuleSeverity;
}) {
let components: Record<string, Record<string, any>>;
let components: Record<string, Record<string, unknown>>;
let rootLocation: Location;

const visitor: Oas3Visitor | Oas2Visitor = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { isEmptyObject } from '../../../utils/is-empty-object.js';
import { isPlainObject } from '../../../utils/is-plain-object.js';
import type { UserContext } from '../../../walk.js';

export function filter(node: any, ctx: UserContext, criteria: (item: any) => boolean) {
export function filter(node: unknown, ctx: UserContext, criteria: (item: unknown) => boolean) {
const { parent, key } = ctx;
let didDelete = false;
if (Array.isArray(node)) {
Expand All @@ -25,7 +25,6 @@ export function filter(node: any, ctx: UserContext, criteria: (item: any) => boo
}
} else if (isPlainObject(node)) {
for (const key of Object.keys(node)) {
node = node as any;
if (isRef(node[key])) {
const resolved = ctx.resolve(node[key]);
if (criteria(resolved.node)) {
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/env.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export const isBrowser =
typeof window !== 'undefined' ||
typeof process === 'undefined' ||
(process?.platform as any) === 'browser'; // main and worker thread
(process?.platform as string) === 'browser'; // main and worker thread
export const env = isBrowser ? {} : process.env || {};
14 changes: 7 additions & 7 deletions packages/core/src/format/format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,9 +230,9 @@ export function formatProblems(
totals,
version,
problems: problems.map((p) => {
const problem = {
const problem: Record<string, unknown> = {
...p,
location: p.location.map((location: any) => ({
location: p.location.map((location: LocationObject) => ({
...location,
source: {
ref: isAbsoluteUrl(location.source.absoluteRef)
Expand All @@ -255,7 +255,7 @@ export function formatProblems(
if (env.FORMAT_JSON_WITH_CODEFRAMES) {
const location = p.location[0]; // TODO: support multiple locations
const loc = getLineColLocation(location);
(problem as any).codeframe = getCodeframe(loc, color);
problem.codeframe = getCodeframe(loc, color);
}
return problem;
}),
Expand Down Expand Up @@ -458,14 +458,14 @@ function outputForGithubActions(problems: NormalizedProblem[], cwd: string): voi
}
}

function formatProperties(props: Record<string, any>): string {
function formatProperties(props: Record<string, unknown>): string {
return Object.entries(props)
.filter(([, v]) => v !== null && v !== undefined)
.map(([k, v]) => `${k}=${escapeProperty(v)}`)
.join(',');
}

function toString(v: any): string {
function toString(v: unknown): string {
if (v === null || v === undefined) {
return '';
} else if (typeof v === 'string' || v instanceof String) {
Expand All @@ -474,10 +474,10 @@ function outputForGithubActions(problems: NormalizedProblem[], cwd: string): voi
return JSON.stringify(v);
}

function escapeMessage(v: any): string {
function escapeMessage(v: unknown): string {
return toString(v).replace(/%/g, '%25').replace(/\r/g, '%0D').replace(/\n/g, '%0A');
}
function escapeProperty(v: any): string {
function escapeProperty(v: unknown): string {
return toString(v)
.replace(/%/g, '%25')
.replace(/\r/g, '%0D')
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export const colorize = new Proxy(colorette, {
return identity;
}

// oxlint-disable-next-line typescript/no-explicit-any
return (target as any)[prop];
},
});
Expand Down
64 changes: 37 additions & 27 deletions packages/core/src/resolve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
import { isNamedType, SpecExtension, type NormalizedNodeType } from './types/index.js';
import type { OasRef } from './typings/openapi.js';
import { getOwn } from './utils/get-own.js';
import { isPlainObject } from './utils/is-plain-object.js';
import { makeRefId } from './utils/make-ref-id.js';
import { nextTick } from './utils/next-tick.js';
import { readFileFromUrl } from './utils/read-file-from-url.js';
Expand Down Expand Up @@ -193,17 +194,17 @@ export type ResolvedRefMap = Map<string, ResolvedRef>;

type RefFrame = {
prev: RefFrame | null;
node: any;
node: unknown;
};

function pushRef(head: RefFrame, node: any): RefFrame {
function pushRef(head: RefFrame, node: unknown): RefFrame {
return {
prev: head,
node,
};
}

function hasRef(head: RefFrame | null, node: any): boolean {
function hasRef(head: RefFrame | null, node: unknown): boolean {
while (head) {
if (head.node === node) {
return true;
Expand Down Expand Up @@ -236,18 +237,18 @@ export async function resolveDocument(opts: {
return resolvedRefMap;

function resolveRefsInParallel(
rootNode: any,
rootNode: unknown,
rootNodeDocument: Document,
rootNodePointer: string,
type: any
type: NormalizedNodeType
) {
const rootNodeDocAbsoluteRef = rootNodeDocument.source.absoluteRef;
const anchorRefsMap: Map<string, any> = new Map();
const anchorRefsMap: Map<string, unknown> = new Map();

walk(rootNode, type, rootNodeDocAbsoluteRef + rootNodePointer);

function walk(node: any, type: NormalizedNodeType, nodeAbsoluteRef: string) {
if (typeof node !== 'object' || node === null) {
function walk(node: unknown, type: NormalizedNodeType, nodeAbsoluteRef: string) {
if (!isPlainObject(node) && !Array.isArray(node)) {
return;
}

Expand All @@ -258,11 +259,6 @@ export async function resolveDocument(opts: {

seenNodes.add(nodeId);

const [_, anchor] = Object.entries(node).find(([key]) => key === '$anchor') || [];
if (anchor) {
anchorRefsMap.set(`#${anchor}`, node);
}

if (Array.isArray(node)) {
const itemsType = type.items;
// we continue resolving unknown types, but stop early on known scalars
Expand Down Expand Up @@ -291,6 +287,11 @@ export async function resolveDocument(opts: {
return;
}

const [_, anchor] = Object.entries(node).find(([key]) => key === '$anchor') || [];
if (anchor) {
anchorRefsMap.set(`#${anchor}`, node);
}

for (const propName of Object.keys(node)) {
let propValue = node[propName];
let propType = getOwn(type.properties, propName);
Expand Down Expand Up @@ -342,7 +343,7 @@ export async function resolveDocument(opts: {
if (isExternalValue(node)) {
const promise = followRef(
rootNodeDocument,
{ $ref: node.externalValue },
{ $ref: node.externalValue as string },
{
prev: null,
node,
Expand All @@ -352,7 +353,7 @@ export async function resolveDocument(opts: {
resolveRefsInParallel(
resolvedRef.node,
resolvedRef.document,
resolvedRef.nodePointer!,
resolvedRef.nodePointer,
type
);
}
Expand Down Expand Up @@ -420,33 +421,42 @@ export async function resolveDocument(opts: {
nodePointer: '#/',
};

let target = targetDoc.parsed as any;
let target = targetDoc.parsed;

const segments = pointer;
for (const segment of segments) {
if (typeof target !== 'object') {
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replaced the guard with explicit Array/Object detection.

target = undefined;
break;
} else if (target[segment] !== undefined) {
if (isPlainObject(target) && target[segment] !== undefined) {
target = target[segment];
resolvedRef.nodePointer = joinPointer(
resolvedRef.nodePointer!,
escapePointerFragment(segment)
);
} else if (Array.isArray(target) && target[+segment] !== undefined) {
target = target[+segment];
resolvedRef.nodePointer = joinPointer(
resolvedRef.nodePointer!,
escapePointerFragment(segment)
);
} else if (isRef(target)) {
resolvedRef = await followRef(targetDoc, target, pushRef(refStack, target));
targetDoc = resolvedRef.document || targetDoc;

if (typeof resolvedRef.node !== 'object') {
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved to the else block below.

if (isPlainObject(resolvedRef.node)) {
target = resolvedRef.node[segment];
resolvedRef.nodePointer = joinPointer(
resolvedRef.nodePointer!,
escapePointerFragment(segment)
);
} else if (Array.isArray(resolvedRef.node)) {
target = resolvedRef.node[+segment];
resolvedRef.nodePointer = joinPointer(
resolvedRef.nodePointer!,
escapePointerFragment(segment)
);
} else {
target = undefined;
break;
}

target = resolvedRef.node[segment];
resolvedRef.nodePointer = joinPointer(
resolvedRef.nodePointer!,
escapePointerFragment(segment)
);
} else {
target = undefined;
break;
Expand Down
6 changes: 4 additions & 2 deletions packages/core/src/rules/ajv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ function getAjv(resolve: ResolveFn, dialect: AjvDialect): AnyAjv {

ajvInstances[dialect] = dialect === '2020' ? new Ajv2020(options) : new AjvDraft4(options);

// oxlint-disable-next-line typescript/no-explicit-any
addFormats(ajvInstances[dialect] as any);
}
return ajvInstances[dialect];
Expand Down Expand Up @@ -126,9 +127,10 @@ export function validateJsonSchema(

function beatifyErrorMessage(error: ErrorObject) {
let message = error.message;
const suggest = error.keyword === 'enum' ? error.params.allowedValues : undefined;
const suggest: string[] | undefined =
error.keyword === 'enum' ? error.params.allowedValues : undefined;
if (suggest) {
message += ` ${suggest.map((e: any) => `"${e}"`).join(', ')}`;
message += ` ${suggest.map((e) => `"${e}"`).join(', ')}`;
}

if (error.keyword === 'type') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { UserContext } from '../../walk.js';

export const NoChannelTrailingSlash: Async2Rule = () => {
return {
Channel(_channel: any, { report, key, location }: UserContext) {
Channel(_channel: unknown, { report, key, location }: UserContext) {
if ((key as string).endsWith('/') && key !== '/') {
report({
message: `\`${key}\` should not have a trailing slash.`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const MAX_KEY_LENGTH = 150;

export const EntityKeyValid: CatalogEntityRule = () => {
return {
any(node: any, { report, location }: UserContext) {
any(node: unknown, { report, location }: UserContext) {
if (isPlainObject(node) && 'key' in node) {
const key = node.key;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import type { Oas3Parameter } from '../../typings/openapi.js';
import { isDefined } from '../../utils/is-defined.js';
import { isPlainObject } from '../../utils/is-plain-object.js';
import type { Oas2Rule, Oas3Rule } from '../../visitors.js';
import type { UserContext } from '../../walk.js';
import { validateExample } from '../utils.js';

export const NoInvalidParameterExamples: any = (opts: any) => {
export const NoInvalidParameterExamples: Oas3Rule | Oas2Rule = (opts) => {
return {
Parameter: {
leave(parameter: Oas3Parameter, ctx: UserContext) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { Oas2Rule, Oas3Rule } from '../../visitors.js';
import type { UserContext } from '../../walk.js';
import { validateExample } from '../utils.js';

export const NoInvalidSchemaExamples: Oas3Rule | Oas2Rule = (opts: any) => {
export const NoInvalidSchemaExamples: Oas3Rule | Oas2Rule = (opts) => {
return {
Schema: {
leave(schema: Oas3_1Schema | Oas3Schema, ctx: UserContext) {
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/rules/common/no-path-trailing-slash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { UserContext } from '../../walk.js';

export const NoPathTrailingSlash: Oas3Rule | Oas2Rule = () => {
return {
PathItem(_path: any, { report, key, rawLocation }: UserContext) {
PathItem(_path: unknown, { report, key, rawLocation }: UserContext) {
if ((key as string).endsWith('/') && key !== '/') {
report({
message: `\`${key}\` should not have a trailing slash.`,
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/rules/common/path-http-verbs-order.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import type { UserContext } from '../../walk.js';

const defaultOrder = ['get', 'head', 'post', 'put', 'patch', 'delete', 'options', 'query', 'trace'];

export const PathHttpVerbsOrder: Oas3Rule | Oas2Rule = (opts: any) => {
export const PathHttpVerbsOrder: Oas3Rule | Oas2Rule = (opts) => {
const order: string[] = (opts && opts.order) || defaultOrder;
if (!Array.isArray(order)) {
throw new Error('path-http-verbs-order `order` option must be an array');
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/rules/common/path-segment-plural.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export const PathSegmentPlural: Oas3Rule | Oas2Rule = (opts) => {
const { ignoreLastPathSegment, exceptions } = opts;
return {
PathItem: {
leave(_path: any, { report, key, location }: UserContext) {
leave(_path: unknown, { report, key, location }: UserContext) {
const pathKey = key.toString();
if (pathKey.startsWith('/')) {
const pathSegments = pathKey.split('/');
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/rules/oas2/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ import { ResponseMimeType } from './response-mime-type.js';
export const rules: Oas2RuleSet<'built-in'> = {
struct: Struct as Oas2Rule,
'no-invalid-schema-examples': NoInvalidSchemaExamples as Oas2Rule,
'no-invalid-parameter-examples': NoInvalidParameterExamples,
'no-invalid-parameter-examples': NoInvalidParameterExamples as Oas2Rule,
Comment thread
tatomyr marked this conversation as resolved.
'info-contact': InfoContact as Oas2Rule,
'info-license': InfoLicense as Oas2Rule,
'info-license-strict': InfoLicenseStrict as Oas2Rule,
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/rules/oas3/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ export const rules: Oas3RuleSet<'built-in'> = {
'response-mime-type': ResponseMimeType,
'path-segment-plural': PathSegmentPlural as Oas3Rule,
'no-invalid-schema-examples': NoInvalidSchemaExamples as Oas3Rule,
'no-invalid-parameter-examples': NoInvalidParameterExamples,
'no-invalid-parameter-examples': NoInvalidParameterExamples as Oas3Rule,
'response-contains-header': ResponseContainsHeader as Oas3Rule,
'response-contains-property': ResponseContainsProperty,
'scalar-property-missing-example': ScalarPropertyMissingExample as Oas3Rule,
Expand Down
Loading
Loading