@gqlkit-ts/cli 0.2.0 → 0.3.0

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.
Files changed (190) hide show
  1. package/dist/auto-type-generator/auto-type-generator.d.ts +10 -4
  2. package/dist/auto-type-generator/auto-type-generator.d.ts.map +1 -1
  3. package/dist/auto-type-generator/auto-type-generator.js +640 -133
  4. package/dist/auto-type-generator/auto-type-generator.js.map +1 -1
  5. package/dist/auto-type-generator/index.d.ts +8 -1
  6. package/dist/auto-type-generator/index.d.ts.map +1 -1
  7. package/dist/auto-type-generator/index.js +3 -0
  8. package/dist/auto-type-generator/index.js.map +1 -1
  9. package/dist/auto-type-generator/inline-enum-collector.d.ts +13 -5
  10. package/dist/auto-type-generator/inline-enum-collector.d.ts.map +1 -1
  11. package/dist/auto-type-generator/inline-enum-collector.js +107 -71
  12. package/dist/auto-type-generator/inline-enum-collector.js.map +1 -1
  13. package/dist/auto-type-generator/inline-object-traverser.d.ts +20 -0
  14. package/dist/auto-type-generator/inline-object-traverser.d.ts.map +1 -0
  15. package/dist/auto-type-generator/inline-object-traverser.js +22 -0
  16. package/dist/auto-type-generator/inline-object-traverser.js.map +1 -0
  17. package/dist/auto-type-generator/inline-union-collector.d.ts +29 -0
  18. package/dist/auto-type-generator/inline-union-collector.d.ts.map +1 -0
  19. package/dist/auto-type-generator/inline-union-collector.js +216 -0
  20. package/dist/auto-type-generator/inline-union-collector.js.map +1 -0
  21. package/dist/auto-type-generator/inline-union-types.d.ts +29 -0
  22. package/dist/auto-type-generator/inline-union-types.d.ts.map +1 -0
  23. package/dist/auto-type-generator/inline-union-types.js +2 -0
  24. package/dist/auto-type-generator/inline-union-types.js.map +1 -0
  25. package/dist/auto-type-generator/inline-union-validator.d.ts +76 -0
  26. package/dist/auto-type-generator/inline-union-validator.d.ts.map +1 -0
  27. package/dist/auto-type-generator/inline-union-validator.js +329 -0
  28. package/dist/auto-type-generator/inline-union-validator.js.map +1 -0
  29. package/dist/auto-type-generator/naming-convention.d.ts +18 -1
  30. package/dist/auto-type-generator/naming-convention.d.ts.map +1 -1
  31. package/dist/auto-type-generator/naming-convention.js +16 -0
  32. package/dist/auto-type-generator/naming-convention.js.map +1 -1
  33. package/dist/auto-type-generator/resolve-type-generator.d.ts +20 -0
  34. package/dist/auto-type-generator/resolve-type-generator.d.ts.map +1 -0
  35. package/dist/auto-type-generator/resolve-type-generator.js +2 -0
  36. package/dist/auto-type-generator/resolve-type-generator.js.map +1 -0
  37. package/dist/auto-type-generator/resolver-field-iterator.d.ts +13 -0
  38. package/dist/auto-type-generator/resolver-field-iterator.d.ts.map +1 -0
  39. package/dist/auto-type-generator/resolver-field-iterator.js +22 -0
  40. package/dist/auto-type-generator/resolver-field-iterator.js.map +1 -0
  41. package/dist/auto-type-generator/typename-extractor.d.ts +26 -0
  42. package/dist/auto-type-generator/typename-extractor.d.ts.map +1 -0
  43. package/dist/auto-type-generator/typename-extractor.js +142 -0
  44. package/dist/auto-type-generator/typename-extractor.js.map +1 -0
  45. package/dist/auto-type-generator/typename-resolve-type-generator.d.ts +35 -0
  46. package/dist/auto-type-generator/typename-resolve-type-generator.d.ts.map +1 -0
  47. package/dist/auto-type-generator/typename-resolve-type-generator.js +177 -0
  48. package/dist/auto-type-generator/typename-resolve-type-generator.js.map +1 -0
  49. package/dist/auto-type-generator/typename-types.d.ts +43 -0
  50. package/dist/auto-type-generator/typename-types.d.ts.map +1 -0
  51. package/dist/auto-type-generator/typename-types.js +37 -0
  52. package/dist/auto-type-generator/typename-types.js.map +1 -0
  53. package/dist/auto-type-generator/typename-validator.d.ts +37 -0
  54. package/dist/auto-type-generator/typename-validator.d.ts.map +1 -0
  55. package/dist/auto-type-generator/typename-validator.js +206 -0
  56. package/dist/auto-type-generator/typename-validator.js.map +1 -0
  57. package/dist/cli.js +2 -0
  58. package/dist/cli.js.map +1 -1
  59. package/dist/commands/docs.d.ts +51 -0
  60. package/dist/commands/docs.d.ts.map +1 -0
  61. package/dist/commands/docs.js +154 -0
  62. package/dist/commands/docs.js.map +1 -0
  63. package/dist/gen-orchestrator/orchestrator.d.ts.map +1 -1
  64. package/dist/gen-orchestrator/orchestrator.js +13 -6
  65. package/dist/gen-orchestrator/orchestrator.js.map +1 -1
  66. package/dist/resolver-extractor/extract-resolvers.d.ts +19 -1
  67. package/dist/resolver-extractor/extract-resolvers.d.ts.map +1 -1
  68. package/dist/resolver-extractor/extractor/define-api-extractor.d.ts +5 -0
  69. package/dist/resolver-extractor/extractor/define-api-extractor.d.ts.map +1 -1
  70. package/dist/resolver-extractor/extractor/define-api-extractor.js +14 -61
  71. package/dist/resolver-extractor/extractor/define-api-extractor.js.map +1 -1
  72. package/dist/resolver-extractor/index.d.ts +0 -1
  73. package/dist/resolver-extractor/index.d.ts.map +1 -1
  74. package/dist/resolver-extractor/validator/abstract-resolver-validator.d.ts +1 -0
  75. package/dist/resolver-extractor/validator/abstract-resolver-validator.d.ts.map +1 -1
  76. package/dist/resolver-extractor/validator/abstract-resolver-validator.js +9 -5
  77. package/dist/resolver-extractor/validator/abstract-resolver-validator.js.map +1 -1
  78. package/dist/schema-generator/emitter/code-emitter.d.ts.map +1 -1
  79. package/dist/schema-generator/emitter/code-emitter.js +20 -0
  80. package/dist/schema-generator/emitter/code-emitter.js.map +1 -1
  81. package/dist/schema-generator/generate-schema.d.ts +1 -0
  82. package/dist/schema-generator/generate-schema.d.ts.map +1 -1
  83. package/dist/schema-generator/generate-schema.js +72 -3
  84. package/dist/schema-generator/generate-schema.js.map +1 -1
  85. package/dist/schema-generator/integrator/result-integrator.d.ts +14 -2
  86. package/dist/schema-generator/integrator/result-integrator.d.ts.map +1 -1
  87. package/dist/schema-generator/integrator/result-integrator.js +54 -1
  88. package/dist/schema-generator/integrator/result-integrator.js.map +1 -1
  89. package/dist/schema-generator/resolver-collector/resolver-collector.d.ts +2 -0
  90. package/dist/schema-generator/resolver-collector/resolver-collector.d.ts.map +1 -1
  91. package/dist/schema-generator/resolver-collector/resolver-collector.js +22 -0
  92. package/dist/schema-generator/resolver-collector/resolver-collector.js.map +1 -1
  93. package/dist/shared/enum-prefix-detector.d.ts +63 -0
  94. package/dist/shared/enum-prefix-detector.d.ts.map +1 -0
  95. package/dist/shared/enum-prefix-detector.js +80 -0
  96. package/dist/shared/enum-prefix-detector.js.map +1 -0
  97. package/dist/shared/ignore-fields-detector.d.ts +26 -0
  98. package/dist/shared/ignore-fields-detector.d.ts.map +1 -0
  99. package/dist/shared/ignore-fields-detector.js +83 -0
  100. package/dist/shared/ignore-fields-detector.js.map +1 -0
  101. package/dist/shared/ignore-fields-validator.d.ts +29 -0
  102. package/dist/shared/ignore-fields-validator.d.ts.map +1 -0
  103. package/dist/shared/ignore-fields-validator.js +43 -0
  104. package/dist/shared/ignore-fields-validator.js.map +1 -0
  105. package/dist/shared/index.d.ts +2 -0
  106. package/dist/shared/index.d.ts.map +1 -1
  107. package/dist/shared/index.js.map +1 -1
  108. package/dist/shared/source-location.d.ts +5 -0
  109. package/dist/shared/source-location.d.ts.map +1 -1
  110. package/dist/shared/source-location.js +7 -0
  111. package/dist/shared/source-location.js.map +1 -1
  112. package/dist/type-extractor/converter/graphql-converter.d.ts.map +1 -1
  113. package/dist/type-extractor/converter/graphql-converter.js +21 -7
  114. package/dist/type-extractor/converter/graphql-converter.js.map +1 -1
  115. package/dist/type-extractor/extractor/field-type-resolver.js +42 -3
  116. package/dist/type-extractor/extractor/field-type-resolver.js.map +1 -1
  117. package/dist/type-extractor/extractor/type-extractor.d.ts.map +1 -1
  118. package/dist/type-extractor/extractor/type-extractor.js +88 -23
  119. package/dist/type-extractor/extractor/type-extractor.js.map +1 -1
  120. package/dist/type-extractor/types/diagnostics.d.ts +1 -1
  121. package/dist/type-extractor/types/diagnostics.d.ts.map +1 -1
  122. package/dist/type-extractor/types/ts-type-reference-factory.d.ts +10 -2
  123. package/dist/type-extractor/types/ts-type-reference-factory.d.ts.map +1 -1
  124. package/dist/type-extractor/types/ts-type-reference-factory.js +8 -2
  125. package/dist/type-extractor/types/ts-type-reference-factory.js.map +1 -1
  126. package/dist/type-extractor/types/typescript.d.ts +4 -0
  127. package/dist/type-extractor/types/typescript.d.ts.map +1 -1
  128. package/docs/coding-agents.md +64 -0
  129. package/docs/configuration.md +6 -20
  130. package/docs/getting-started.md +15 -12
  131. package/docs/index.md +36 -22
  132. package/docs/integration/apollo.md +8 -40
  133. package/docs/integration/drizzle.md +6 -10
  134. package/docs/integration/prisma.md +196 -0
  135. package/docs/integration/yoga.md +8 -40
  136. package/docs/schema/abstract-resolvers.md +117 -0
  137. package/docs/schema/directives.md +5 -0
  138. package/docs/schema/documentation.md +5 -0
  139. package/docs/schema/enums.md +99 -0
  140. package/docs/schema/fields.md +64 -0
  141. package/docs/schema/index.md +21 -0
  142. package/docs/schema/inputs.md +115 -15
  143. package/docs/schema/interfaces.md +31 -1
  144. package/docs/schema/objects.md +40 -0
  145. package/docs/schema/queries-mutations.md +136 -22
  146. package/docs/schema/scalars.md +5 -0
  147. package/docs/schema/unions.md +208 -1
  148. package/docs/what-is-gqlkit.md +13 -8
  149. package/package.json +6 -4
  150. package/src/auto-type-generator/auto-type-generator.ts +946 -201
  151. package/src/auto-type-generator/index.ts +42 -0
  152. package/src/auto-type-generator/inline-enum-collector.ts +187 -139
  153. package/src/auto-type-generator/inline-object-traverser.ts +49 -0
  154. package/src/auto-type-generator/inline-union-collector.ts +402 -0
  155. package/src/auto-type-generator/inline-union-types.ts +33 -0
  156. package/src/auto-type-generator/inline-union-validator.ts +482 -0
  157. package/src/auto-type-generator/naming-convention.ts +38 -1
  158. package/src/auto-type-generator/resolve-type-generator.ts +21 -0
  159. package/src/auto-type-generator/resolver-field-iterator.ts +39 -0
  160. package/src/auto-type-generator/typename-extractor.ts +230 -0
  161. package/src/auto-type-generator/typename-resolve-type-generator.ts +281 -0
  162. package/src/auto-type-generator/typename-types.ts +66 -0
  163. package/src/auto-type-generator/typename-validator.ts +326 -0
  164. package/src/cli.ts +2 -0
  165. package/src/commands/docs.ts +211 -0
  166. package/src/gen-orchestrator/orchestrator.ts +20 -6
  167. package/src/resolver-extractor/extract-resolvers.ts +19 -0
  168. package/src/resolver-extractor/extractor/define-api-extractor.ts +23 -89
  169. package/src/resolver-extractor/index.ts +0 -6
  170. package/src/resolver-extractor/validator/abstract-resolver-validator.ts +16 -8
  171. package/src/schema-generator/emitter/code-emitter.ts +34 -0
  172. package/src/schema-generator/generate-schema.ts +99 -2
  173. package/src/schema-generator/integrator/result-integrator.ts +70 -1
  174. package/src/schema-generator/resolver-collector/resolver-collector.ts +34 -0
  175. package/src/shared/enum-prefix-detector.ts +99 -0
  176. package/src/shared/ignore-fields-detector.ts +109 -0
  177. package/src/shared/ignore-fields-validator.ts +66 -0
  178. package/src/shared/index.ts +2 -0
  179. package/src/shared/source-location.ts +11 -0
  180. package/src/type-extractor/converter/graphql-converter.ts +31 -7
  181. package/src/type-extractor/extractor/field-type-resolver.ts +48 -3
  182. package/src/type-extractor/extractor/type-extractor.ts +103 -26
  183. package/src/type-extractor/types/diagnostics.ts +12 -2
  184. package/src/type-extractor/types/ts-type-reference-factory.ts +18 -5
  185. package/src/type-extractor/types/typescript.ts +4 -0
  186. package/dist/resolver-extractor/validator/only-validator.d.ts +0 -61
  187. package/dist/resolver-extractor/validator/only-validator.d.ts.map +0 -1
  188. package/dist/resolver-extractor/validator/only-validator.js +0 -76
  189. package/dist/resolver-extractor/validator/only-validator.js.map +0 -1
  190. package/src/resolver-extractor/validator/only-validator.ts +0 -158
@@ -1,3 +1,8 @@
1
+ ---
2
+ title: Defining Union Types
3
+ description: TypeScript union types of object types are converted to GraphQL union types.
4
+ ---
5
+
1
6
  # Union Types
2
7
 
3
8
  TypeScript union types of object types are converted to GraphQL union types.
@@ -42,6 +47,100 @@ type Query {
42
47
  }
43
48
  ```
44
49
 
50
+ ## Inline Unions
51
+
52
+ When a field type is an inline union of object types, gqlkit automatically generates a GraphQL Union type. The generated type name follows the convention `{ParentTypeName}{PascalCaseFieldName}`:
53
+
54
+ ```typescript
55
+ import type { User } from "./User";
56
+ import type { Post } from "./Post";
57
+
58
+ export type SearchResult = {
59
+ id: string;
60
+ /**
61
+ * The matched item - either a User or a Post
62
+ */
63
+ item: User | Post;
64
+ };
65
+ ```
66
+
67
+ Generates:
68
+
69
+ ```graphql
70
+ type SearchResult {
71
+ id: String!
72
+ """The matched item - either a User or a Post"""
73
+ item: SearchResultItem!
74
+ }
75
+
76
+ union SearchResultItem = Post | User
77
+ ```
78
+
79
+ ### Nullable Inline Unions
80
+
81
+ Inline unions can be nullable:
82
+
83
+ ```typescript
84
+ export type Container = {
85
+ id: string;
86
+ result: User | Post | null;
87
+ };
88
+ ```
89
+
90
+ Generates:
91
+
92
+ ```graphql
93
+ type Container {
94
+ id: String!
95
+ result: ContainerResult
96
+ }
97
+
98
+ union ContainerResult = Post | User
99
+ ```
100
+
101
+ ### Known Type References
102
+
103
+ When union members are exported types in the schema directory (`knownTypeNames`), they are preserved as references. Unknown inline object types are automatically generated:
104
+
105
+ ```typescript
106
+ import type { User } from "./User"; // known type
107
+
108
+ export type Activity = {
109
+ actor: User | { id: string; type: string }; // User is referenced, anonymous object is generated
110
+ };
111
+ ```
112
+
113
+ Generates:
114
+
115
+ ```graphql
116
+ type Activity {
117
+ actor: ActivityActor!
118
+ }
119
+
120
+ union ActivityActor = ActivityActorAnonymous | User
121
+
122
+ type ActivityActorAnonymous {
123
+ id: String!
124
+ type: String!
125
+ }
126
+ ```
127
+
128
+ ### Validation
129
+
130
+ Inline unions in output context must contain only object types. The following are not allowed:
131
+
132
+ - Primitive types (string, number, boolean)
133
+ - Enum types
134
+ - Scalar types
135
+
136
+ ```typescript
137
+ // These will produce errors:
138
+ export type Invalid = {
139
+ value: string | number; // Error: primitives not allowed
140
+ status: User | "active"; // Error: cannot mix object and enum
141
+ };
142
+ ```
143
+
45
144
  ## Union vs Enum
46
145
 
47
146
  - Use **Union** when each member is a distinct object type with different fields
@@ -72,9 +171,117 @@ export type Node = GqlInterface<{
72
171
 
73
172
  See [Interfaces](./interfaces.md) for more details on interface types.
74
173
 
174
+ ## Inline Union Payloads
175
+
176
+ When a resolver return type is an inline union with object literals, gqlkit generates a GraphQL Union type. Each union member must have a `__typename` property with a string literal type:
177
+
178
+ ```typescript
179
+ export const updateUser = defineMutation<
180
+ { input: UpdateUserInput },
181
+ | { __typename: "UpdateUserSuccess"; user: User }
182
+ | { __typename: "UpdateUserError"; message: string }
183
+ >(/* ... */);
184
+ ```
185
+
186
+ Generates:
187
+
188
+ ```graphql
189
+ type Mutation {
190
+ updateUser(input: UpdateUserInput!): UpdateUserPayload!
191
+ }
192
+
193
+ union UpdateUserPayload = UpdateUserError | UpdateUserSuccess
194
+
195
+ type UpdateUserSuccess {
196
+ user: User!
197
+ }
198
+
199
+ type UpdateUserError {
200
+ message: String!
201
+ }
202
+ ```
203
+
204
+ ### `__typename` Requirement
205
+
206
+ For inline union payloads, the `__typename` property is required and must be a string literal type:
207
+
208
+ ```typescript
209
+ // ✅ OK: __typename with string literal type
210
+ type Result =
211
+ | { __typename: "Success"; data: string }
212
+ | { __typename: "Error"; message: string };
213
+
214
+ // ❌ Error: __typename missing
215
+ type Invalid =
216
+ | { data: string }
217
+ | { message: string };
218
+
219
+ // ❌ Error: __typename is not a string literal
220
+ type AlsoInvalid =
221
+ | { __typename: string; data: string }
222
+ | { __typename: string; message: string };
223
+ ```
224
+
225
+ ### Automatic `__resolveType` Generation
226
+
227
+ For inline union payloads, gqlkit automatically generates a `__resolveType` function that returns the `__typename` property value. You don't need to define it manually.
228
+
229
+ If you need custom type resolution logic, use [defineResolveType](./abstract-resolvers.md#defineresolveType).
230
+
231
+ ### Mixed Union Payloads
232
+
233
+ You can mix inline object literals with named types. Only inline objects require `__typename`:
234
+
235
+ ```typescript
236
+ import type { User } from "./user";
237
+
238
+ export const findEntity = defineQuery<
239
+ { id: string },
240
+ | User // named type - __typename determined by type
241
+ | { __typename: "Guest"; sessionId: string } // inline type - __typename required
242
+ >(/* ... */);
243
+ ```
244
+
245
+ Generates:
246
+
247
+ ```graphql
248
+ union FindEntityPayload = Guest | User
249
+
250
+ type Guest {
251
+ sessionId: String!
252
+ }
253
+ ```
254
+
255
+ See [Queries & Mutations](./queries-mutations.md#inline-payload-types) for more details on inline payload types.
256
+
75
257
  ## Runtime Type Resolution
76
258
 
77
- When GraphQL executes a query that returns a union type, it needs to determine the concrete type at runtime. Use `defineResolveType` to handle this:
259
+ When GraphQL executes a query that returns a union type, it needs to determine the concrete type at runtime.
260
+
261
+ ### Automatic Resolution
262
+
263
+ If your union member types have `__typename` or `$typeName` fields with string literal values, gqlkit automatically generates the `resolveType` function:
264
+
265
+ ```typescript
266
+ export interface User {
267
+ __typename: "User";
268
+ id: string;
269
+ name: string;
270
+ }
271
+
272
+ export interface Post {
273
+ __typename: "Post";
274
+ id: string;
275
+ title: string;
276
+ }
277
+
278
+ export type SearchResult = User | Post;
279
+ // resolveType is automatically generated - no manual definition needed
280
+ ```
281
+
282
+ ### Manual Resolution
283
+
284
+ For types without `__typename` or `$typeName`, use `defineResolveType`:
78
285
 
79
286
  ```typescript
80
287
  import { defineResolveType } from "../gqlkit";
@@ -1,22 +1,27 @@
1
+ ---
2
+ title: What is gqlkit?
3
+ description: Just types and functions — write TypeScript, generate GraphQL.
4
+ ---
5
+
1
6
  # What is gqlkit?
2
7
 
3
- gqlkit is a convention-driven code generator for GraphQL servers in TypeScript.
8
+ Just types and functions write TypeScript, generate GraphQL.
4
9
 
5
10
  ## Core Concept
6
11
 
7
- Define GraphQL types and resolver signatures in TypeScript → `gqlkit gen` generates GraphQL schema AST and a resolver map from your codebase.
12
+ Write types and resolvers in TypeScript → run `gqlkit gen` get GraphQL schema AST and resolver map.
8
13
 
9
14
  ## Design Principles
10
15
 
11
- - **Type-First**: Define types using plain TypeScript, no decorators needed
12
- - **Fail fast with actionable errors**: Invalid resolver references, type mismatches, etc.
13
- - **No runtime schema mutation**: Pure static analysis of TypeScript code
14
- - **Deterministic**: Same code same outputs, always
15
- - **GraphQL-tools compatible**: Generated outputs work seamlessly with `makeExecutableSchema`
16
+ - **Implement first**: Write types and resolvers, generate schema when ready. No edit-regenerate-implement loops.
17
+ - **Just types and functions**: Plain TypeScript with a thin API. No complex generics, no decorators.
18
+ - **Type-safe**: TypeScript types become GraphQL types. Resolver signatures checked at compile time.
19
+ - **Fail fast with actionable errors**: Invalid resolver references, type mismatches, and convention violations.
20
+ - **GraphQL-tools compatible**: Generated outputs work seamlessly with `makeExecutableSchema`.
16
21
 
17
22
  ## How It Works
18
23
 
19
- 1. You write TypeScript types and resolvers in `src/gqlkit/schema/`
24
+ 1. Write TypeScript types and resolvers in `src/gqlkit/schema/`
20
25
  2. Run `gqlkit gen`
21
26
  3. gqlkit scans your code, builds internal type graph, and validates resolver signatures
22
27
  4. Outputs `typeDefs` (GraphQL AST) and `resolvers` map to `src/gqlkit/__generated__/`
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@gqlkit-ts/cli",
3
- "version": "0.2.0",
4
- "description": "gqlkit is a toolkit for building GraphQL servers by following simple TypeScript conventions. Write types and resolvers, and you get a complete GraphQL API — schema included.",
3
+ "version": "0.3.0",
4
+ "description": "Just types and functions write TypeScript, generate GraphQL.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "bin": {
@@ -12,6 +12,7 @@
12
12
  "docs",
13
13
  "src",
14
14
  "!**/testdata/**",
15
+ "!**/testing/**",
15
16
  "!**/*.test.ts",
16
17
  "!**/*.test.js",
17
18
  "!**/*.test.d.ts",
@@ -58,8 +59,9 @@
58
59
  },
59
60
  "devDependencies": {
60
61
  "@types/shell-quote": "1.7.5",
61
- "@gqlkit-ts/docs": "0.0.1",
62
- "@gqlkit-ts/runtime": "0.1.1"
62
+ "memfs": "4.56.10",
63
+ "@gqlkit-ts/runtime": "0.2.0",
64
+ "@gqlkit-ts/docs": "0.0.1"
63
65
  },
64
66
  "scripts": {
65
67
  "build": "tsc --build && bundle-docs --target ./docs",