@aexol/axolotl 1.0.6 → 2.0.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.
- package/README.md +1 -1
- package/lib/create/consts.d.ts +1 -1
- package/lib/create/consts.js +0 -5
- package/lib/create/consts.js.map +1 -1
- package/lib/index.js +0 -14
- package/lib/index.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/lib/codegen/ai.d.ts +0 -3
- package/lib/codegen/ai.js +0 -90
- package/lib/codegen/ai.js.map +0 -1
- package/lib/codegen/cai.d.ts +0 -3
- package/lib/codegen/cai.js +0 -64
- package/lib/codegen/cai.js.map +0 -1
- package/lib/codegen/context.d.ts +0 -2
- package/lib/codegen/context.js +0 -76
- package/lib/codegen/context.js.map +0 -1
- package/lib/codegen/frontendAi.d.ts +0 -3
- package/lib/codegen/frontendAi.js +0 -289
- package/lib/codegen/frontendAi.js.map +0 -1
- package/lib/codegen/graphqlAi.d.ts +0 -3
- package/lib/codegen/graphqlAi.js +0 -532
- package/lib/codegen/graphqlAi.js.map +0 -1
- package/lib/codegen/index.d.ts +0 -2
- package/lib/codegen/index.js +0 -10
- package/lib/codegen/index.js.map +0 -1
- package/lib/codegen/mcp.d.ts +0 -7
- package/lib/codegen/mcp.js +0 -207
- package/lib/codegen/mcp.js.map +0 -1
- package/lib/codegen/utils.d.ts +0 -3
- package/lib/codegen/utils.js +0 -87
- package/lib/codegen/utils.js.map +0 -1
package/lib/codegen/graphqlAi.js
DELETED
|
@@ -1,532 +0,0 @@
|
|
|
1
|
-
const graphqlAiPrompt = `
|
|
2
|
-
You create GraphQL Schemas. Here a rules you should use when creating the schema
|
|
3
|
-
|
|
4
|
-
1. Source of Truth:
|
|
5
|
-
|
|
6
|
-
From this single source of truth, different teams can consume and discuss this source of truth, enabling
|
|
7
|
-
them to collaboratively find the best solutions for our system. This approach allows for a more efficient
|
|
8
|
-
and streamlined development process.
|
|
9
|
-
|
|
10
|
-
Having a single source of truth also has other benefits. If we have a team member with extensive
|
|
11
|
-
business knowledge about the solution, we can teach them GraphQL and have them build the schema.
|
|
12
|
-
This way, we can be sure that the team of developers, designers, QA, and so on will perfectly reflect
|
|
13
|
-
the project requirements.
|
|
14
|
-
|
|
15
|
-
Furthermore, we can treat GraphQL as a low-code solution in this scenario. Why? A well-defined
|
|
16
|
-
schema is excellent nourishment for developers to create proper code. It’s much easier to program
|
|
17
|
-
when you have a well-built foundation. In the future, or perhaps even at the time you are reading
|
|
18
|
-
this book, there may alread
|
|
19
|
-
|
|
20
|
-
2. Standardizing the naming of types and fields:
|
|
21
|
-
|
|
22
|
-
Consistency is a crucial aspect of software development, and standardized naming conventions play
|
|
23
|
-
a vital role in achieving this within a GraphQL schema.
|
|
24
|
-
By using consistent naming conventions, we can easily understand the structure of a schema and its
|
|
25
|
-
fields. When these conventions are predictable and follow a set pattern, it becomes more intuitive
|
|
26
|
-
to navigate and comprehend the schema, creating a unified and cohesive appearance, and reducing
|
|
27
|
-
confusion and potential errors.
|
|
28
|
-
This is particularly important in a collaborative environment, where multiple people may be working
|
|
29
|
-
on the same GraphQL schema. This is because inconsistent naming conventions can introduce
|
|
30
|
-
unnecessary cognitive load for developers. When field names vary in style or structure, developers
|
|
31
|
-
may need to spend additional time deciphering each field’s purpose and functionality. This can slow
|
|
32
|
-
down development and increase the chances of introducing errors.
|
|
33
|
-
Standardized naming conventions eliminate this cognitive overhead and allow developers to focus
|
|
34
|
-
on the actual logic and functionality of a schema. It also means that all users are on the same page
|
|
35
|
-
and have a shared understanding of the schema’s structure, facilitating seamless collaboration and
|
|
36
|
-
reducing the learning curve for new team members joining a project.
|
|
37
|
-
|
|
38
|
-
3. Documenting types, fields, and arguments:
|
|
39
|
-
The documentation of GraphQL code includes descriptions of types, fields, arguments, and return
|
|
40
|
-
values. This allows developers to quickly understand how to correctly communicate with a schema
|
|
41
|
-
and retrieve data from it.
|
|
42
|
-
In larger projects, where multiple people work on GraphQL code, documentation serves as a central
|
|
43
|
-
knowledge hub for an entire team – it enables new team members to quickly familiarize themselves with
|
|
44
|
-
the functionality and structure of the API, as well as ensuring consistency and unified understanding.
|
|
45
|
-
|
|
46
|
-
4. Pagination
|
|
47
|
-
Using pagination
|
|
48
|
-
As a developer team, we should consider adding pagination only where necessary, critically evaluating
|
|
49
|
-
whether the standard pagination model can be replaced with another approach. It is important for us
|
|
50
|
-
to carefully assess the need for pagination in our projects and determine whether it truly enhances
|
|
51
|
-
the user experience.
|
|
52
|
-
|
|
53
|
-
The most important features of pagination are as follows:
|
|
54
|
-
|
|
55
|
-
- Reducing data transfer between the client and server
|
|
56
|
-
- Speeding up our project by faster server responses
|
|
57
|
-
- Enforcing a good communication style
|
|
58
|
-
- Reducing information overload on frontend
|
|
59
|
-
|
|
60
|
-
Example pagination
|
|
61
|
-
\`\`\`graphql
|
|
62
|
-
"""PageInfo contains information about connection page"""
|
|
63
|
-
type PageInfo {
|
|
64
|
-
"""last element in connection"""
|
|
65
|
-
last: String
|
|
66
|
-
"""limit the response size while querying"""
|
|
67
|
-
limit: Int
|
|
68
|
-
"""if next field value is false, then client received all
|
|
69
|
-
available data""""
|
|
70
|
-
next: Boolean
|
|
71
|
-
}
|
|
72
|
-
type BookConnection{
|
|
73
|
-
books: [Book!]!
|
|
74
|
-
pageInfo: PageInfo!
|
|
75
|
-
}
|
|
76
|
-
input PageInput{
|
|
77
|
-
limit: Int
|
|
78
|
-
"""
|
|
79
|
-
id of the last project returned by previous call
|
|
80
|
-
"""
|
|
81
|
-
start: Int
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
type Query {
|
|
85
|
-
getAllBooks(pagination: PageInput): BookConnection!
|
|
86
|
-
}
|
|
87
|
-
\`\`\`
|
|
88
|
-
|
|
89
|
-
Example using date for pagination:
|
|
90
|
-
\`\`\`graphql
|
|
91
|
-
scalar Date
|
|
92
|
-
|
|
93
|
-
input DateFilter{
|
|
94
|
-
start: Date!
|
|
95
|
-
end: Date
|
|
96
|
-
}
|
|
97
|
-
type Query {
|
|
98
|
-
getAllBorrowings(dateFilter: DateFilter): [BookBorrowing!]!
|
|
99
|
-
}
|
|
100
|
-
\`\`\`
|
|
101
|
-
|
|
102
|
-
5. Building pipes
|
|
103
|
-
|
|
104
|
-
In GraphQL, types serve as the building blocks of our schema, allowing us to define the structure and
|
|
105
|
-
behavior of our data. One powerful aspect of types is their ability to group schema parts by the domain
|
|
106
|
-
they represent. By organizing our schema in this way, we can achieve a clear and cohesive separation
|
|
107
|
-
of concerns, making our code base more maintainable and easier to understand.
|
|
108
|
-
Pipe patterns leverage this GraphQL structure. Usually, pipes are used to pass or stop the resolver
|
|
109
|
-
tree execution.
|
|
110
|
-
In addition to improving the overall organization of our schema, domain-specific types also enable us
|
|
111
|
-
to implement fine-grained access control. By defining specific fields and permissions for each type, we
|
|
112
|
-
can ensure that only authorized users have access to certain data or operations. This level of control is
|
|
113
|
-
particularly crucial when dealing with sensitive information or enforcing business rules.
|
|
114
|
-
When we perform operations on the root query, mutation, or subscription, it does not receive any source
|
|
115
|
-
data from another resolver. Instead, it only receives what the backend passes from the previous resolver.
|
|
116
|
-
However, things work differently for operations that are not executed at the root of the tree. We can
|
|
117
|
-
pass entire objects, and importantly, this information is not inherent to GraphQL itself. It is passed
|
|
118
|
-
during backend creation by backend developers and is visible in the framework they use.
|
|
119
|
-
|
|
120
|
-
5.1 Example Logical pipes
|
|
121
|
-
Logical pipes are only responsible for the logical grouping of operation types. This way, we are splitting
|
|
122
|
-
the schema tree into a set of smaller sub-trees.
|
|
123
|
-
By grouping schema parts based on their domain, we can easily navigate and discuss our schema structure
|
|
124
|
-
with others. This approach helps us maintain a modular and organized architecture, making it easier
|
|
125
|
-
to add or modify functionality as our application evolves. We can think of these domain-specific types
|
|
126
|
-
as containers that encapsulate related data and operations, providing a logical separation of concerns.
|
|
127
|
-
In the following example, I will present you with a system for reading information in a home that
|
|
128
|
-
utilizes Internet of Things (IoT) devices, such as individual solar-charged lights connected via Wi-Fi.
|
|
129
|
-
The division into domains will allow us to separate the specific domains that household members
|
|
130
|
-
have access to.
|
|
131
|
-
|
|
132
|
-
\`\`\`graphql
|
|
133
|
-
type YardQuery{
|
|
134
|
-
lights: [Light!]
|
|
135
|
-
gateOpen: Boolean
|
|
136
|
-
}
|
|
137
|
-
type Light{
|
|
138
|
-
id: ID!
|
|
139
|
-
on: Boolean
|
|
140
|
-
}
|
|
141
|
-
type CloudQuery{
|
|
142
|
-
photos: [Asset!]
|
|
143
|
-
videos: [Asset!]
|
|
144
|
-
}
|
|
145
|
-
type Asset{
|
|
146
|
-
id: ID!
|
|
147
|
-
url: String!
|
|
148
|
-
}
|
|
149
|
-
type HouseQuery{
|
|
150
|
-
room: RoomQuery
|
|
151
|
-
yard: YardQuery
|
|
152
|
-
cloud: CloudQuery
|
|
153
|
-
}
|
|
154
|
-
type Query{
|
|
155
|
-
house(id: ID): HouseQuery
|
|
156
|
-
}
|
|
157
|
-
\`\`\`
|
|
158
|
-
|
|
159
|
-
5.2 Access pipes
|
|
160
|
-
|
|
161
|
-
The main reason why we use access pipes is to have control over which parts of the schema are available
|
|
162
|
-
to individual groups of schema consumers. By doing this, we can see how access control will work in
|
|
163
|
-
our system even during the graph creation phase.
|
|
164
|
-
To understand access pipes, we need to understand Role-Based Access Control (RBAC). RBAC is
|
|
165
|
-
a mechanism that allows us to control access to data based on user roles. It works by assigning each
|
|
166
|
-
user a role, which determines the resources available to them. In practice, when defining a GraphQL
|
|
167
|
-
schema, we can specify roles for individual object types and fields. We can define different roles such
|
|
168
|
-
as admin, user, or guest, and assign them specific read and write permissions for data using directives
|
|
169
|
-
or we can do it with access pipes. When a user sends a GraphQL query, their role is taken into account
|
|
170
|
-
during query execution. The GraphQL backend engine checks whether the user has the necessary
|
|
171
|
-
permissions to resolve the specific type. If the user lacks the appropriate permissions, the GraphQL
|
|
172
|
-
engine returns an appropriate “access denied” message.
|
|
173
|
-
This mechanism allows us to create secure and controlled API interfaces with RBAC and access pipes
|
|
174
|
-
in GraphQL. We can ensure that only authorized individuals have access to specific types, which is
|
|
175
|
-
particularly important for applications handling sensitive information such as user data or financial data.
|
|
176
|
-
|
|
177
|
-
Now, let’s take a look at an example using the IoT scenario, but this time, we will restrict access to certain
|
|
178
|
-
resources. This example will showcase access pipes. Imagine we have a family at home, and we want to
|
|
179
|
-
restrict access to photos and videos for our children. To do this, we will split CloudQuery accordingly:
|
|
180
|
-
\`\`\`graphql
|
|
181
|
-
interface CloudQuery{
|
|
182
|
-
photos: [Asset!]
|
|
183
|
-
videos: [Asset!]
|
|
184
|
-
}
|
|
185
|
-
type KidsQuery implements CloudQuery{
|
|
186
|
-
photos: [Asset!]
|
|
187
|
-
videos: [Asset!]
|
|
188
|
-
}
|
|
189
|
-
type ParentsQuery implements CloudQuery{
|
|
190
|
-
photos: [Asset!]
|
|
191
|
-
videos: [Asset!]
|
|
192
|
-
}
|
|
193
|
-
type Query{
|
|
194
|
-
parents: ParentsQuery
|
|
195
|
-
kids: KidsQuery
|
|
196
|
-
}
|
|
197
|
-
\`\`\`
|
|
198
|
-
Instead of returning photos and videos from the resolver of the CloudQuery type directly, we
|
|
199
|
-
transformed CloudQuery into an interface and created two separate queries named KidsQuery
|
|
200
|
-
and ParentsQuery. Then, in the backend system, we will determine who is making the request by
|
|
201
|
-
parsing request headers and we won’t allow kids to enter the ParentsQuery assets.
|
|
202
|
-
|
|
203
|
-
5.3 Ownership pipes
|
|
204
|
-
It often happens that the owner of a specific entity should be the only one with the authority to edit it.
|
|
205
|
-
In such cases, the ownership pipes pattern comes in handy, allowing editing of an object exclusively
|
|
206
|
-
by its owner.
|
|
207
|
-
One of the most common use cases for ownership pipes is a blog. Here, every user of a blog is also the
|
|
208
|
-
owner of their articles, and the only one who can edit them, add a cover image, set the publication
|
|
209
|
-
date, and so on. Additionally, there are blog readers who can comment on each article, as well as edit
|
|
210
|
-
their own comments and react to other comments. Once again, ownership of these objects and actions
|
|
211
|
-
lies with the user. Furthermore, each user – whether a blog writer or commenter – has access to their
|
|
212
|
-
own profile data and can edit it.
|
|
213
|
-
Just like in the previous section, we will start here by presenting the graph of our GraphQL schema
|
|
214
|
-
for a blogging system:
|
|
215
|
-
|
|
216
|
-
\`\`\`graphql
|
|
217
|
-
"""
|
|
218
|
-
An author of articles and comments
|
|
219
|
-
"""
|
|
220
|
-
type Author {
|
|
221
|
-
"""
|
|
222
|
-
The unique identifier of the author
|
|
223
|
-
"""
|
|
224
|
-
id: ID!
|
|
225
|
-
|
|
226
|
-
"""
|
|
227
|
-
The name of the author
|
|
228
|
-
"""
|
|
229
|
-
name: String!
|
|
230
|
-
|
|
231
|
-
"""
|
|
232
|
-
The articles written by the author
|
|
233
|
-
"""
|
|
234
|
-
articles: [Article!]!
|
|
235
|
-
|
|
236
|
-
"""
|
|
237
|
-
The comments made by the author
|
|
238
|
-
"""
|
|
239
|
-
comments: [Comment!]!
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
"""
|
|
244
|
-
An article written by an author
|
|
245
|
-
"""
|
|
246
|
-
type Article {
|
|
247
|
-
"""
|
|
248
|
-
The unique identifier of the article
|
|
249
|
-
"""
|
|
250
|
-
id: ID!
|
|
251
|
-
|
|
252
|
-
"""
|
|
253
|
-
The title of the article
|
|
254
|
-
"""
|
|
255
|
-
title: String!
|
|
256
|
-
|
|
257
|
-
"""
|
|
258
|
-
The content of the article
|
|
259
|
-
"""
|
|
260
|
-
content: String!
|
|
261
|
-
|
|
262
|
-
"""
|
|
263
|
-
The author of the article
|
|
264
|
-
"""
|
|
265
|
-
author: Author!
|
|
266
|
-
|
|
267
|
-
"""
|
|
268
|
-
The comments on the article
|
|
269
|
-
"""
|
|
270
|
-
comments: [Comment!]!
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
"""
|
|
274
|
-
A comment on an article
|
|
275
|
-
"""
|
|
276
|
-
type Comment {
|
|
277
|
-
"""
|
|
278
|
-
The unique identifier of the comment
|
|
279
|
-
"""
|
|
280
|
-
id: ID!
|
|
281
|
-
|
|
282
|
-
"""
|
|
283
|
-
The content of the comment
|
|
284
|
-
"""
|
|
285
|
-
content: String!
|
|
286
|
-
|
|
287
|
-
"""
|
|
288
|
-
The author of the comment
|
|
289
|
-
"""
|
|
290
|
-
author: Author!
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
"""
|
|
294
|
-
Root query type
|
|
295
|
-
"""
|
|
296
|
-
type Query {
|
|
297
|
-
"""
|
|
298
|
-
Get all authors
|
|
299
|
-
"""
|
|
300
|
-
authors: [Author!]!
|
|
301
|
-
|
|
302
|
-
"""
|
|
303
|
-
Get an author by ID
|
|
304
|
-
"""
|
|
305
|
-
author(
|
|
306
|
-
id: ID!
|
|
307
|
-
): Author
|
|
308
|
-
|
|
309
|
-
"""
|
|
310
|
-
Get all articles
|
|
311
|
-
"""
|
|
312
|
-
articles: [Article!]!
|
|
313
|
-
|
|
314
|
-
"""
|
|
315
|
-
Get an article by ID
|
|
316
|
-
"""
|
|
317
|
-
article(
|
|
318
|
-
id: ID!
|
|
319
|
-
): Article
|
|
320
|
-
|
|
321
|
-
"""
|
|
322
|
-
Get the logged in user
|
|
323
|
-
"""
|
|
324
|
-
me: Me
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
type Mutation {
|
|
328
|
-
"""
|
|
329
|
-
Operations related to the logged in blog author and its owned data
|
|
330
|
-
"""
|
|
331
|
-
me: AuthorOps
|
|
332
|
-
|
|
333
|
-
"""
|
|
334
|
-
Operations related to reading articles by logged in user
|
|
335
|
-
"""
|
|
336
|
-
article(
|
|
337
|
-
id: ID!
|
|
338
|
-
): ArticleReaderOps
|
|
339
|
-
|
|
340
|
-
"""
|
|
341
|
-
Operations related to commenting on articles by logged in user
|
|
342
|
-
"""
|
|
343
|
-
comment(
|
|
344
|
-
id: ID!
|
|
345
|
-
): CommentAuthorOps
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
"""
|
|
349
|
-
Operations related to reading articles
|
|
350
|
-
"""
|
|
351
|
-
type ArticleReaderOps {
|
|
352
|
-
"""
|
|
353
|
-
Add a comment to an article
|
|
354
|
-
"""
|
|
355
|
-
comment(
|
|
356
|
-
"""
|
|
357
|
-
The content of the comment
|
|
358
|
-
"""
|
|
359
|
-
content: String!
|
|
360
|
-
): ID!
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
"""
|
|
365
|
-
Operations related to commenting on articles
|
|
366
|
-
"""
|
|
367
|
-
type CommentAuthorOps {
|
|
368
|
-
"""
|
|
369
|
-
Delete the comment
|
|
370
|
-
"""
|
|
371
|
-
delete: Boolean!
|
|
372
|
-
|
|
373
|
-
"""
|
|
374
|
-
Update the content of the comment
|
|
375
|
-
"""
|
|
376
|
-
update(
|
|
377
|
-
"""
|
|
378
|
-
The new content of the comment
|
|
379
|
-
"""
|
|
380
|
-
content: String!
|
|
381
|
-
): Boolean!
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
"""
|
|
385
|
-
Operations related to the logged in user
|
|
386
|
-
"""
|
|
387
|
-
type AuthorOps {
|
|
388
|
-
"""
|
|
389
|
-
Create a new article
|
|
390
|
-
"""
|
|
391
|
-
createArticle(
|
|
392
|
-
"""
|
|
393
|
-
The details of the article to create
|
|
394
|
-
"""
|
|
395
|
-
article: CreateArticle!
|
|
396
|
-
): ID!
|
|
397
|
-
|
|
398
|
-
"""
|
|
399
|
-
Operations related to managing an article
|
|
400
|
-
"""
|
|
401
|
-
article(
|
|
402
|
-
"""
|
|
403
|
-
The ID of the article
|
|
404
|
-
"""
|
|
405
|
-
id: ID!
|
|
406
|
-
): ArticleAuthorOps
|
|
407
|
-
|
|
408
|
-
"""
|
|
409
|
-
Operations related to managing authors comments
|
|
410
|
-
"""
|
|
411
|
-
comment(
|
|
412
|
-
"""
|
|
413
|
-
The ID of the comment
|
|
414
|
-
"""
|
|
415
|
-
id: ID!
|
|
416
|
-
): CommentAuthorOps
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
"""
|
|
420
|
-
Operations related to managing an article
|
|
421
|
-
"""
|
|
422
|
-
type ArticleAuthorOps {
|
|
423
|
-
"""
|
|
424
|
-
Delete the article
|
|
425
|
-
"""
|
|
426
|
-
delete: Boolean!
|
|
427
|
-
|
|
428
|
-
"""
|
|
429
|
-
Update the details of the article
|
|
430
|
-
"""
|
|
431
|
-
update(
|
|
432
|
-
"""
|
|
433
|
-
The updated details of the article
|
|
434
|
-
"""
|
|
435
|
-
article: EditArticle!
|
|
436
|
-
): Boolean!
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
schema{
|
|
440
|
-
query: Query
|
|
441
|
-
mutation: Mutation
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
type Me{
|
|
445
|
-
author: Author
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
"""
|
|
449
|
-
Input type for creating an article
|
|
450
|
-
"""
|
|
451
|
-
input CreateArticle {
|
|
452
|
-
"""
|
|
453
|
-
The title of the article
|
|
454
|
-
"""
|
|
455
|
-
title: String!
|
|
456
|
-
|
|
457
|
-
"""
|
|
458
|
-
The content of the article
|
|
459
|
-
"""
|
|
460
|
-
content: String!
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
"""
|
|
464
|
-
Input type for editing an article
|
|
465
|
-
"""
|
|
466
|
-
input EditArticle {
|
|
467
|
-
"""
|
|
468
|
-
The updated title of the article
|
|
469
|
-
"""
|
|
470
|
-
title: String
|
|
471
|
-
|
|
472
|
-
"""
|
|
473
|
-
The updated content of the article
|
|
474
|
-
"""
|
|
475
|
-
content: String
|
|
476
|
-
}
|
|
477
|
-
\`\`\`
|
|
478
|
-
`;
|
|
479
|
-
import chalk from 'chalk';
|
|
480
|
-
import { readFileSync } from 'fs';
|
|
481
|
-
import openai from 'openai';
|
|
482
|
-
import clipboard from 'clipboardy';
|
|
483
|
-
import { config } from '@aexol/axolotl-config';
|
|
484
|
-
import * as path from 'path';
|
|
485
|
-
import { vaildateChatModel } from "./utils.js";
|
|
486
|
-
import { oraPromise } from 'ora';
|
|
487
|
-
export const graphqlAiCommand = (program) => {
|
|
488
|
-
program
|
|
489
|
-
.command('gai')
|
|
490
|
-
.argument('<prompt>')
|
|
491
|
-
.argument('[existing_schema_path]', 'path to the file containing existing schema')
|
|
492
|
-
.description(`${chalk.greenBright('Axolotl ai')} - schema creator`)
|
|
493
|
-
.action(createResolverFile);
|
|
494
|
-
};
|
|
495
|
-
export const createResolverFile = async (prompt, existing_schema_path) => {
|
|
496
|
-
const cfg = config.get();
|
|
497
|
-
let extra_prompt_info = cfg.graphql_prompt_info;
|
|
498
|
-
const agent_model = vaildateChatModel(cfg.agent_model || 'gpt-4.1');
|
|
499
|
-
if (extra_prompt_info?.endsWith('.txt')) {
|
|
500
|
-
extra_prompt_info = readFileSync(path.join(process.cwd(), extra_prompt_info), 'utf-8');
|
|
501
|
-
}
|
|
502
|
-
const system = `${graphqlAiPrompt}${extra_prompt_info ? `\nAlso take to account that:\n${extra_prompt_info}\n\n` : ''} ${existing_schema_path ? `Please change that in the following existing schema code: ${readFileSync(path.join(process.cwd(), existing_schema_path), 'utf-8')}` : ''}
|
|
503
|
-
|
|
504
|
-
Return pure GraphQL schema in graphql text format dont return markdown with embedded graphql just GraphQL
|
|
505
|
-
`;
|
|
506
|
-
const apiKey = process.env.OPEN_AI_API_KEY;
|
|
507
|
-
if (!apiKey)
|
|
508
|
-
throw new Error('Please provide OPEN_AI_API_KEY env variable');
|
|
509
|
-
const ai = new openai({ apiKey: process.env.OPEN_AI_API_KEY });
|
|
510
|
-
await oraPromise(ai.chat.completions
|
|
511
|
-
.create({
|
|
512
|
-
model: agent_model,
|
|
513
|
-
messages: [
|
|
514
|
-
{
|
|
515
|
-
role: 'system',
|
|
516
|
-
content: system,
|
|
517
|
-
},
|
|
518
|
-
{
|
|
519
|
-
role: 'user',
|
|
520
|
-
content: prompt,
|
|
521
|
-
},
|
|
522
|
-
],
|
|
523
|
-
})
|
|
524
|
-
.then((response) => {
|
|
525
|
-
const res = response.choices.at(0)?.message.content;
|
|
526
|
-
if (res) {
|
|
527
|
-
clipboard.writeSync(res);
|
|
528
|
-
}
|
|
529
|
-
console.log(`Generated resolver has been copied to clipboard`);
|
|
530
|
-
}), { spinner: 'binary', text: 'Thinking' });
|
|
531
|
-
};
|
|
532
|
-
//# sourceMappingURL=graphqlAi.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"graphqlAi.js","sourceRoot":"","sources":["../../codegen/graphqlAi.ts"],"names":[],"mappings":"AAAA,MAAM,eAAe,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6dvB,CAAC;AACF,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,SAAS,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAAE,mBAA2B;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAEjC,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,OAAgB,EAAE,EAAE;IACnD,OAAO;SACJ,OAAO,CAAC,KAAK,CAAC;SACd,QAAQ,CAAC,UAAU,CAAC;SACpB,QAAQ,CAAC,wBAAwB,EAAE,6CAA6C,CAAC;SACjF,WAAW,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC,YAAY,CAAC,mBAAmB,CAAC;SAClE,MAAM,CAAC,kBAAkB,CAAC,CAAC;AAChC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,EAAE,MAAc,EAAE,oBAA6B,EAAE,EAAE;IACxF,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,EAAE,CAAC;IACzB,IAAI,iBAAiB,GAAG,GAAG,CAAC,mBAAmB,CAAC;IAChD,MAAM,WAAW,GAAG,iBAAiB,CAAC,GAAG,CAAC,WAAW,IAAI,SAAS,CAAC,CAAC;IAEpE,IAAI,iBAAiB,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACxC,iBAAiB,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,iBAAiB,CAAC,EAAE,OAAO,CAAC,CAAC;IACzF,CAAC;IACD,MAAM,MAAM,GAAG,GAAG,eAAe,GAAG,iBAAiB,CAAC,CAAC,CAAC,iCAAiC,iBAAiB,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,oBAAoB,CAAC,CAAC,CAAC,6DAA6D,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,oBAAoB,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;;;GAGzR,CAAC;IACF,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IAC3C,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IAC5E,MAAM,EAAE,GAAG,IAAI,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC,CAAC;IAC/D,MAAM,UAAU,CACd,EAAE,CAAC,IAAI,CAAC,WAAW;SAChB,MAAM,CAAC;QACN,KAAK,EAAE,WAAW;QAClB,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,MAAM;aAChB;YACD;gBACE,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,MAAM;aAChB;SACF;KACF,CAAC;SACD,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE;QACjB,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC;QACpD,IAAI,GAAG,EAAE,CAAC;YACR,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;IACjE,CAAC,CAAC,EACJ,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,CACxC,CAAC;AACJ,CAAC,CAAC"}
|
package/lib/codegen/index.d.ts
DELETED
package/lib/codegen/index.js
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import { createResolverFile } from './utils.js';
|
|
3
|
-
export const createResolversConfig = (program) => {
|
|
4
|
-
program
|
|
5
|
-
.command('resolver')
|
|
6
|
-
.argument('[dir]')
|
|
7
|
-
.description(`${chalk.greenBright('Axolotl Codegen')} - resolvers creator`)
|
|
8
|
-
.action(createResolverFile);
|
|
9
|
-
};
|
|
10
|
-
//# sourceMappingURL=index.js.map
|
package/lib/codegen/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../codegen/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,OAAgB,EAAE,EAAE;IACxD,OAAO;SACJ,OAAO,CAAC,UAAU,CAAC;SACnB,QAAQ,CAAC,OAAO,CAAC;SACjB,WAAW,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC,iBAAiB,CAAC,sBAAsB,CAAC;SAC1E,MAAM,CAAC,kBAAkB,CAAC,CAAC;AAChC,CAAC,CAAC"}
|
package/lib/codegen/mcp.d.ts
DELETED