polen 0.10.0-next.21 → 0.10.0-next.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/api/config/configurator.d.ts +62 -11
- package/build/api/config/configurator.d.ts.map +1 -1
- package/build/api/config/configurator.js +9 -0
- package/build/api/config/configurator.js.map +1 -1
- package/build/api/vite/plugins/core.d.ts.map +1 -1
- package/build/api/vite/plugins/core.js +1 -0
- package/build/api/vite/plugins/core.js.map +1 -1
- package/build/project-data.d.ts +1 -0
- package/build/project-data.d.ts.map +1 -1
- package/build/sandbox.js +40 -17
- package/build/sandbox.js.map +1 -1
- package/build/template/components/CodeBlock.d.ts.map +1 -1
- package/build/template/components/CodeBlock.js +3 -5
- package/build/template/components/CodeBlock.js.map +1 -1
- package/build/template/components/Field.js +1 -1
- package/build/template/components/Field.js.map +1 -1
- package/build/template/components/GraphQLInteractive/GraphQLInteractive.d.ts +31 -0
- package/build/template/components/GraphQLInteractive/GraphQLInteractive.d.ts.map +1 -0
- package/build/template/components/GraphQLInteractive/GraphQLInteractive.js +275 -0
- package/build/template/components/GraphQLInteractive/GraphQLInteractive.js.map +1 -0
- package/build/template/components/GraphQLInteractive/components/GraphQLErrorBoundary.d.ts +39 -0
- package/build/template/components/GraphQLInteractive/components/GraphQLErrorBoundary.d.ts.map +1 -0
- package/build/template/components/GraphQLInteractive/components/GraphQLErrorBoundary.js +51 -0
- package/build/template/components/GraphQLInteractive/components/GraphQLErrorBoundary.js.map +1 -0
- package/build/template/components/GraphQLInteractive/components/GraphQLTokenPopover.d.ts +33 -0
- package/build/template/components/GraphQLInteractive/components/GraphQLTokenPopover.d.ts.map +1 -0
- package/build/template/components/GraphQLInteractive/components/GraphQLTokenPopover.js +242 -0
- package/build/template/components/GraphQLInteractive/components/GraphQLTokenPopover.js.map +1 -0
- package/build/template/components/GraphQLInteractive/hooks/use-popover-state.d.ts +45 -0
- package/build/template/components/GraphQLInteractive/hooks/use-popover-state.d.ts.map +1 -0
- package/build/template/components/GraphQLInteractive/hooks/use-popover-state.js +176 -0
- package/build/template/components/GraphQLInteractive/hooks/use-popover-state.js.map +1 -0
- package/build/template/components/GraphQLInteractive/index.d.ts +2 -0
- package/build/template/components/GraphQLInteractive/index.d.ts.map +1 -0
- package/build/template/components/GraphQLInteractive/index.js +2 -0
- package/build/template/components/GraphQLInteractive/index.js.map +1 -0
- package/build/template/components/GraphQLInteractive/lib/graphql-node-types.d.ts +52 -0
- package/build/template/components/GraphQLInteractive/lib/graphql-node-types.d.ts.map +1 -0
- package/build/template/components/GraphQLInteractive/lib/graphql-node-types.js +34 -0
- package/build/template/components/GraphQLInteractive/lib/graphql-node-types.js.map +1 -0
- package/build/template/components/GraphQLInteractive/lib/parser.d.ts +71 -0
- package/build/template/components/GraphQLInteractive/lib/parser.d.ts.map +1 -0
- package/build/template/components/GraphQLInteractive/lib/parser.js +836 -0
- package/build/template/components/GraphQLInteractive/lib/parser.js.map +1 -0
- package/build/template/components/GraphQLInteractive/lib/semantic-nodes.d.ts +98 -0
- package/build/template/components/GraphQLInteractive/lib/semantic-nodes.d.ts.map +1 -0
- package/build/template/components/GraphQLInteractive/lib/semantic-nodes.js +31 -0
- package/build/template/components/GraphQLInteractive/lib/semantic-nodes.js.map +1 -0
- package/build/template/components/content/$$.d.ts +0 -1
- package/build/template/components/content/$$.d.ts.map +1 -1
- package/build/template/components/content/$$.js +0 -1
- package/build/template/components/content/$$.js.map +1 -1
- package/package.json +5 -21
- package/src/api/config/configurator.ts +72 -11
- package/src/api/vite/plugins/core.ts +1 -0
- package/src/lib/kit-temp.test.ts +9 -9
- package/src/project-data.ts +1 -0
- package/src/sandbox.ts +40 -17
- package/src/template/components/CodeBlock.tsx +6 -9
- package/src/template/components/Field.tsx +1 -1
- package/src/template/components/GraphQLInteractive/GraphQLInteractive.tsx +464 -0
- package/src/template/components/GraphQLInteractive/components/GraphQLErrorBoundary.tsx +96 -0
- package/src/template/components/GraphQLInteractive/components/GraphQLTokenPopover.tsx +492 -0
- package/src/template/components/GraphQLInteractive/hooks/use-popover-state.ts +244 -0
- package/src/template/components/GraphQLInteractive/index.ts +1 -0
- package/src/template/components/GraphQLInteractive/lib/graphql-node-types.ts +217 -0
- package/src/template/components/GraphQLInteractive/lib/parser.ts +1075 -0
- package/src/template/components/GraphQLInteractive/lib/semantic-nodes.ts +154 -0
- package/src/template/components/GraphQLInteractive/tests/parser-comment.test.ts +33 -0
- package/src/template/components/GraphQLInteractive/tests/parser-error-hint.test.ts +102 -0
- package/src/template/components/GraphQLInteractive/tests/parser.test.ts +131 -0
- package/src/template/components/content/$$.ts +0 -1
- package/build/template/components/content/GraphQLDocumentWithSchema.d.ts +0 -8
- package/build/template/components/content/GraphQLDocumentWithSchema.d.ts.map +0 -1
- package/build/template/components/content/GraphQLDocumentWithSchema.js +0 -13
- package/build/template/components/content/GraphQLDocumentWithSchema.js.map +0 -1
- package/build/template/components/content/GraphQLDocumentWrapper.d.ts +0 -7
- package/build/template/components/content/GraphQLDocumentWrapper.d.ts.map +0 -1
- package/build/template/components/content/GraphQLDocumentWrapper.js +0 -48
- package/build/template/components/content/GraphQLDocumentWrapper.js.map +0 -1
- package/src/template/components/content/GraphQLDocumentWithSchema.tsx +0 -13
- package/src/template/components/content/GraphQLDocumentWrapper.tsx +0 -72
@@ -0,0 +1,154 @@
|
|
1
|
+
/**
|
2
|
+
* Semantic Node Types for GraphQL Interactive
|
3
|
+
*
|
4
|
+
* This module defines the semantic node types used to represent
|
5
|
+
* GraphQL schema information alongside tree-sitter syntax nodes.
|
6
|
+
*/
|
7
|
+
|
8
|
+
import type {
|
9
|
+
GraphQLArgument,
|
10
|
+
GraphQLEnumType,
|
11
|
+
GraphQLField,
|
12
|
+
GraphQLInputField,
|
13
|
+
GraphQLInputObjectType,
|
14
|
+
GraphQLInputType,
|
15
|
+
GraphQLInterfaceType,
|
16
|
+
GraphQLNamedType,
|
17
|
+
GraphQLObjectType,
|
18
|
+
GraphQLScalarType,
|
19
|
+
GraphQLUnionType,
|
20
|
+
} from 'graphql'
|
21
|
+
|
22
|
+
/**
|
23
|
+
* Wrapper for output fields that need parent type context
|
24
|
+
*/
|
25
|
+
export interface OutputFieldNode {
|
26
|
+
kind: 'OutputField'
|
27
|
+
parentType: GraphQLObjectType | GraphQLInterfaceType
|
28
|
+
fieldDef: GraphQLField<any, any>
|
29
|
+
}
|
30
|
+
|
31
|
+
/**
|
32
|
+
* Wrapper for input fields that need parent type context
|
33
|
+
*/
|
34
|
+
export interface InputFieldNode {
|
35
|
+
kind: 'InputField'
|
36
|
+
parentType: GraphQLInputObjectType
|
37
|
+
fieldDef: GraphQLInputField
|
38
|
+
}
|
39
|
+
|
40
|
+
/**
|
41
|
+
* Wrapper for arguments that need parent field context
|
42
|
+
*/
|
43
|
+
export interface ArgumentNode {
|
44
|
+
kind: 'Argument'
|
45
|
+
parentType: GraphQLObjectType | GraphQLInterfaceType
|
46
|
+
parentField: GraphQLField<any, any>
|
47
|
+
argumentDef: GraphQLArgument
|
48
|
+
}
|
49
|
+
|
50
|
+
/**
|
51
|
+
* Wrapper for operation definitions
|
52
|
+
*/
|
53
|
+
export interface OperationNode {
|
54
|
+
kind: 'Operation'
|
55
|
+
type: 'query' | 'mutation' | 'subscription'
|
56
|
+
name?: string
|
57
|
+
}
|
58
|
+
|
59
|
+
/**
|
60
|
+
* Wrapper for variable references
|
61
|
+
*/
|
62
|
+
export interface VariableNode {
|
63
|
+
kind: 'Variable'
|
64
|
+
name: string
|
65
|
+
type?: GraphQLInputType
|
66
|
+
}
|
67
|
+
|
68
|
+
/**
|
69
|
+
* Wrapper for fragment definitions
|
70
|
+
*/
|
71
|
+
export interface FragmentNode {
|
72
|
+
kind: 'Fragment'
|
73
|
+
name: string
|
74
|
+
onType: GraphQLNamedType
|
75
|
+
}
|
76
|
+
|
77
|
+
/**
|
78
|
+
* Wrapper for invalid fields that don't exist in the schema
|
79
|
+
*/
|
80
|
+
export interface InvalidFieldNode {
|
81
|
+
kind: 'InvalidField'
|
82
|
+
fieldName: string
|
83
|
+
parentType: GraphQLObjectType | GraphQLInterfaceType
|
84
|
+
suggestion?: string
|
85
|
+
}
|
86
|
+
|
87
|
+
/**
|
88
|
+
* Union of all semantic node types
|
89
|
+
*
|
90
|
+
* This union represents the different kinds of semantic information that can
|
91
|
+
* be attached to GraphQL tokens during parsing. It includes both GraphQL's
|
92
|
+
* native type classes (for type references) and our custom wrapper interfaces
|
93
|
+
* (for context-dependent elements like fields and arguments).
|
94
|
+
*
|
95
|
+
* @example
|
96
|
+
* ```typescript
|
97
|
+
* // Type reference - uses GraphQL native class
|
98
|
+
* const userType: SemanticNode = schema.getType('User')
|
99
|
+
*
|
100
|
+
* // Field reference - uses custom wrapper with context
|
101
|
+
* const fieldSemantic: SemanticNode = {
|
102
|
+
* kind: 'OutputField',
|
103
|
+
* parentType: userType,
|
104
|
+
* fieldDef: userType.getFields()['name']
|
105
|
+
* }
|
106
|
+
* ```
|
107
|
+
*/
|
108
|
+
export type SemanticNode =
|
109
|
+
// GraphQL's classes (used directly for type references)
|
110
|
+
| GraphQLObjectType
|
111
|
+
| GraphQLScalarType
|
112
|
+
| GraphQLInterfaceType
|
113
|
+
| GraphQLUnionType
|
114
|
+
| GraphQLEnumType
|
115
|
+
| GraphQLInputObjectType
|
116
|
+
// Our wrappers (for context-dependent cases)
|
117
|
+
| OutputFieldNode
|
118
|
+
| InputFieldNode
|
119
|
+
| ArgumentNode
|
120
|
+
| OperationNode
|
121
|
+
| VariableNode
|
122
|
+
| FragmentNode
|
123
|
+
| InvalidFieldNode
|
124
|
+
|
125
|
+
/**
|
126
|
+
* Type guards for our custom wrapper types
|
127
|
+
*/
|
128
|
+
export function isOutputField(node: SemanticNode | undefined): node is OutputFieldNode {
|
129
|
+
return node != null && 'kind' in node && node.kind === 'OutputField'
|
130
|
+
}
|
131
|
+
|
132
|
+
export function isInputField(node: SemanticNode | undefined): node is InputFieldNode {
|
133
|
+
return node != null && 'kind' in node && node.kind === 'InputField'
|
134
|
+
}
|
135
|
+
|
136
|
+
export function isArgument(node: SemanticNode | undefined): node is ArgumentNode {
|
137
|
+
return node != null && 'kind' in node && node.kind === 'Argument'
|
138
|
+
}
|
139
|
+
|
140
|
+
export function isOperation(node: SemanticNode | undefined): node is OperationNode {
|
141
|
+
return node != null && 'kind' in node && node.kind === 'Operation'
|
142
|
+
}
|
143
|
+
|
144
|
+
export function isVariable(node: SemanticNode | undefined): node is VariableNode {
|
145
|
+
return node != null && 'kind' in node && node.kind === 'Variable'
|
146
|
+
}
|
147
|
+
|
148
|
+
export function isFragment(node: SemanticNode | undefined): node is FragmentNode {
|
149
|
+
return node != null && 'kind' in node && node.kind === 'Fragment'
|
150
|
+
}
|
151
|
+
|
152
|
+
export function isInvalidField(node: SemanticNode | undefined): node is InvalidFieldNode {
|
153
|
+
return node != null && 'kind' in node && node.kind === 'InvalidField'
|
154
|
+
}
|
@@ -0,0 +1,33 @@
|
|
1
|
+
import { buildSchema } from 'graphql'
|
2
|
+
import { describe, expect, test } from 'vitest'
|
3
|
+
import { parseGraphQLWithTreeSitter } from '../lib/parser.js'
|
4
|
+
|
5
|
+
describe('parseGraphQLWithTreeSitter - comments', () => {
|
6
|
+
test('should recognize comments and apply correct styling class', async () => {
|
7
|
+
const schema = buildSchema(`
|
8
|
+
type Query {
|
9
|
+
pokemon(id: ID!): Pokemon
|
10
|
+
}
|
11
|
+
|
12
|
+
type Pokemon {
|
13
|
+
id: ID!
|
14
|
+
name: String!
|
15
|
+
}
|
16
|
+
`)
|
17
|
+
|
18
|
+
const code = `query {
|
19
|
+
pokemon(id: "025") {
|
20
|
+
id
|
21
|
+
name # This is a comment
|
22
|
+
}
|
23
|
+
}`
|
24
|
+
|
25
|
+
const tokens = await parseGraphQLWithTreeSitter(code, [], schema)
|
26
|
+
|
27
|
+
// Find the comment token (tree-sitter may parse this as a single comment node)
|
28
|
+
const commentToken = tokens.find(t => t.text.startsWith('#') && t.text.includes('comment'))
|
29
|
+
|
30
|
+
expect(commentToken).toBeDefined()
|
31
|
+
expect(commentToken?.highlighter.getCssClass()).toBe('graphql-comment')
|
32
|
+
})
|
33
|
+
})
|
@@ -0,0 +1,102 @@
|
|
1
|
+
import { buildSchema } from 'graphql'
|
2
|
+
import { describe, expect, test } from 'vitest'
|
3
|
+
import { parseGraphQLWithTreeSitter } from '../lib/parser.js'
|
4
|
+
import { isInvalidField } from '../lib/semantic-nodes.js'
|
5
|
+
|
6
|
+
describe('parseGraphQLWithTreeSitter - error hints', () => {
|
7
|
+
test('should create error hint tokens after invalid fields', async () => {
|
8
|
+
const schema = buildSchema(`
|
9
|
+
type Query {
|
10
|
+
pokemon(id: ID!): Pokemon
|
11
|
+
}
|
12
|
+
|
13
|
+
type Pokemon {
|
14
|
+
id: ID!
|
15
|
+
name: String!
|
16
|
+
}
|
17
|
+
`)
|
18
|
+
|
19
|
+
const code = `query {
|
20
|
+
pokemon(id: "123") {
|
21
|
+
id
|
22
|
+
name
|
23
|
+
invalidField
|
24
|
+
}
|
25
|
+
}`
|
26
|
+
|
27
|
+
const tokens = await parseGraphQLWithTreeSitter(code, [], schema)
|
28
|
+
|
29
|
+
// Find the invalid field token
|
30
|
+
const invalidToken = tokens.find(t =>
|
31
|
+
t.text === 'invalidField'
|
32
|
+
&& isInvalidField(t.semantic)
|
33
|
+
)
|
34
|
+
|
35
|
+
expect(invalidToken).toBeDefined()
|
36
|
+
|
37
|
+
// Find the error hint token that follows the invalid field
|
38
|
+
const invalidTokenIndex = tokens.indexOf(invalidToken!)
|
39
|
+
const errorHintToken = tokens[invalidTokenIndex + 1]
|
40
|
+
|
41
|
+
expect(errorHintToken).toBeDefined()
|
42
|
+
expect(errorHintToken?.text).toBe(' ← No such field')
|
43
|
+
expect(errorHintToken?.highlighter.getCssClass()).toBe('graphql-error-hint')
|
44
|
+
})
|
45
|
+
|
46
|
+
test('should place error hint after arguments for invalid fields with args', async () => {
|
47
|
+
const schema = buildSchema(`
|
48
|
+
type Query {
|
49
|
+
pokemon(id: ID!): Pokemon
|
50
|
+
}
|
51
|
+
|
52
|
+
type Pokemon {
|
53
|
+
id: ID!
|
54
|
+
name: String!
|
55
|
+
}
|
56
|
+
`)
|
57
|
+
|
58
|
+
const code = `query {
|
59
|
+
invalidField(limit: 10, offset: 20) {
|
60
|
+
id
|
61
|
+
}
|
62
|
+
}`
|
63
|
+
|
64
|
+
const tokens = await parseGraphQLWithTreeSitter(code, [], schema)
|
65
|
+
|
66
|
+
// Find the closing parenthesis
|
67
|
+
const closingParenIndex = tokens.findIndex(t => t.text === ')' && t.start > 35)
|
68
|
+
expect(closingParenIndex).toBeGreaterThan(-1)
|
69
|
+
|
70
|
+
// The error hint should come after the closing parenthesis
|
71
|
+
const errorHintToken = tokens[closingParenIndex + 1]
|
72
|
+
expect(errorHintToken?.highlighter.getCssClass()).toBe('graphql-error-hint')
|
73
|
+
expect(errorHintToken?.text).toBe(' ← No such field')
|
74
|
+
})
|
75
|
+
|
76
|
+
test('should not create error hint tokens for valid fields', async () => {
|
77
|
+
const schema = buildSchema(`
|
78
|
+
type Query {
|
79
|
+
pokemon(id: ID!): Pokemon
|
80
|
+
}
|
81
|
+
|
82
|
+
type Pokemon {
|
83
|
+
id: ID!
|
84
|
+
name: String!
|
85
|
+
}
|
86
|
+
`)
|
87
|
+
|
88
|
+
const code = `query {
|
89
|
+
pokemon(id: "123") {
|
90
|
+
id
|
91
|
+
name
|
92
|
+
}
|
93
|
+
}`
|
94
|
+
|
95
|
+
const tokens = await parseGraphQLWithTreeSitter(code, [], schema)
|
96
|
+
|
97
|
+
// Check that no error hint tokens were created
|
98
|
+
const errorHintTokens = tokens.filter(t => t.highlighter.getCssClass() === 'graphql-error-hint')
|
99
|
+
|
100
|
+
expect(errorHintTokens.length).toBe(0)
|
101
|
+
})
|
102
|
+
})
|
@@ -0,0 +1,131 @@
|
|
1
|
+
import { buildSchema } from 'graphql'
|
2
|
+
import { describe, expect, test } from 'vitest'
|
3
|
+
import { parseGraphQLWithTreeSitter } from '../lib/parser.js'
|
4
|
+
import { isArgument } from '../lib/semantic-nodes.js'
|
5
|
+
|
6
|
+
describe('parseGraphQLWithTreeSitter', () => {
|
7
|
+
describe('argument parsing', () => {
|
8
|
+
test('should recognize argument names as interactive tokens', async () => {
|
9
|
+
const schema = buildSchema(`
|
10
|
+
type Query {
|
11
|
+
pokemon(id: ID!): String
|
12
|
+
}
|
13
|
+
`)
|
14
|
+
|
15
|
+
const code = `query {
|
16
|
+
pokemon(id: "123") {
|
17
|
+
__typename
|
18
|
+
}
|
19
|
+
}`
|
20
|
+
|
21
|
+
const tokens = await parseGraphQLWithTreeSitter(code, [], schema)
|
22
|
+
|
23
|
+
// Find the argument "id" token
|
24
|
+
const argumentToken = tokens.find(t =>
|
25
|
+
t.text === 'id'
|
26
|
+
&& isArgument(t.semantic)
|
27
|
+
)
|
28
|
+
|
29
|
+
expect(argumentToken).toBeDefined()
|
30
|
+
expect(argumentToken?.polen.isInteractive()).toBe(true)
|
31
|
+
expect(argumentToken?.polen.getReferenceUrl()).toBe('/reference/Query#pokemon__id')
|
32
|
+
})
|
33
|
+
|
34
|
+
test('should handle multiple arguments', async () => {
|
35
|
+
const schema = buildSchema(`
|
36
|
+
type Query {
|
37
|
+
search(query: String!, limit: Int, offset: Int): [String!]!
|
38
|
+
}
|
39
|
+
`)
|
40
|
+
|
41
|
+
const code = `query {
|
42
|
+
search(query: "test", limit: 10) {
|
43
|
+
__typename
|
44
|
+
}
|
45
|
+
}`
|
46
|
+
|
47
|
+
const tokens = await parseGraphQLWithTreeSitter(code, [], schema)
|
48
|
+
|
49
|
+
const queryArg = tokens.find(t => t.text === 'query' && isArgument(t.semantic))
|
50
|
+
const limitArg = tokens.find(t => t.text === 'limit' && isArgument(t.semantic))
|
51
|
+
|
52
|
+
expect(queryArg).toBeDefined()
|
53
|
+
expect(queryArg?.polen.isInteractive()).toBe(true)
|
54
|
+
expect(queryArg?.polen.getReferenceUrl()).toBe('/reference/Query#search__query')
|
55
|
+
|
56
|
+
expect(limitArg).toBeDefined()
|
57
|
+
expect(limitArg?.polen.isInteractive()).toBe(true)
|
58
|
+
expect(limitArg?.polen.getReferenceUrl()).toBe('/reference/Query#search__limit')
|
59
|
+
})
|
60
|
+
|
61
|
+
test('should handle arguments with variables', async () => {
|
62
|
+
const schema = buildSchema(`
|
63
|
+
type Query {
|
64
|
+
pokemon(id: ID!): String
|
65
|
+
}
|
66
|
+
`)
|
67
|
+
|
68
|
+
const code = `query GetPokemon($pokemonId: ID!) {
|
69
|
+
pokemon(id: $pokemonId) {
|
70
|
+
__typename
|
71
|
+
}
|
72
|
+
}`
|
73
|
+
|
74
|
+
const tokens = await parseGraphQLWithTreeSitter(code, [], schema)
|
75
|
+
|
76
|
+
// The argument name "id" should still be recognized even when value is a variable
|
77
|
+
const idArgument = tokens.find(t =>
|
78
|
+
t.text === 'id'
|
79
|
+
&& isArgument(t.semantic)
|
80
|
+
)
|
81
|
+
|
82
|
+
expect(idArgument).toBeDefined()
|
83
|
+
expect(idArgument?.polen.isInteractive()).toBe(true)
|
84
|
+
|
85
|
+
// Variable tokens - basic implementation completed
|
86
|
+
const variable = tokens.find(t => t.text === '$pokemonId')
|
87
|
+
if (variable && variable.semantic && 'kind' in variable.semantic) {
|
88
|
+
expect(variable.semantic.kind).toBe('Variable')
|
89
|
+
}
|
90
|
+
})
|
91
|
+
})
|
92
|
+
|
93
|
+
describe('field parsing', () => {
|
94
|
+
test('should recognize fields as interactive', async () => {
|
95
|
+
const schema = buildSchema(`
|
96
|
+
type Pokemon {
|
97
|
+
id: ID!
|
98
|
+
name: String!
|
99
|
+
}
|
100
|
+
|
101
|
+
type Query {
|
102
|
+
pokemon: Pokemon
|
103
|
+
}
|
104
|
+
`)
|
105
|
+
|
106
|
+
const code = `query {
|
107
|
+
pokemon {
|
108
|
+
id
|
109
|
+
name
|
110
|
+
}
|
111
|
+
}`
|
112
|
+
|
113
|
+
const tokens = await parseGraphQLWithTreeSitter(code, [], schema)
|
114
|
+
|
115
|
+
const pokemonField = tokens.find(t =>
|
116
|
+
t.text === 'pokemon' && t.semantic && 'kind' in t.semantic && t.semantic.kind === 'OutputField'
|
117
|
+
)
|
118
|
+
const idField = tokens.find(t =>
|
119
|
+
t.text === 'id' && t.semantic && 'kind' in t.semantic && t.semantic.kind === 'OutputField'
|
120
|
+
)
|
121
|
+
|
122
|
+
expect(pokemonField).toBeDefined()
|
123
|
+
expect(pokemonField?.polen.isInteractive()).toBe(true)
|
124
|
+
expect(pokemonField?.polen.getReferenceUrl()).toBe('/reference/Query#pokemon')
|
125
|
+
|
126
|
+
expect(idField).toBeDefined()
|
127
|
+
expect(idField?.polen.isInteractive()).toBe(true)
|
128
|
+
expect(idField?.polen.getReferenceUrl()).toBe('/reference/Pokemon#id')
|
129
|
+
})
|
130
|
+
})
|
131
|
+
})
|
@@ -1,8 +0,0 @@
|
|
1
|
-
import React from 'react';
|
2
|
-
import type { GraphQLDocumentProps } from '../../../lib/graphql-document/components/GraphQLDocument.js';
|
3
|
-
/**
|
4
|
-
* Wrapper component that provides schema from virtual module directly to GraphQLDocument
|
5
|
-
* This bypasses the context issue with MDX components
|
6
|
-
*/
|
7
|
-
export declare const GraphQLDocumentWithSchema: React.FC<Omit<GraphQLDocumentProps, `schema`>>;
|
8
|
-
//# sourceMappingURL=GraphQLDocumentWithSchema.d.ts.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"GraphQLDocumentWithSchema.d.ts","sourceRoot":"","sources":["../../../../src/template/components/content/GraphQLDocumentWithSchema.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6DAA6D,CAAA;AAEvG;;;GAGG;AACH,eAAO,MAAM,yBAAyB,EAAE,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,oBAAoB,EAAE,QAAQ,CAAC,CAGpF,CAAA"}
|
@@ -1,13 +0,0 @@
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
2
|
-
import React from 'react';
|
3
|
-
import PROJECT_DATA from 'virtual:polen/project/data.jsonsuper';
|
4
|
-
import { GraphQLDocument } from '../../../lib/graphql-document/components/GraphQLDocument.js';
|
5
|
-
/**
|
6
|
-
* Wrapper component that provides schema from virtual module directly to GraphQLDocument
|
7
|
-
* This bypasses the context issue with MDX components
|
8
|
-
*/
|
9
|
-
export const GraphQLDocumentWithSchema = (props) => {
|
10
|
-
const schema = PROJECT_DATA.schema?.versions[0]?.after;
|
11
|
-
return _jsx(GraphQLDocument, { ...props, schema: schema });
|
12
|
-
};
|
13
|
-
//# sourceMappingURL=GraphQLDocumentWithSchema.js.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"GraphQLDocumentWithSchema.js","sourceRoot":"","sources":["../../../../src/template/components/content/GraphQLDocumentWithSchema.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,YAAY,MAAM,sCAAsC,CAAA;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,6DAA6D,CAAA;AAG7F;;;GAGG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAmD,CAAC,KAAK,EAAE,EAAE;IACjG,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,CAAA;IACtD,OAAO,KAAC,eAAe,OAAK,KAAK,EAAE,MAAM,EAAE,MAAM,GAAI,CAAA;AACvD,CAAC,CAAA"}
|
@@ -1,7 +0,0 @@
|
|
1
|
-
import React from 'react';
|
2
|
-
import type { GraphQLDocumentProps } from '../../../lib/graphql-document/components/GraphQLDocument.js';
|
3
|
-
/**
|
4
|
-
* Client-side wrapper that hydrates GraphQL documents with schema
|
5
|
-
*/
|
6
|
-
export declare const GraphQLDocumentWithSchema: React.FC<Omit<GraphQLDocumentProps, `schema`>>;
|
7
|
-
//# sourceMappingURL=GraphQLDocumentWrapper.d.ts.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"GraphQLDocumentWrapper.d.ts","sourceRoot":"","sources":["../../../../src/template/components/content/GraphQLDocumentWrapper.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6DAA6D,CAAA;AAEvG;;GAEG;AACH,eAAO,MAAM,yBAAyB,EAAE,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,oBAAoB,EAAE,QAAQ,CAAC,CAgEpF,CAAA"}
|
@@ -1,48 +0,0 @@
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
2
|
-
import React from 'react';
|
3
|
-
import { GraphQLDocument } from '../../../lib/graphql-document/components/GraphQLDocument.js';
|
4
|
-
/**
|
5
|
-
* Client-side wrapper that hydrates GraphQL documents with schema
|
6
|
-
*/
|
7
|
-
export const GraphQLDocumentWithSchema = (props) => {
|
8
|
-
try {
|
9
|
-
const [schema, setSchema] = React.useState(null);
|
10
|
-
const [isClient, setIsClient] = React.useState(false);
|
11
|
-
React.useEffect(() => {
|
12
|
-
setIsClient(true);
|
13
|
-
// Access virtual module only on client side
|
14
|
-
if (typeof window !== `undefined`) {
|
15
|
-
import(`virtual:polen/project/data.jsonsuper`).then(PROJECT_DATA => {
|
16
|
-
const s = PROJECT_DATA.default?.schema?.versions?.[0]?.after;
|
17
|
-
// Schema loaded successfully
|
18
|
-
if (s) {
|
19
|
-
setSchema(s);
|
20
|
-
}
|
21
|
-
}).catch(() => {
|
22
|
-
// Schema loading is optional - continue without it
|
23
|
-
});
|
24
|
-
}
|
25
|
-
}, []);
|
26
|
-
// During SSR, render a simple code block
|
27
|
-
if (!isClient) {
|
28
|
-
return (_jsx("div", { "data-testid": 'graphql-document', className: 'graphql-document graphql-document-static', children: _jsx("pre", { children: _jsx("code", { className: "language-graphql", children: props.children }) }) }));
|
29
|
-
}
|
30
|
-
// During client render, use the full component
|
31
|
-
// Pass a custom navigate function that doesn't require router
|
32
|
-
const handleNavigate = (url) => {
|
33
|
-
if (typeof window !== `undefined`) {
|
34
|
-
window.location.href = url;
|
35
|
-
}
|
36
|
-
};
|
37
|
-
return (_jsx("div", { "data-testid": 'graphql-document', children: _jsx(GraphQLDocument, { ...props, schema: schema, options: {
|
38
|
-
debug: false, // Default to false for shipping
|
39
|
-
...props.options,
|
40
|
-
onNavigate: handleNavigate,
|
41
|
-
} }) }));
|
42
|
-
}
|
43
|
-
catch (err) {
|
44
|
-
// Fall back to plain code block on error
|
45
|
-
return (_jsx("div", { "data-testid": 'graphql-document', className: 'graphql-document graphql-document-static', children: _jsx("pre", { children: _jsx("code", { className: "language-graphql", children: props.children }) }) }));
|
46
|
-
}
|
47
|
-
};
|
48
|
-
//# sourceMappingURL=GraphQLDocumentWrapper.js.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"GraphQLDocumentWrapper.js","sourceRoot":"","sources":["../../../../src/template/components/content/GraphQLDocumentWrapper.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,eAAe,EAAE,MAAM,6DAA6D,CAAA;AAG7F;;GAEG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAmD,CAAC,KAAK,EAAE,EAAE;IACjG,IAAI,CAAC;QACH,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAM,IAAI,CAAC,CAAA;QACrD,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;QAErD,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;YACnB,WAAW,CAAC,IAAI,CAAC,CAAA;YAEjB,4CAA4C;YAC5C,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;gBAClC,MAAM,CAAC,sCAAsC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE;oBACjE,MAAM,CAAC,GAAG,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAA;oBAC5D,6BAA6B;oBAC7B,IAAI,CAAC,EAAE,CAAC;wBACN,SAAS,CAAC,CAAC,CAAC,CAAA;oBACd,CAAC;gBACH,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;oBACZ,mDAAmD;gBACrD,CAAC,CAAC,CAAA;YACJ,CAAC;QACH,CAAC,EAAE,EAAE,CAAC,CAAA;QAEN,yCAAyC;QACzC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,CACL,6BAAiB,kBAAkB,EAAC,SAAS,EAAC,0CAA0C,YACtF,wBACE,eAAM,SAAS,EAAC,kBAAkB,YAAE,KAAK,CAAC,QAAQ,GAAQ,GACtD,GACF,CACP,CAAA;QACH,CAAC;QAED,+CAA+C;QAC/C,8DAA8D;QAC9D,MAAM,cAAc,GAAG,CAAC,GAAW,EAAE,EAAE;YACrC,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;gBAClC,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,GAAG,CAAA;YAC5B,CAAC;QACH,CAAC,CAAA;QAED,OAAO,CACL,6BAAiB,kBAAkB,YACjC,KAAC,eAAe,OACV,KAAK,EACT,MAAM,EAAE,MAAM,EACd,OAAO,EAAE;oBACP,KAAK,EAAE,KAAK,EAAE,gCAAgC;oBAC9C,GAAG,KAAK,CAAC,OAAO;oBAChB,UAAU,EAAE,cAAc;iBAC3B,GACD,GACE,CACP,CAAA;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,yCAAyC;QACzC,OAAO,CACL,6BAAiB,kBAAkB,EAAC,SAAS,EAAC,0CAA0C,YACtF,wBACE,eAAM,SAAS,EAAC,kBAAkB,YAAE,KAAK,CAAC,QAAQ,GAAQ,GACtD,GACF,CACP,CAAA;IACH,CAAC;AACH,CAAC,CAAA"}
|
@@ -1,13 +0,0 @@
|
|
1
|
-
import React from 'react'
|
2
|
-
import PROJECT_DATA from 'virtual:polen/project/data.jsonsuper'
|
3
|
-
import { GraphQLDocument } from '../../../lib/graphql-document/components/GraphQLDocument.js'
|
4
|
-
import type { GraphQLDocumentProps } from '../../../lib/graphql-document/components/GraphQLDocument.js'
|
5
|
-
|
6
|
-
/**
|
7
|
-
* Wrapper component that provides schema from virtual module directly to GraphQLDocument
|
8
|
-
* This bypasses the context issue with MDX components
|
9
|
-
*/
|
10
|
-
export const GraphQLDocumentWithSchema: React.FC<Omit<GraphQLDocumentProps, `schema`>> = (props) => {
|
11
|
-
const schema = PROJECT_DATA.schema?.versions[0]?.after
|
12
|
-
return <GraphQLDocument {...props} schema={schema} />
|
13
|
-
}
|
@@ -1,72 +0,0 @@
|
|
1
|
-
import React from 'react'
|
2
|
-
import { GraphQLDocument } from '../../../lib/graphql-document/components/GraphQLDocument.js'
|
3
|
-
import type { GraphQLDocumentProps } from '../../../lib/graphql-document/components/GraphQLDocument.js'
|
4
|
-
|
5
|
-
/**
|
6
|
-
* Client-side wrapper that hydrates GraphQL documents with schema
|
7
|
-
*/
|
8
|
-
export const GraphQLDocumentWithSchema: React.FC<Omit<GraphQLDocumentProps, `schema`>> = (props) => {
|
9
|
-
try {
|
10
|
-
const [schema, setSchema] = React.useState<any>(null)
|
11
|
-
const [isClient, setIsClient] = React.useState(false)
|
12
|
-
|
13
|
-
React.useEffect(() => {
|
14
|
-
setIsClient(true)
|
15
|
-
|
16
|
-
// Access virtual module only on client side
|
17
|
-
if (typeof window !== `undefined`) {
|
18
|
-
import(`virtual:polen/project/data.jsonsuper`).then(PROJECT_DATA => {
|
19
|
-
const s = PROJECT_DATA.default?.schema?.versions?.[0]?.after
|
20
|
-
// Schema loaded successfully
|
21
|
-
if (s) {
|
22
|
-
setSchema(s)
|
23
|
-
}
|
24
|
-
}).catch(() => {
|
25
|
-
// Schema loading is optional - continue without it
|
26
|
-
})
|
27
|
-
}
|
28
|
-
}, [])
|
29
|
-
|
30
|
-
// During SSR, render a simple code block
|
31
|
-
if (!isClient) {
|
32
|
-
return (
|
33
|
-
<div data-testid='graphql-document' className='graphql-document graphql-document-static'>
|
34
|
-
<pre>
|
35
|
-
<code className="language-graphql">{props.children}</code>
|
36
|
-
</pre>
|
37
|
-
</div>
|
38
|
-
)
|
39
|
-
}
|
40
|
-
|
41
|
-
// During client render, use the full component
|
42
|
-
// Pass a custom navigate function that doesn't require router
|
43
|
-
const handleNavigate = (url: string) => {
|
44
|
-
if (typeof window !== `undefined`) {
|
45
|
-
window.location.href = url
|
46
|
-
}
|
47
|
-
}
|
48
|
-
|
49
|
-
return (
|
50
|
-
<div data-testid='graphql-document'>
|
51
|
-
<GraphQLDocument
|
52
|
-
{...props}
|
53
|
-
schema={schema}
|
54
|
-
options={{
|
55
|
-
debug: false, // Default to false for shipping
|
56
|
-
...props.options,
|
57
|
-
onNavigate: handleNavigate,
|
58
|
-
}}
|
59
|
-
/>
|
60
|
-
</div>
|
61
|
-
)
|
62
|
-
} catch (err) {
|
63
|
-
// Fall back to plain code block on error
|
64
|
-
return (
|
65
|
-
<div data-testid='graphql-document' className='graphql-document graphql-document-static'>
|
66
|
-
<pre>
|
67
|
-
<code className="language-graphql">{props.children}</code>
|
68
|
-
</pre>
|
69
|
-
</div>
|
70
|
-
)
|
71
|
-
}
|
72
|
-
}
|