Skip to content

Commit c34631b

Browse files
authored
fix: fix JSON schema with root ID not parsed correctly (#13)
1 parent c288170 commit c34631b

File tree

4 files changed

+104
-4
lines changed

4 files changed

+104
-4
lines changed

src/core.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -212,18 +212,28 @@ export async function compileRule(
212212
? { type: 'array', items: meta.schema, definitions: meta.schema?.[0]?.definitions }
213213
: meta.schema
214214

215+
let overriddenRootSchemaId: string | undefined
216+
let isRootSchema = true
217+
215218
try {
216219
const compiled = await compileSchema(schema, id, {
217220
unreachableDefinitions: false,
218221
strictIndexSignatures: true,
219222
customName(schema, keyName) {
223+
const canOverrideRootSchemaId = isRootSchema
224+
isRootSchema = false
225+
220226
const resolved = schema.title || schema.$id || keyName
221-
if (resolved === id) {
227+
if (resolved === id)
222228
return id
223-
}
224229
if (!resolved)
225230
return undefined!
226-
return `_${normalizeIdentifier(`${id}_${resolved}`)}`
231+
232+
const normalizedName = `_${normalizeIdentifier(`${id}_${resolved}`)}`
233+
if (canOverrideRootSchemaId)
234+
overriddenRootSchemaId = normalizedName
235+
236+
return normalizedName
227237
},
228238
...compileOptions,
229239
})
@@ -249,7 +259,7 @@ export async function compileRule(
249259
return {
250260
name: ruleName,
251261
jsdoc,
252-
typeName: id,
262+
typeName: overriddenRootSchemaId ?? id,
253263
typeDeclarations: lines,
254264
}
255265
}

test/index.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { vue } from '@antfu/eslint-config'
22
import { expect, it } from 'vitest'
33
import { flatConfigsToRulesDTS, pluginsToRulesDTS } from '../src/core'
44
import { invalidJsonSchemaPlugin } from './input/invalid-json-schema-plugin'
5+
import { pluginWithSchemaIds } from './input/plugin-with-schema-ids'
56

67
it('pluginsToRuleOptions', async () => {
78
await expect(await pluginsToRulesDTS({
@@ -35,6 +36,13 @@ it('invalid JSON schema plugin', async () => {
3536
.toMatchFileSnapshot('./output/invalid-json-schema-plugin.d.ts')
3637
})
3738

39+
it('json schema with ids', async () => {
40+
await expect(await pluginsToRulesDTS({
41+
plugin: pluginWithSchemaIds,
42+
}))
43+
.toMatchFileSnapshot('./output/plugin-with-schema-ids.d.ts')
44+
})
45+
3846
it('flatConfigsToRuleOptions', async () => {
3947
await expect(await flatConfigsToRulesDTS(await vue() as any))
4048
.toMatchFileSnapshot('./output/flat-config-vue.d.ts')
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import type { ESLint, Rule } from 'eslint'
2+
3+
export const pluginWithSchemaIds: ESLint.Plugin = {
4+
rules: {
5+
'schema-with-id-at-root': {
6+
create: () => null as unknown as Rule.RuleListener,
7+
meta: {
8+
schema: {
9+
id: 'schemaId',
10+
type: 'object',
11+
additionalProperties: false,
12+
properties: {
13+
a: {
14+
id: 'aId',
15+
type: 'string',
16+
},
17+
b: {
18+
id: 'bId',
19+
additionalProperties: false,
20+
type: 'object',
21+
properties: {
22+
b1: {
23+
type: 'string',
24+
},
25+
},
26+
},
27+
c: {
28+
additionalProperties: false,
29+
type: 'object',
30+
properties: {
31+
c1: {
32+
type: 'string',
33+
id: 'c1Id',
34+
},
35+
},
36+
},
37+
d: {
38+
additionalProperties: false,
39+
type: 'object',
40+
properties: {
41+
da: {
42+
type: 'string',
43+
},
44+
},
45+
},
46+
},
47+
},
48+
},
49+
},
50+
},
51+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/* eslint-disable */
2+
/* prettier-ignore */
3+
import type { Linter } from 'eslint'
4+
5+
declare module 'eslint' {
6+
namespace Linter {
7+
interface RulesRecord extends RuleOptions {}
8+
}
9+
}
10+
11+
export interface RuleOptions {
12+
'plugin/schema-with-id-at-root'?: Linter.RuleEntry<_PluginSchemaWithIdAtRootSchemaId>
13+
}
14+
15+
/* ======= Declarations ======= */
16+
// ----- plugin/schema-with-id-at-root -----
17+
type _PluginSchemaWithIdAtRootAId = string
18+
type _PluginSchemaWithIdAtRootC1Id = string
19+
interface _PluginSchemaWithIdAtRootSchemaId {
20+
a?: _PluginSchemaWithIdAtRootAId
21+
b?: _PluginSchemaWithIdAtRootBId
22+
c?: {
23+
c1?: _PluginSchemaWithIdAtRootC1Id
24+
}
25+
d?: {
26+
da?: string
27+
}
28+
}
29+
interface _PluginSchemaWithIdAtRootBId {
30+
b1?: string
31+
}

0 commit comments

Comments
 (0)