Skip to content

Commit 6305a28

Browse files
authored
feature: prepare to resolve json schema (#77)
1 parent 0ed4e60 commit 6305a28

File tree

6 files changed

+113
-2
lines changed

6 files changed

+113
-2
lines changed

packages/json-worker/src/parts/JsonCompletion/JsonCompletion.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export const jsonCompletion = async (
1717
return []
1818
}
1919
const { node, schema } = parsed
20+
2021
if (node.type === TokenType.String) {
2122
const options = schema?.properties?.type?.enum || []
2223
return options.map(EnumToCompletionOption.enumToCompletionOption)
Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,45 @@
11
import { AstNode } from '../AstNode/AstNode.ts'
22
import type { CompletionItem } from '../CompletionItem/CompletionItem.ts'
33
import * as PropertyKeyToCompletionOption from '../PropertyKeyToCompletionOption/PropertyKeyToCompletionOption.ts'
4+
import * as ResolveSchemaRef from '../ResolveSchemaRef/ResolveSchemaRef.ts'
5+
import type { JsonSchema } from '../JsonSchema/JsonSchema.ts'
6+
7+
const getSchemaProperties = (schema: JsonSchema): JsonSchema['properties'] => {
8+
if (schema.properties) {
9+
return schema.properties
10+
}
11+
12+
if (schema.$ref) {
13+
const resolved = ResolveSchemaRef.resolveSchemaRef(schema, schema.$ref)
14+
return resolved.properties || {}
15+
}
16+
17+
if (schema.allOf) {
18+
const properties: { [key: string]: JsonSchema } = {}
19+
for (const subSchema of schema.allOf) {
20+
const subProperties = getSchemaProperties(subSchema)
21+
Object.assign(properties, subProperties)
22+
}
23+
return properties
24+
}
25+
26+
if (schema.anyOf) {
27+
const properties: { [key: string]: JsonSchema } = {}
28+
for (const subSchema of schema.anyOf) {
29+
const subProperties = getSchemaProperties(subSchema)
30+
Object.assign(properties, subProperties)
31+
}
32+
return properties
33+
}
34+
35+
return {}
36+
}
437

538
export const jsonCompletionProperty = (
6-
schema: any,
39+
schema: JsonSchema,
740
node: AstNode,
841
): readonly CompletionItem[] => {
9-
const keys = Object.keys(schema?.properties || {})
42+
const properties = getSchemaProperties(schema)
43+
const keys = Object.keys(properties || {})
1044
return keys.map(PropertyKeyToCompletionOption.propertyKeyToCompletionOption)
1145
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
export interface JsonSchema {
2+
readonly $ref?: string
3+
readonly properties?: {
4+
readonly [key: string]: JsonSchema
5+
}
6+
readonly definitions?: {
7+
readonly [key: string]: JsonSchema
8+
}
9+
readonly allOf?: readonly JsonSchema[]
10+
readonly anyOf?: readonly JsonSchema[]
11+
readonly description?: string
12+
readonly type?: string
13+
readonly enum?: readonly string[]
14+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export const resolveSchema = (schema: any): any => {
2+
return schema
3+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import type { JsonSchema } from '../JsonSchema/JsonSchema.ts'
2+
3+
const definitionPrefix = '#/definitions/'
4+
5+
export const resolveSchemaRef = (
6+
schema: JsonSchema,
7+
ref: string,
8+
): JsonSchema => {
9+
if (!ref.startsWith(definitionPrefix)) {
10+
return {}
11+
}
12+
const path = ref.slice(definitionPrefix.length)
13+
const resolved = schema.definitions?.[path]
14+
if (!resolved) {
15+
return {}
16+
}
17+
return resolved
18+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { jest, test, expect } from '@jest/globals'
2+
import * as JsonCompletionProperty from '../src/parts/JsonCompletionProperty/JsonCompletionProperty.ts'
3+
4+
test.skip('handles schema references', () => {
5+
const schema = {
6+
allOf: [
7+
{
8+
$ref: '#/definitions/compilerOptionsDefinition',
9+
},
10+
],
11+
definitions: {
12+
compilerOptionsDefinition: {
13+
properties: {
14+
compilerOptions: {
15+
type: 'object',
16+
properties: {
17+
target: {
18+
type: 'string',
19+
},
20+
},
21+
},
22+
},
23+
},
24+
},
25+
}
26+
27+
const node = {
28+
type: 0,
29+
offset: 0,
30+
length: 0,
31+
childCount: 0,
32+
}
33+
34+
const result = JsonCompletionProperty.jsonCompletionProperty(schema, node)
35+
expect(result).toEqual([
36+
{
37+
kind: 10,
38+
label: 'compilerOptions',
39+
},
40+
])
41+
})

0 commit comments

Comments
 (0)