Skip to content

Commit 5a4aca8

Browse files
committed
chore: add eslint rule to harmonize rules
1 parent 200dd26 commit 5a4aca8

8 files changed

Lines changed: 7 additions & 70 deletions

File tree

eslint.config.mjs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,13 @@ export default tseslint.config(
7676
Existing rule you had
7777
=========================== */
7878

79-
'@typescript-eslint/no-explicit-any': 'off'
79+
'@typescript-eslint/no-explicit-any': 'off',
80+
81+
'padding-line-between-statements': [
82+
'error',
83+
{ blankLine: 'never', prev: 'if', next: '*' },
84+
{ blankLine: 'never', prev: '*', next: 'if' }
85+
]
8086
}
8187
}
8288
)

example/middleware.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ export function rateLimitMiddleware(
2727
const ip = req.ip
2828
const now = Date.now()
2929
const record = requestCounts.get(ip!)
30-
3130
if (!record || now > record.resetTime) {
3231
requestCounts.set(ip!, {
3332
count: 1,
@@ -36,15 +35,13 @@ export function rateLimitMiddleware(
3635
next()
3736
return
3837
}
39-
4038
if (record.count >= maxRequests) {
4139
res.status(429).json({
4240
error: 'Too Many Requests',
4341
retryAfter: Math.ceil((record.resetTime - now) / 1_000)
4442
})
4543
return
4644
}
47-
4845
record.count++
4946
next()
5047
}

src/controller.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ export function addController(
104104
)
105105
continue // skip
106106
}
107-
108107
let hasSuccessResponse = false
109108
const returnType = method.getReturnType()
110109

@@ -168,7 +167,6 @@ export function addController(
168167
}
169168
}
170169
}
171-
172170
// Add default success response
173171
if (!hasSuccessResponse) {
174172
if (
@@ -190,7 +188,6 @@ export function addController(
190188
}
191189
}
192190
}
193-
194191
// We use another array for codegen parameters instead of operation.parameters
195192
// because we want to have Request() and Body() in the codegen one
196193
// to send it to the method at runtime
@@ -328,7 +325,6 @@ export function addController(
328325

329326
// Security
330327
operation.security = [...controllerSecurities, ...getSecurities(method)]
331-
332328
// OperationId
333329
if (method.getDecorator('OperationId')) {
334330
operation.operationId = extractDecoratorValues(
@@ -338,12 +334,10 @@ export function addController(
338334
const name = method.getName()
339335
operation.operationId = name.charAt(0).toUpperCase() + name.slice(1)
340336
}
341-
342337
// Deprecated
343338
if (method.getDecorator('Deprecated')) {
344339
operation.deprecated = true
345340
}
346-
347341
// Add to spec + codegen
348342
const isHidden =
349343
typeof (

src/index.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,6 @@ export async function generate(config: OpenAPIConfiguration) {
148148
if (typeof config.openapi.securitySchemes !== 'undefined') {
149149
spec.components!.securitySchemes = config.openapi.securitySchemes
150150
}
151-
152151
// Codegen object
153152
const codegenControllers: CodeGenControllers = {}
154153
const controllersPathByName: Record<string, string> = {}
@@ -215,7 +214,6 @@ export async function generate(config: OpenAPIConfiguration) {
215214
spec.components!.schemas![name] = resolved
216215
}
217216
}
218-
219217
// Export all responses
220218
if (
221219
typeof config.openapi.outputErrorsToDescription !== 'undefined' &&
@@ -327,7 +325,6 @@ export async function generate(config: OpenAPIConfiguration) {
327325
rows.map(row => `| ${row.join(' | ')} |`).join('\n')
328326
spec.info.description = `# Errors\n${markdown}`
329327
}
330-
331328
// Write OpenAPI file(s)
332329
const jsonContent = JSON.stringify(spec, null, '\t')
333330

@@ -339,7 +336,6 @@ export async function generate(config: OpenAPIConfiguration) {
339336
// Process each file path
340337
for (const filePath of filePaths) {
341338
const resolvedPath = path.resolve(root, filePath)
342-
343339
// Determine format based on file extension
344340
if (
345341
filePath.toLowerCase().endsWith('.yaml') ||

src/resolve.ts

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,6 @@ export function resolve(
304304
// For other and anonymous types, don't use ref
305305
return resolveObjectType(type, spec)
306306
}
307-
308307
// Add to spec components if not already resolved
309308
// tslint:disable-next-line: strict-type-predicates
310309
if (typeof spec.components!.schemas![typeName] === 'undefined') {
@@ -451,11 +450,9 @@ function resolveProperties(
451450
// OpenAPI don't want the required[] prop if it's empty
452451
delete result.required
453452
}
454-
455453
// Check for index signatures regardless of whether explicit properties exist
456454
const stringIndexType = type.getStringIndexType()
457455
const numberIndexType = type.getNumberIndexType()
458-
459456
// Handle mapped types and objects with index signatures (ex: { [key: string]: any } or Record<string, any>)
460457
if (
461458
(typeof stringIndexType !== 'undefined' &&
@@ -474,7 +471,6 @@ function resolveProperties(
474471
// Check if the type represents a Record-like structure that should have additionalProperties
475472
const typeSymbol = type.getSymbol()
476473
const typeText = type.getText()
477-
478474
// Handle cases where the type might be a transformed Record type
479475
if (typeSymbol?.getName() === '__type' || typeText.includes('Record<')) {
480476
// For anonymous types that might be transformed Record types,
@@ -485,7 +481,6 @@ function resolveProperties(
485481
if (apparentType && apparentType !== type) {
486482
const apparentStringIndexType = apparentType.getStringIndexType()
487483
const apparentNumberIndexType = apparentType.getNumberIndexType()
488-
489484
if (
490485
(typeof apparentStringIndexType !== 'undefined' &&
491486
apparentStringIndexType.getText() !== 'never') ||
@@ -500,7 +495,6 @@ function resolveProperties(
500495
}
501496
}
502497
}
503-
504498
return result
505499
}
506500

@@ -530,7 +524,6 @@ function resolveMappedObjectType(
530524
const omittedKeys = typeArguments[1].isUnion()
531525
? typeArguments[1].getUnionTypes().map(t => String(t.getLiteralValue()))
532526
: [String(typeArguments[1].getLiteralValue())]
533-
534527
if (helperName === 'Omit' && omittedKeys.includes('toJSON')) {
535528
// If we're omitting toJSON, don't follow it to avoid infinite loops
536529
shouldSkipToJSON = true
@@ -539,22 +532,19 @@ function resolveMappedObjectType(
539532
shouldSkipToJSON = true
540533
}
541534
}
542-
543535
// Check if the subject type has a toJSON method
544536
const toJSONProperty = subjectType.getProperty('toJSON')
545537
if (toJSONProperty && !shouldSkipToJSON) {
546538
const node = getDeclarationForProperty(subjectType, toJSONProperty) as
547539
| MethodDeclaration
548540
| MethodSignature
549541
const toJSONReturnType = resolve(node.getReturnType(), spec)
550-
551542
// Apply mapped type transformation to the toJSON return type
552543
if ('$ref' in toJSONReturnType) {
553544
// For reference types, we need to create a new schema with the transformation applied
554545
// This is more complex, so for now we'll fall back to normal resolution
555546
return resolveObjectType(type, spec)
556547
}
557-
558548
if (toJSONReturnType.type === 'object' && toJSONReturnType.properties) {
559549
const transformedSchema = { ...toJSONReturnType }
560550

@@ -571,7 +561,6 @@ function resolveMappedObjectType(
571561
return transformedSchema
572562
}
573563
}
574-
575564
// Fall back to normal object resolution if no toJSON or transformation failed
576565
return resolveObjectType(type, spec)
577566
}
@@ -582,7 +571,6 @@ function resolveMappedObjectType(
582571
function hasInterfaceInheritance(type: Type): boolean {
583572
const symbol = type.getSymbol()
584573
if (!symbol) return false
585-
586574
const declarations = symbol.getDeclarations()
587575

588576
return declarations.some(
@@ -599,13 +587,11 @@ function getBaseInterfaces(
599587
): OpenAPIV3.ReferenceObject[] {
600588
const symbol = type.getSymbol()
601589
if (!symbol) return []
602-
603590
const baseRefs: OpenAPIV3.ReferenceObject[] = []
604591
const declarations = symbol.getDeclarations()
605592

606593
for (const decl of declarations) {
607594
if (!Node.isInterfaceDeclaration(decl)) continue
608-
609595
const extendsExpressions = decl.getExtends()
610596
for (const extendsExpr of extendsExpressions) {
611597
const baseType = extendsExpr.getType()
@@ -631,17 +617,14 @@ function getOwnInterfaceProperties(
631617
// Fallback to normal property resolution
632618
return resolveProperties(type, spec)
633619
}
634-
635620
const declarations = symbol.getDeclarations()
636621
const interfaceDecl = declarations.find(decl =>
637622
Node.isInterfaceDeclaration(decl)
638623
)
639-
640624
if (!interfaceDecl) {
641625
// Fallback to normal property resolution
642626
return resolveProperties(type, spec)
643627
}
644-
645628
const result: ResolvePropertiesReturnType = {
646629
properties: {},
647630
required: []
@@ -675,7 +658,6 @@ function getOwnInterfaceProperties(
675658
// Handle JSDoc tags
676659
const jsDocTags = propSig.getSymbol()?.compilerSymbol.getJsDocTags() ?? []
677660
appendJsDocTags(jsDocTags, resolvedType)
678-
679661
// Add to properties
680662
if (
681663
!('type' in resolvedType && (resolvedType.type as any) === 'undefined')
@@ -686,14 +668,11 @@ function getOwnInterfaceProperties(
686668
}
687669
}
688670
}
689-
690671
// Handle method signatures (but ignore them like in resolveProperties)
691672
// Methods are already filtered out by only looking at property signatures
692-
693673
if (result.required!.length === 0) {
694674
delete result.required
695675
}
696-
697676
return result
698677
}
699678

@@ -719,31 +698,26 @@ function resolveObjectType(
719698
| MethodSignature
720699
return resolve(node.getReturnType(), spec)
721700
}
722-
723701
// Check for interface inheritance
724702
if (!hasInterfaceInheritance(type)) {
725703
return {
726704
type: 'object',
727705
...resolveProperties(type, spec)
728706
}
729707
}
730-
731708
const baseRefs = getBaseInterfaces(type, spec)
732-
733709
// If there are no base interfaces, fall back to normal resolution
734710
if (baseRefs.length === 0) {
735711
return {
736712
type: 'object',
737713
...resolveProperties(type, spec)
738714
}
739715
}
740-
741716
// Shallow copy to avoid mutating the original baseRefs array
742717
const allOfElements = Array.from<
743718
OpenAPIV3.ReferenceObject | OpenAPIV3.SchemaObject
744719
>(baseRefs)
745720
const ownProps = getOwnInterfaceProperties(type, spec)
746-
747721
// Add own properties if any exist
748722
if (
749723
Object.keys(ownProps.properties).length > 0 ||
@@ -754,7 +728,6 @@ function resolveObjectType(
754728
...ownProps
755729
})
756730
}
757-
758731
return {
759732
allOf: allOfElements
760733
}
@@ -823,7 +796,6 @@ export function appendJsDocTags(
823796
if (!supportedTags.includes(tag.name) || !tag.text) {
824797
continue
825798
}
826-
827799
const textValue = tag.text.map(t => t.text).join('\n')
828800
const value = numericTags.includes(tag.name)
829801
? parseFloat(textValue)
@@ -845,7 +817,6 @@ export function appendInitializer(
845817
// Default value
846818
const initializer = node.getInitializer()
847819
const initializerType = initializer?.getType()
848-
849820
if (initializerType?.isLiteral()) {
850821
const initializerLiteralType = initializerType.compilerType as
851822
| ts.StringLiteralType

0 commit comments

Comments
 (0)