polen 0.11.0-next.24 → 0.11.0-next.25
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/input.d.ts +76 -77
- package/build/api/config/input.d.ts.map +1 -1
- package/build/api/config/normalized.d.ts +136 -143
- package/build/api/config/normalized.d.ts.map +1 -1
- package/build/api/config-template/template.d.ts +110 -121
- package/build/api/config-template/template.d.ts.map +1 -1
- package/build/api/examples/diagnostic/diagnostic.d.ts +0 -23
- package/build/api/examples/diagnostic/diagnostic.d.ts.map +1 -1
- package/build/api/examples/diagnostic/diagnostic.js +1 -3
- package/build/api/examples/diagnostic/diagnostic.js.map +1 -1
- package/build/api/examples/scanner.d.ts +27 -1
- package/build/api/examples/scanner.d.ts.map +1 -1
- package/build/api/examples/scanner.js +19 -17
- package/build/api/examples/scanner.js.map +1 -1
- package/build/api/examples/schemas/catalog.d.ts +20 -12
- package/build/api/examples/schemas/catalog.d.ts.map +1 -1
- package/build/api/examples/schemas/example/example.d.ts +17 -11
- package/build/api/examples/schemas/example/example.d.ts.map +1 -1
- package/build/api/schema/augmentations/$$.d.ts +7 -0
- package/build/api/schema/augmentations/$$.d.ts.map +1 -0
- package/build/api/schema/augmentations/$$.js +7 -0
- package/build/api/schema/augmentations/$$.js.map +1 -0
- package/build/api/schema/augmentations/$.d.ts +1 -1
- package/build/api/schema/augmentations/$.d.ts.map +1 -1
- package/build/api/schema/augmentations/$.js +1 -1
- package/build/api/schema/augmentations/$.js.map +1 -1
- package/build/api/schema/augmentations/apply.d.ts +29 -0
- package/build/api/schema/augmentations/apply.d.ts.map +1 -0
- package/build/api/schema/augmentations/apply.js +181 -0
- package/build/api/schema/augmentations/apply.js.map +1 -0
- package/build/api/schema/augmentations/augmentation.d.ts +31 -0
- package/build/api/schema/augmentations/augmentation.d.ts.map +1 -0
- package/build/api/schema/augmentations/augmentation.js +22 -0
- package/build/api/schema/augmentations/augmentation.js.map +1 -0
- package/build/api/schema/augmentations/config.d.ts +24 -0
- package/build/api/schema/augmentations/config.d.ts.map +1 -0
- package/build/api/schema/augmentations/config.js +9 -0
- package/build/api/schema/augmentations/config.js.map +1 -0
- package/build/api/schema/augmentations/diagnostics/diagnostic.d.ts +67 -0
- package/build/api/schema/augmentations/diagnostics/diagnostic.d.ts.map +1 -0
- package/build/api/schema/augmentations/diagnostics/diagnostic.js +13 -0
- package/build/api/schema/augmentations/diagnostics/diagnostic.js.map +1 -0
- package/build/api/schema/augmentations/diagnostics/duplicate-version.d.ts +45 -0
- package/build/api/schema/augmentations/diagnostics/duplicate-version.d.ts.map +1 -0
- package/build/api/schema/augmentations/diagnostics/duplicate-version.js +17 -0
- package/build/api/schema/augmentations/diagnostics/duplicate-version.js.map +1 -0
- package/build/api/schema/augmentations/diagnostics/invalid-path.d.ts +46 -0
- package/build/api/schema/augmentations/diagnostics/invalid-path.d.ts.map +1 -0
- package/build/api/schema/augmentations/diagnostics/invalid-path.js +18 -0
- package/build/api/schema/augmentations/diagnostics/invalid-path.js.map +1 -0
- package/build/api/schema/augmentations/diagnostics/version-mismatch.d.ts +46 -0
- package/build/api/schema/augmentations/diagnostics/version-mismatch.d.ts.map +1 -0
- package/build/api/schema/augmentations/diagnostics/version-mismatch.js +18 -0
- package/build/api/schema/augmentations/diagnostics/version-mismatch.js.map +1 -0
- package/build/api/schema/augmentations/input.d.ts +145 -0
- package/build/api/schema/augmentations/input.d.ts.map +1 -0
- package/build/api/schema/augmentations/input.js +191 -0
- package/build/api/schema/augmentations/input.js.map +1 -0
- package/build/api/schema/augmentations/placement.d.ts +8 -0
- package/build/api/schema/augmentations/placement.d.ts.map +1 -0
- package/build/api/schema/augmentations/placement.js +7 -0
- package/build/api/schema/augmentations/placement.js.map +1 -0
- package/build/api/schema/config-schema.d.ts +66 -66
- package/build/api/schema/config-schema.d.ts.map +1 -1
- package/build/api/schema/config-schema.js +2 -2
- package/build/api/schema/config-schema.js.map +1 -1
- package/build/api/schema/input-source/load.d.ts +2 -0
- package/build/api/schema/input-source/load.d.ts.map +1 -1
- package/build/api/schema/input-source/load.js.map +1 -1
- package/build/api/schema/input-sources/directory.d.ts +39 -39
- package/build/api/schema/input-sources/file.d.ts +39 -39
- package/build/api/schema/input-sources/introspection-file.d.ts +39 -39
- package/build/api/schema/input-sources/introspection.d.ts +39 -39
- package/build/api/schema/input-sources/memory.d.ts +39 -39
- package/build/api/schema/input-sources/versioned-directory.d.ts +79 -79
- package/build/api/schema/load.d.ts.map +1 -1
- package/build/api/schema/load.js +9 -2
- package/build/api/schema/load.js.map +1 -1
- package/build/lib/catalog/catalog.d.ts +1181 -1181
- package/build/lib/catalog/unversioned.d.ts +312 -312
- package/build/lib/catalog/versioned.d.ts +634 -634
- package/build/lib/change/change.d.ts +238 -238
- package/build/lib/document/document.d.ts +14 -8
- package/build/lib/document/document.d.ts.map +1 -1
- package/build/lib/document/versioned.d.ts +17 -10
- package/build/lib/document/versioned.d.ts.map +1 -1
- package/build/lib/grafaid/schema/KindMap/_.d.ts +1 -1
- package/build/lib/graphql-path/$$.d.ts +7 -13
- package/build/lib/graphql-path/$$.d.ts.map +1 -1
- package/build/lib/graphql-path/$$.js +7 -13
- package/build/lib/graphql-path/$$.js.map +1 -1
- package/build/lib/graphql-path/definition.d.ts +104 -94
- package/build/lib/graphql-path/definition.d.ts.map +1 -1
- package/build/lib/graphql-path/definition.js +126 -125
- package/build/lib/graphql-path/definition.js.map +1 -1
- package/build/lib/graphql-path/query.d.ts +25 -57
- package/build/lib/graphql-path/query.d.ts.map +1 -1
- package/build/lib/graphql-path/query.js +15 -93
- package/build/lib/graphql-path/query.js.map +1 -1
- package/build/lib/graphql-path/schema.d.ts +49 -0
- package/build/lib/graphql-path/schema.d.ts.map +1 -0
- package/build/lib/graphql-path/schema.js +89 -0
- package/build/lib/graphql-path/schema.js.map +1 -0
- package/build/lib/graphql-path/types.d.ts +76 -28
- package/build/lib/graphql-path/types.d.ts.map +1 -1
- package/build/lib/graphql-path/types.js +101 -2
- package/build/lib/graphql-path/types.js.map +1 -1
- package/build/lib/revision/revision.d.ts +1170 -1170
- package/build/lib/schema/schema.d.ts +708 -708
- package/build/lib/schema/unversioned.d.ts +1092 -1092
- package/build/lib/schema/versioned.d.ts +634 -634
- package/build/lib/semver/official-release.d.ts +10 -10
- package/build/lib/semver/pre-release.d.ts +10 -10
- package/build/lib/semver/semver.d.ts +50 -50
- package/build/lib/version-coverage/version-coverage.d.ts +43 -11
- package/build/lib/version-coverage/version-coverage.d.ts.map +1 -1
- package/build/lib/version-coverage/version-coverage.js +40 -6
- package/build/lib/version-coverage/version-coverage.js.map +1 -1
- package/build/template/hooks/use-examples.d.ts +1 -1
- package/build/template/routes/changelog/ChangelogSidebar.d.ts +2 -2
- package/build/template/routes/changelog/ChangelogSidebar.d.ts.map +1 -1
- package/build/template/routes/changelog/ChangelogSidebar.js +4 -4
- package/build/template/routes/changelog/ChangelogSidebar.js.map +1 -1
- package/build/template/routes/examples/_.d.ts +3 -3
- package/build/template/routes/examples/_index.d.ts +2 -2
- package/build/template/routes/examples/name.d.ts +3 -3
- package/build/template/stores/changelog.d.ts +39 -39
- package/build/vite/plugins/examples.d.ts.map +1 -1
- package/build/vite/plugins/examples.js +0 -2
- package/build/vite/plugins/examples.js.map +1 -1
- package/build/vite/plugins/schemas.d.ts.map +1 -1
- package/build/vite/plugins/schemas.js +38 -2
- package/build/vite/plugins/schemas.js.map +1 -1
- package/package.json +1 -1
- package/src/api/examples/diagnostic/diagnostic.ts +0 -3
- package/src/api/examples/scanner.test.ts +83 -0
- package/src/api/examples/scanner.ts +17 -21
- package/src/api/schema/augmentations/$$.ts +6 -0
- package/src/api/schema/augmentations/$.ts +1 -1
- package/src/api/schema/augmentations/apply.test.ts +89 -0
- package/src/api/schema/augmentations/apply.ts +277 -0
- package/src/api/schema/augmentations/augmentation.ts +24 -0
- package/src/api/schema/augmentations/config.ts +11 -0
- package/src/api/schema/augmentations/diagnostics/diagnostic.ts +20 -0
- package/src/api/schema/augmentations/diagnostics/duplicate-version.ts +20 -0
- package/src/api/schema/augmentations/diagnostics/invalid-path.ts +21 -0
- package/src/api/schema/augmentations/diagnostics/version-mismatch.ts +21 -0
- package/src/api/schema/augmentations/input.test.ts +144 -0
- package/src/api/schema/augmentations/input.ts +215 -0
- package/src/api/schema/augmentations/placement.ts +11 -0
- package/src/api/schema/config-schema.ts +2 -2
- package/src/api/schema/input-source/load.ts +2 -0
- package/src/api/schema/load.ts +19 -2
- package/src/lib/graphql-path/$$.ts +7 -13
- package/src/lib/graphql-path/$.test.ts +175 -0
- package/src/lib/graphql-path/definition.ts +162 -162
- package/src/lib/graphql-path/query.ts +15 -98
- package/src/lib/graphql-path/schema.ts +136 -0
- package/src/lib/graphql-path/types.ts +108 -28
- package/src/lib/version-coverage/version-coverage.ts +48 -6
- package/src/template/routes/changelog/ChangelogSidebar.tsx +4 -4
- package/src/vite/plugins/examples.ts +0 -2
- package/src/vite/plugins/schemas.ts +51 -2
- package/build/api/examples/diagnostic/unused-default.d.ts +0 -49
- package/build/api/examples/diagnostic/unused-default.d.ts.map +0 -1
- package/build/api/examples/diagnostic/unused-default.js +0 -19
- package/build/api/examples/diagnostic/unused-default.js.map +0 -1
- package/build/api/schema/augmentations/augmentations/description.d.ts +0 -26
- package/build/api/schema/augmentations/augmentations/description.d.ts.map +0 -1
- package/build/api/schema/augmentations/augmentations/description.js +0 -55
- package/build/api/schema/augmentations/augmentations/description.js.map +0 -1
- package/build/api/schema/augmentations/schema-augmentation.d.ts +0 -20
- package/build/api/schema/augmentations/schema-augmentation.d.ts.map +0 -1
- package/build/api/schema/augmentations/schema-augmentation.js +0 -22
- package/build/api/schema/augmentations/schema-augmentation.js.map +0 -1
- package/build/api/schema/augmentations/target.d.ts +0 -25
- package/build/api/schema/augmentations/target.d.ts.map +0 -1
- package/build/api/schema/augmentations/target.js +0 -39
- package/build/api/schema/augmentations/target.js.map +0 -1
- package/build/lib/graphql-path/constructors.d.ts +0 -57
- package/build/lib/graphql-path/constructors.d.ts.map +0 -1
- package/build/lib/graphql-path/constructors.js +0 -73
- package/build/lib/graphql-path/constructors.js.map +0 -1
- package/src/api/examples/diagnostic/unused-default.ts +0 -22
- package/src/api/schema/augmentations/augmentations/description.ts +0 -69
- package/src/api/schema/augmentations/schema-augmentation.ts +0 -32
- package/src/api/schema/augmentations/target.ts +0 -61
- package/src/lib/graphql-path/constructors.ts +0 -81
@@ -1,73 +1,153 @@
|
|
1
1
|
/**
|
2
|
-
* Definition path operations
|
3
|
-
*/
|
4
|
-
|
5
|
-
import {
|
6
|
-
|
7
|
-
import
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
2
|
+
* Definition path operations using Effect Schema transforms
|
3
|
+
*/
|
4
|
+
|
5
|
+
import { S } from '#lib/kit-temp/effect'
|
6
|
+
import { ParseResult } from 'effect'
|
7
|
+
import { ArgumentSegment, FieldSegment, TypeSegment } from './types.js'
|
8
|
+
|
9
|
+
// ============================================================================
|
10
|
+
// Internal Path Schemas (Decoded Forms)
|
11
|
+
// ============================================================================
|
12
|
+
|
13
|
+
const TypeDefinitionPathDecoded = S.Tuple(TypeSegment)
|
14
|
+
const FieldDefinitionPathDecoded = S.Tuple(TypeSegment, FieldSegment)
|
15
|
+
const ArgumentDefinitionPathDecoded = S.Tuple(TypeSegment, FieldSegment, ArgumentSegment)
|
16
|
+
|
17
|
+
// ============================================================================
|
18
|
+
// Transform Codecs (String <-> Struct)
|
19
|
+
// ============================================================================
|
20
|
+
|
21
|
+
/**
|
22
|
+
* Type definition path codec
|
23
|
+
* Encoded: "User"
|
24
|
+
* Decoded: [{ _tag: 'TypeSegment', type: 'User' }]
|
25
|
+
*/
|
26
|
+
export const TypeDefinitionPath = S.transformOrFail(
|
27
|
+
S.String,
|
28
|
+
TypeDefinitionPathDecoded,
|
29
|
+
{
|
30
|
+
decode: (str, _options, ast) => {
|
31
|
+
if (!str || str.includes('.') || str.includes('(')) {
|
32
|
+
return ParseResult.fail(new ParseResult.Type(ast, str))
|
33
|
+
}
|
34
|
+
return ParseResult.succeed([TypeSegment.make({ type: str })])
|
35
|
+
},
|
36
|
+
encode: (path) => ParseResult.succeed(path[0].type),
|
37
|
+
},
|
38
|
+
).annotations({
|
39
|
+
identifier: 'TypeDefinitionPath',
|
40
|
+
description: 'Path to a type definition',
|
41
|
+
})
|
42
|
+
|
43
|
+
/**
|
44
|
+
* Field definition path codec
|
45
|
+
* Encoded: "User.name"
|
46
|
+
* Decoded: [{ _tag: 'TypeSegment', type: 'User' }, { _tag: 'FieldSegment', field: 'name' }]
|
47
|
+
*/
|
48
|
+
export const FieldDefinitionPath = S.transformOrFail(
|
49
|
+
S.String,
|
50
|
+
FieldDefinitionPathDecoded,
|
51
|
+
{
|
52
|
+
decode: (str, _options, ast) => {
|
53
|
+
const parts = str.split('.')
|
54
|
+
if (parts.length !== 2 || !parts[0] || !parts[1] || str.includes('(')) {
|
55
|
+
return ParseResult.fail(new ParseResult.Type(ast, str))
|
56
|
+
}
|
57
|
+
return ParseResult.succeed([
|
58
|
+
TypeSegment.make({ type: parts[0] }),
|
59
|
+
FieldSegment.make({ field: parts[1] }),
|
60
|
+
])
|
61
|
+
},
|
62
|
+
encode: (path) => ParseResult.succeed(`${path[0].type}.${path[1].field}`),
|
63
|
+
},
|
64
|
+
).annotations({
|
65
|
+
identifier: 'FieldDefinitionPath',
|
66
|
+
description: 'Path to a field definition',
|
67
|
+
})
|
68
|
+
|
69
|
+
/**
|
70
|
+
* Argument definition path codec
|
71
|
+
* Encoded: "User.posts(limit)"
|
72
|
+
* Decoded: [{ _tag: 'TypeSegment', type: 'User' }, { _tag: 'FieldSegment', field: 'posts' }, { _tag: 'ArgumentSegment', argument: 'limit' }]
|
73
|
+
*/
|
74
|
+
export const ArgumentDefinitionPath = S.transformOrFail(
|
75
|
+
S.String,
|
76
|
+
ArgumentDefinitionPathDecoded,
|
77
|
+
{
|
78
|
+
decode: (str, _options, ast) => {
|
79
|
+
const match = str.match(/^([^.]+)\.([^.(]+)\(([^)]+)\)$/)
|
80
|
+
if (!match || !match[1] || !match[2] || !match[3]) {
|
81
|
+
return ParseResult.fail(new ParseResult.Type(ast, str))
|
82
|
+
}
|
83
|
+
return ParseResult.succeed([
|
84
|
+
TypeSegment.make({ type: match[1] }),
|
85
|
+
FieldSegment.make({ field: match[2] }),
|
86
|
+
ArgumentSegment.make({ argument: match[3] }),
|
87
|
+
])
|
88
|
+
},
|
89
|
+
encode: (path) => ParseResult.succeed(`${path[0].type}.${path[1].field}(${path[2].argument})`),
|
90
|
+
},
|
91
|
+
).annotations({
|
92
|
+
identifier: 'ArgumentDefinitionPath',
|
93
|
+
description: 'Path to an argument definition',
|
94
|
+
})
|
95
|
+
|
96
|
+
/**
|
97
|
+
* Union of all definition paths
|
98
|
+
* Automatically determines the correct path type from the string format
|
99
|
+
*/
|
100
|
+
export const DefinitionPath = S.Union(
|
101
|
+
ArgumentDefinitionPath, // Check argument first (most specific)
|
102
|
+
FieldDefinitionPath, // Then field
|
103
|
+
TypeDefinitionPath, // Then type (least specific)
|
104
|
+
).annotations({
|
105
|
+
identifier: 'DefinitionPath',
|
106
|
+
description: 'Union of all definition path types',
|
107
|
+
})
|
108
|
+
|
109
|
+
// ============================================================================
|
110
|
+
// Type Exports
|
111
|
+
// ============================================================================
|
112
|
+
|
113
|
+
export type TypeDefinitionPath = S.Schema.Type<typeof TypeDefinitionPath>
|
114
|
+
export type FieldDefinitionPath = S.Schema.Type<typeof FieldDefinitionPath>
|
115
|
+
export type ArgumentDefinitionPath = S.Schema.Type<typeof ArgumentDefinitionPath>
|
116
|
+
export type DefinitionPath = S.Schema.Type<typeof DefinitionPath>
|
117
|
+
|
118
|
+
// ============================================================================
|
119
|
+
// Codec Functions
|
120
|
+
// ============================================================================
|
28
121
|
|
29
122
|
/**
|
30
123
|
* Decode a string expression into a definition path
|
31
|
-
*
|
32
124
|
* @param expression - The string expression to decode
|
33
|
-
* @returns The decoded definition path
|
125
|
+
* @returns The decoded definition path
|
34
126
|
* @example
|
35
127
|
* decode('User') // type definition path
|
36
128
|
* decode('User.name') // field definition path
|
37
129
|
* decode('User.posts(limit)') // argument definition path
|
38
130
|
*/
|
39
|
-
export const
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
}
|
55
|
-
|
56
|
-
// Handle type path: Type
|
57
|
-
const typeMatch = expression.match(/^[^.]+$/)
|
58
|
-
if (typeMatch) {
|
59
|
-
return createTypeDefinitionPath(expression)
|
60
|
-
}
|
61
|
-
|
62
|
-
return null
|
63
|
-
}
|
131
|
+
export const decodeSync = S.decodeUnknownSync(DefinitionPath)
|
132
|
+
|
133
|
+
/**
|
134
|
+
* Encode a definition path to a string expression
|
135
|
+
* @param path - The definition path to encode
|
136
|
+
* @returns A string expression representation
|
137
|
+
* @example
|
138
|
+
* encode([{ _tag: 'TypeSegment', type: 'User' }]) // 'User'
|
139
|
+
* encode([{ _tag: 'TypeSegment', type: 'User' }, { _tag: 'FieldSegment', field: 'name' }]) // 'User.name'
|
140
|
+
*/
|
141
|
+
export const encodeSync = S.encodeSync(DefinitionPath)
|
142
|
+
|
143
|
+
// ============================================================================
|
144
|
+
// Helper Functions
|
145
|
+
// ============================================================================
|
64
146
|
|
65
147
|
/**
|
66
148
|
* Extract the type name from any definition path
|
67
|
-
*
|
68
149
|
* @param path - The definition path
|
69
150
|
* @returns The type name
|
70
|
-
* @example getType([{ kind: 'type', type: 'User' }]) // 'User'
|
71
151
|
*/
|
72
152
|
export const getType = (path: DefinitionPath): string => {
|
73
153
|
return path[0].type
|
@@ -75,10 +155,8 @@ export const getType = (path: DefinitionPath): string => {
|
|
75
155
|
|
76
156
|
/**
|
77
157
|
* Extract the field name from a field or argument definition path
|
78
|
-
*
|
79
158
|
* @param path - The field or argument definition path
|
80
159
|
* @returns The field name
|
81
|
-
* @example getField([{ kind: 'type', type: 'User' }, { kind: 'field', field: 'name' }]) // 'name'
|
82
160
|
*/
|
83
161
|
export const getField = (path: FieldDefinitionPath | ArgumentDefinitionPath): string => {
|
84
162
|
return path[1].field
|
@@ -86,155 +164,77 @@ export const getField = (path: FieldDefinitionPath | ArgumentDefinitionPath): st
|
|
86
164
|
|
87
165
|
/**
|
88
166
|
* Extract the argument name from an argument definition path
|
89
|
-
*
|
90
167
|
* @param path - The argument definition path
|
91
168
|
* @returns The argument name
|
92
|
-
* @example getArgument([{ kind: 'type', type: 'User' }, { kind: 'field', field: 'posts' }, { kind: 'argument', argument: 'limit' }]) // 'limit'
|
93
169
|
*/
|
94
170
|
export const getArgument = (path: ArgumentDefinitionPath): string => {
|
95
171
|
return path[2].argument
|
96
172
|
}
|
97
173
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
export const parseFieldPath = (path?: string): { typeName: string | null; fieldName: string | null } => {
|
102
|
-
if (!path) return { typeName: null, fieldName: null }
|
103
|
-
|
104
|
-
const parts = path.split('.')
|
105
|
-
if (parts.length >= 2) {
|
106
|
-
return {
|
107
|
-
typeName: parts[0] || null,
|
108
|
-
fieldName: parts[1] || null,
|
109
|
-
}
|
110
|
-
}
|
111
|
-
|
112
|
-
return { typeName: null, fieldName: null }
|
113
|
-
}
|
114
|
-
|
115
|
-
/**
|
116
|
-
* Definition paths - direct paths to schema definition elements
|
117
|
-
* These represent the "address" of a specific schema element
|
118
|
-
*/
|
119
|
-
export type DefinitionPath =
|
120
|
-
| TypeDefinitionPath
|
121
|
-
| FieldDefinitionPath
|
122
|
-
| ArgumentDefinitionPath
|
123
|
-
|
124
|
-
/**
|
125
|
-
* Path to a type definition
|
126
|
-
* @example [{ kind: 'type', type: 'User' }]
|
127
|
-
*/
|
128
|
-
export type TypeDefinitionPath = [TypeSegment]
|
129
|
-
|
130
|
-
/**
|
131
|
-
* Path to a field definition (type + field)
|
132
|
-
* @example [{ kind: 'type', type: 'User' }, { kind: 'field', field: 'name' }]
|
133
|
-
*/
|
134
|
-
export type FieldDefinitionPath = [TypeSegment, FieldSegment]
|
135
|
-
|
136
|
-
/**
|
137
|
-
* Path to an argument definition (type + field + argument)
|
138
|
-
* @example [{ kind: 'type', type: 'User' }, { kind: 'field', field: 'posts' }, { kind: 'argument', argument: 'limit' }]
|
139
|
-
*/
|
140
|
-
export type ArgumentDefinitionPath = [TypeSegment, FieldSegment, ArgumentSegment]
|
174
|
+
// ============================================================================
|
175
|
+
// Type Guards
|
176
|
+
// ============================================================================
|
141
177
|
|
142
178
|
/**
|
143
179
|
* Type guard to check if a path is a type definition path
|
144
|
-
*
|
145
|
-
* @param path - The path to check
|
146
|
-
* @returns True if the path is a type definition path
|
147
180
|
*/
|
148
181
|
export const isTypeDefinitionPath = (path: DefinitionPath): path is TypeDefinitionPath => {
|
149
|
-
return path.length === 1 && path[0].
|
182
|
+
return path.length === 1 && path[0]._tag === 'TypeSegment'
|
150
183
|
}
|
151
184
|
|
152
185
|
/**
|
153
186
|
* Type guard to check if a path is a field definition path
|
154
|
-
*
|
155
|
-
* @param path - The path to check
|
156
|
-
* @returns True if the path is a field definition path
|
157
187
|
*/
|
158
188
|
export const isFieldDefinitionPath = (path: DefinitionPath): path is FieldDefinitionPath => {
|
159
|
-
return path.length === 2 && path[0].
|
189
|
+
return path.length === 2 && path[0]._tag === 'TypeSegment' && path[1]._tag === 'FieldSegment'
|
160
190
|
}
|
161
191
|
|
162
192
|
/**
|
163
193
|
* Type guard to check if a path is an argument definition path
|
164
|
-
*
|
165
|
-
* @param path - The path to check
|
166
|
-
* @returns True if the path is an argument definition path
|
167
194
|
*/
|
168
195
|
export const isArgumentDefinitionPath = (path: DefinitionPath): path is ArgumentDefinitionPath => {
|
169
|
-
return
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
* @param type - The type name
|
176
|
-
* @returns A type definition path
|
177
|
-
* @example createTypeDefinitionPath('User') // [{ kind: 'type', type: 'User' }]
|
178
|
-
*/
|
179
|
-
export const createTypeDefinitionPath = (type: string): TypeDefinitionPath => {
|
180
|
-
return [createTypeSegment(type)]
|
181
|
-
}
|
182
|
-
|
183
|
-
/**
|
184
|
-
* Create a path to a field definition
|
185
|
-
*
|
186
|
-
* @param type - The type name
|
187
|
-
* @param field - The field name
|
188
|
-
* @returns A field definition path
|
189
|
-
* @example createFieldDefinitionPath('User', 'name') // [{ kind: 'type', type: 'User' }, { kind: 'field', field: 'name' }]
|
190
|
-
*/
|
191
|
-
export const createFieldDefinitionPath = (type: string, field: string): FieldDefinitionPath => {
|
192
|
-
return [createTypeSegment(type), createFieldSegment(field)]
|
196
|
+
return (
|
197
|
+
path.length === 3
|
198
|
+
&& path[0]._tag === 'TypeSegment'
|
199
|
+
&& path[1]._tag === 'FieldSegment'
|
200
|
+
&& path[2]._tag === 'ArgumentSegment'
|
201
|
+
)
|
193
202
|
}
|
194
203
|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
* @param type - The type name
|
199
|
-
* @param field - The field name
|
200
|
-
* @param argument - The argument name
|
201
|
-
* @returns An argument definition path
|
202
|
-
* @example createArgumentDefinitionPath('User', 'posts', 'limit') // [{ kind: 'type', type: 'User' }, { kind: 'field', field: 'posts' }, { kind: 'argument', argument: 'limit' }]
|
203
|
-
*/
|
204
|
-
export const createArgumentDefinitionPath = (
|
205
|
-
type: string,
|
206
|
-
field: string,
|
207
|
-
argument: string,
|
208
|
-
): ArgumentDefinitionPath => {
|
209
|
-
return [createTypeSegment(type), createFieldSegment(field), createArgumentSegment(argument)]
|
210
|
-
}
|
204
|
+
// ============================================================================
|
205
|
+
// Constructor Functions
|
206
|
+
// ============================================================================
|
211
207
|
|
212
208
|
/**
|
213
209
|
* Create a type definition path
|
214
|
-
*
|
215
210
|
* @param type - The type name
|
216
211
|
* @returns A type definition path
|
217
|
-
* @example type('User') // [{ kind: 'type', type: 'User' }]
|
218
212
|
*/
|
219
|
-
export const type =
|
213
|
+
export const type = (typeName: string): TypeDefinitionPath => {
|
214
|
+
return [TypeSegment.make({ type: typeName })]
|
215
|
+
}
|
220
216
|
|
221
217
|
/**
|
222
218
|
* Create a field definition path
|
223
|
-
*
|
224
219
|
* @param type - The type name
|
225
220
|
* @param field - The field name
|
226
221
|
* @returns A field definition path
|
227
|
-
* @example field('User', 'name') // [{ kind: 'type', type: 'User' }, { kind: 'field', field: 'name' }]
|
228
222
|
*/
|
229
|
-
export const field =
|
223
|
+
export const field = (typeName: string, fieldName: string): FieldDefinitionPath => {
|
224
|
+
return [TypeSegment.make({ type: typeName }), FieldSegment.make({ field: fieldName })]
|
225
|
+
}
|
230
226
|
|
231
227
|
/**
|
232
228
|
* Create an argument definition path
|
233
|
-
*
|
234
229
|
* @param type - The type name
|
235
230
|
* @param field - The field name
|
236
231
|
* @param argument - The argument name
|
237
232
|
* @returns An argument definition path
|
238
|
-
* @example argument('User', 'posts', 'limit') // [{ kind: 'type', type: 'User' }, { kind: 'field', field: 'posts' }, { kind: 'argument', argument: 'limit' }]
|
239
233
|
*/
|
240
|
-
export const argument =
|
234
|
+
export const argument = (typeName: string, fieldName: string, argumentName: string): ArgumentDefinitionPath => {
|
235
|
+
return [
|
236
|
+
TypeSegment.make({ type: typeName }),
|
237
|
+
FieldSegment.make({ field: fieldName }),
|
238
|
+
ArgumentSegment.make({ argument: argumentName }),
|
239
|
+
]
|
240
|
+
}
|
@@ -2,117 +2,34 @@
|
|
2
2
|
* Query path operations
|
3
3
|
*/
|
4
4
|
|
5
|
-
import {
|
6
|
-
import
|
7
|
-
|
8
|
-
/**
|
9
|
-
* Builder class for creating query paths with a fluent interface
|
10
|
-
*
|
11
|
-
* @example
|
12
|
-
* ```ts
|
13
|
-
* const path = builder()
|
14
|
-
* .type('User')
|
15
|
-
* .field('posts')
|
16
|
-
* .type('Post')
|
17
|
-
* .field('author')
|
18
|
-
* .build()
|
19
|
-
* ```
|
20
|
-
*/
|
21
|
-
export class QueryPathBuilder {
|
22
|
-
private segments: QuerySegment[] = []
|
23
|
-
|
24
|
-
/**
|
25
|
-
* Add a type segment to the path
|
26
|
-
*
|
27
|
-
* @param typeName - The type name
|
28
|
-
* @returns The builder for chaining
|
29
|
-
*/
|
30
|
-
type(typeName: string): this {
|
31
|
-
this.segments.push(createTypeSegment(typeName))
|
32
|
-
return this
|
33
|
-
}
|
34
|
-
|
35
|
-
/**
|
36
|
-
* Add a field segment to the path
|
37
|
-
*
|
38
|
-
* @param fieldName - The field name
|
39
|
-
* @returns The builder for chaining
|
40
|
-
*/
|
41
|
-
field(fieldName: string): this {
|
42
|
-
this.segments.push(createFieldSegment(fieldName))
|
43
|
-
return this
|
44
|
-
}
|
45
|
-
|
46
|
-
/**
|
47
|
-
* Build the final query path
|
48
|
-
*
|
49
|
-
* @returns The constructed query path
|
50
|
-
*/
|
51
|
-
build(): QueryPath {
|
52
|
-
return this.segments
|
53
|
-
}
|
54
|
-
}
|
55
|
-
|
56
|
-
/**
|
57
|
-
* Create a new query path builder
|
58
|
-
*
|
59
|
-
* @returns A new query path builder instance
|
60
|
-
* @example
|
61
|
-
* ```ts
|
62
|
-
* const path = builder()
|
63
|
-
* .type('User')
|
64
|
-
* .field('posts')
|
65
|
-
* .type('Post')
|
66
|
-
* .field('author')
|
67
|
-
* .build()
|
68
|
-
* ```
|
69
|
-
*/
|
70
|
-
export const builder = (): QueryPathBuilder => new QueryPathBuilder()
|
5
|
+
import { S } from '#lib/kit-temp/effect'
|
6
|
+
import { QueryPath } from './types.js'
|
71
7
|
|
72
8
|
/**
|
73
9
|
* Encode a query path to a human-readable expression string
|
10
|
+
* Uses the Effect Schema codec for QueryPath
|
74
11
|
*
|
75
|
-
* @param path - The query path to encode
|
12
|
+
* @param path - The query path segments to encode
|
76
13
|
* @returns A string expression representation
|
77
14
|
* @example
|
78
|
-
* encode(
|
15
|
+
* encode([
|
16
|
+
* { _tag: 'TypeSegment', type: 'User' },
|
17
|
+
* { _tag: 'FieldSegment', field: 'posts' },
|
18
|
+
* { _tag: 'TypeSegment', type: 'Post' },
|
19
|
+
* { _tag: 'FieldSegment', field: 'title' }
|
20
|
+
* ]) // 'User.posts.Post.title'
|
79
21
|
*/
|
80
|
-
export const encode = (
|
81
|
-
return path.map(segment => {
|
82
|
-
if (segment.kind === 'type') return segment.type
|
83
|
-
if (segment.kind === 'field') return segment.field
|
84
|
-
return ''
|
85
|
-
}).filter(Boolean).join('.')
|
86
|
-
}
|
22
|
+
export const encode = S.encodeSync(QueryPath)
|
87
23
|
|
88
24
|
/**
|
89
25
|
* Decode a string expression into a query path
|
26
|
+
* Uses the Effect Schema codec for QueryPath
|
90
27
|
* Note: This assumes alternating type.field.type.field pattern
|
91
28
|
*
|
92
29
|
* @param expression - The string expression to decode
|
93
|
-
* @returns The decoded query path
|
30
|
+
* @returns The decoded query path segments
|
31
|
+
* @throws ParseError if the expression is invalid
|
94
32
|
* @example
|
95
33
|
* decode('User.posts.Post.title') // Query path traversing User->posts->Post->title
|
96
34
|
*/
|
97
|
-
export const decode = (
|
98
|
-
if (!expression) return null
|
99
|
-
|
100
|
-
const parts = expression.split('.')
|
101
|
-
const segments: QuerySegment[] = []
|
102
|
-
|
103
|
-
// Assume alternating pattern: type.field.type.field...
|
104
|
-
for (let i = 0; i < parts.length; i++) {
|
105
|
-
const part = parts[i]
|
106
|
-
if (!part) continue
|
107
|
-
|
108
|
-
if (i % 2 === 0) {
|
109
|
-
// Even indices are types
|
110
|
-
segments.push(createTypeSegment(part))
|
111
|
-
} else {
|
112
|
-
// Odd indices are fields
|
113
|
-
segments.push(createFieldSegment(part))
|
114
|
-
}
|
115
|
-
}
|
116
|
-
|
117
|
-
return segments
|
118
|
-
}
|
35
|
+
export const decode = S.decodeUnknownSync(QueryPath)
|
@@ -0,0 +1,136 @@
|
|
1
|
+
/**
|
2
|
+
* GraphQL schema location utilities for definition paths
|
3
|
+
*/
|
4
|
+
|
5
|
+
import { Grafaid } from '#lib/grafaid'
|
6
|
+
import { Data, Either, Match } from 'effect'
|
7
|
+
import * as Definition from './definition.js'
|
8
|
+
|
9
|
+
// ============================================================================
|
10
|
+
// Errors
|
11
|
+
// ============================================================================
|
12
|
+
|
13
|
+
export class TypeNotFoundError extends Data.TaggedError('TypeNotFoundError')<{
|
14
|
+
typeName: string
|
15
|
+
path: string
|
16
|
+
}> {}
|
17
|
+
|
18
|
+
export class FieldNotFoundError extends Data.TaggedError('FieldNotFoundError')<{
|
19
|
+
typeName: string
|
20
|
+
fieldName: string
|
21
|
+
path: string
|
22
|
+
}> {}
|
23
|
+
|
24
|
+
// ============================================================================
|
25
|
+
// Locate Functions
|
26
|
+
// ============================================================================
|
27
|
+
|
28
|
+
/**
|
29
|
+
* Locate a type in the GraphQL schema from a type definition path.
|
30
|
+
*
|
31
|
+
* @param schema - The GraphQL schema
|
32
|
+
* @param path - The type definition path
|
33
|
+
* @returns Either the located type or a TypeNotFoundError
|
34
|
+
*/
|
35
|
+
export const locateType = (
|
36
|
+
schema: Grafaid.Schema.Schema,
|
37
|
+
path: Definition.TypeDefinitionPath,
|
38
|
+
): Either.Either<Grafaid.Schema.TypesLike.Named, TypeNotFoundError> => {
|
39
|
+
const typeName = Definition.getType(path)
|
40
|
+
const type = schema.getType(typeName)
|
41
|
+
if (!type) {
|
42
|
+
return Either.left(
|
43
|
+
new TypeNotFoundError({
|
44
|
+
typeName,
|
45
|
+
path: Definition.encodeSync(path),
|
46
|
+
}),
|
47
|
+
)
|
48
|
+
}
|
49
|
+
return Either.right(type)
|
50
|
+
}
|
51
|
+
|
52
|
+
/**
|
53
|
+
* Locate a field in the GraphQL schema from a field definition path.
|
54
|
+
*
|
55
|
+
* @param schema - The GraphQL schema
|
56
|
+
* @param path - The field definition path
|
57
|
+
* @returns Either the located field or a FieldNotFoundError
|
58
|
+
*/
|
59
|
+
export const locateField = (
|
60
|
+
schema: Grafaid.Schema.Schema,
|
61
|
+
path: Definition.FieldDefinitionPath,
|
62
|
+
): Either.Either<Grafaid.Schema.NodesLike.Field, FieldNotFoundError> => {
|
63
|
+
const typeName = Definition.getType(path)
|
64
|
+
const fieldName = Definition.getField(path)
|
65
|
+
|
66
|
+
const type = schema.getType(typeName)
|
67
|
+
if (!type) {
|
68
|
+
return Either.left(
|
69
|
+
new FieldNotFoundError({
|
70
|
+
typeName,
|
71
|
+
fieldName,
|
72
|
+
path: Definition.encodeSync(path),
|
73
|
+
}),
|
74
|
+
)
|
75
|
+
}
|
76
|
+
|
77
|
+
if (!Grafaid.Schema.TypesLike.isFielded(type)) {
|
78
|
+
return Either.left(
|
79
|
+
new FieldNotFoundError({
|
80
|
+
typeName,
|
81
|
+
fieldName,
|
82
|
+
path: Definition.encodeSync(path),
|
83
|
+
}),
|
84
|
+
)
|
85
|
+
}
|
86
|
+
|
87
|
+
const fields = type.getFields()
|
88
|
+
const field = fields[fieldName]
|
89
|
+
|
90
|
+
if (!field) {
|
91
|
+
// dprint-ignore
|
92
|
+
return Either.left(new FieldNotFoundError({
|
93
|
+
typeName,
|
94
|
+
fieldName,
|
95
|
+
path: Definition.encodeSync(path),
|
96
|
+
}))
|
97
|
+
}
|
98
|
+
|
99
|
+
return Either.right(field)
|
100
|
+
}
|
101
|
+
|
102
|
+
/**
|
103
|
+
* Locate a type or field in the GraphQL schema from a definition path.
|
104
|
+
*
|
105
|
+
* @param schema - The GraphQL schema
|
106
|
+
* @param path - The definition path (type or field)
|
107
|
+
* @returns Either the located type/field or an error
|
108
|
+
*/
|
109
|
+
export const locate = (
|
110
|
+
schema: Grafaid.Schema.Schema,
|
111
|
+
path: Definition.DefinitionPath,
|
112
|
+
): Either.Either<
|
113
|
+
Grafaid.Schema.TypesLike.Named | Grafaid.Schema.NodesLike.Field,
|
114
|
+
TypeNotFoundError | FieldNotFoundError
|
115
|
+
> => {
|
116
|
+
return Match.value(path).pipe(
|
117
|
+
Match.when(
|
118
|
+
Definition.isTypeDefinitionPath,
|
119
|
+
(p) => locateType(schema, p),
|
120
|
+
),
|
121
|
+
Match.when(
|
122
|
+
Definition.isFieldDefinitionPath,
|
123
|
+
(p) => locateField(schema, p),
|
124
|
+
),
|
125
|
+
Match.orElse(() => {
|
126
|
+
// This should never happen with proper path types
|
127
|
+
// Return a generic error for unsupported path types
|
128
|
+
return Either.left(
|
129
|
+
new TypeNotFoundError({
|
130
|
+
typeName: 'unknown',
|
131
|
+
path: Definition.encodeSync(path),
|
132
|
+
}),
|
133
|
+
)
|
134
|
+
}),
|
135
|
+
)
|
136
|
+
}
|