@bairock/lenz 0.0.15 → 0.0.17

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 (134) hide show
  1. package/README.md +195 -19
  2. package/dist/cli/commands/generate/crud.d.ts +3 -0
  3. package/dist/cli/commands/generate/crud.d.ts.map +1 -0
  4. package/dist/cli/commands/generate/crud.js +123 -0
  5. package/dist/cli/commands/generate/crud.js.map +1 -0
  6. package/dist/cli/commands/generate/index.d.ts +3 -0
  7. package/dist/cli/commands/generate/index.d.ts.map +1 -0
  8. package/dist/cli/commands/generate/index.js +8 -0
  9. package/dist/cli/commands/generate/index.js.map +1 -0
  10. package/dist/cli/commands/generate/orm.d.ts +3 -0
  11. package/dist/cli/commands/generate/orm.d.ts.map +1 -0
  12. package/dist/cli/commands/generate/orm.js +107 -0
  13. package/dist/cli/commands/generate/orm.js.map +1 -0
  14. package/dist/cli/commands/generate.d.ts.map +1 -1
  15. package/dist/cli/commands/generate.js +34 -8
  16. package/dist/cli/commands/generate.js.map +1 -1
  17. package/dist/cli/commands/init.d.ts.map +1 -1
  18. package/dist/cli/commands/init.js +0 -2
  19. package/dist/cli/commands/init.js.map +1 -1
  20. package/dist/cli/index.js +1 -3
  21. package/dist/cli/index.js.map +1 -1
  22. package/dist/config/index.d.ts +4 -6
  23. package/dist/config/index.d.ts.map +1 -1
  24. package/dist/config/index.js +24 -3
  25. package/dist/config/index.js.map +1 -1
  26. package/dist/engine/CodeGenerator.d.ts +8 -28
  27. package/dist/engine/CodeGenerator.d.ts.map +1 -1
  28. package/dist/engine/CodeGenerator.js +28 -1969
  29. package/dist/engine/CodeGenerator.js.map +1 -1
  30. package/dist/engine/GraphQLParseHelpers.d.ts +25 -0
  31. package/dist/engine/GraphQLParseHelpers.d.ts.map +1 -0
  32. package/dist/engine/GraphQLParseHelpers.js +128 -0
  33. package/dist/engine/GraphQLParseHelpers.js.map +1 -0
  34. package/dist/engine/GraphQLParser.d.ts +23 -10
  35. package/dist/engine/GraphQLParser.d.ts.map +1 -1
  36. package/dist/engine/GraphQLParser.js +154 -240
  37. package/dist/engine/GraphQLParser.js.map +1 -1
  38. package/dist/engine/GraphQLRelationAnalyzer.d.ts +10 -0
  39. package/dist/engine/GraphQLRelationAnalyzer.d.ts.map +1 -0
  40. package/dist/engine/GraphQLRelationAnalyzer.js +117 -0
  41. package/dist/engine/GraphQLRelationAnalyzer.js.map +1 -0
  42. package/dist/engine/LenzEngine.d.ts +1 -1
  43. package/dist/engine/LenzEngine.d.ts.map +1 -1
  44. package/dist/engine/LenzEngine.js +33 -13
  45. package/dist/engine/LenzEngine.js.map +1 -1
  46. package/dist/engine/SchemaRelationValidator.d.ts +15 -0
  47. package/dist/engine/SchemaRelationValidator.d.ts.map +1 -0
  48. package/dist/engine/SchemaRelationValidator.js +133 -0
  49. package/dist/engine/SchemaRelationValidator.js.map +1 -0
  50. package/dist/engine/SchemaValidator.d.ts +11 -10
  51. package/dist/engine/SchemaValidator.d.ts.map +1 -1
  52. package/dist/engine/SchemaValidator.js +151 -169
  53. package/dist/engine/SchemaValidator.js.map +1 -1
  54. package/dist/engine/directives.d.ts +10 -0
  55. package/dist/engine/directives.d.ts.map +1 -1
  56. package/dist/engine/directives.js +152 -6
  57. package/dist/engine/directives.js.map +1 -1
  58. package/dist/engine/generators/ClientGenerator.d.ts +7 -0
  59. package/dist/engine/generators/ClientGenerator.d.ts.map +1 -0
  60. package/dist/engine/generators/ClientGenerator.js +386 -0
  61. package/dist/engine/generators/ClientGenerator.js.map +1 -0
  62. package/dist/engine/generators/CrudModuleGenerator.d.ts +10 -0
  63. package/dist/engine/generators/CrudModuleGenerator.d.ts.map +1 -0
  64. package/dist/engine/generators/CrudModuleGenerator.js +141 -0
  65. package/dist/engine/generators/CrudModuleGenerator.js.map +1 -0
  66. package/dist/engine/generators/DelegateGenerator.d.ts +9 -0
  67. package/dist/engine/generators/DelegateGenerator.d.ts.map +1 -0
  68. package/dist/engine/generators/DelegateGenerator.js +453 -0
  69. package/dist/engine/generators/DelegateGenerator.js.map +1 -0
  70. package/dist/engine/generators/DelegateHelpers.d.ts +7 -0
  71. package/dist/engine/generators/DelegateHelpers.d.ts.map +1 -0
  72. package/dist/engine/generators/DelegateHelpers.js +144 -0
  73. package/dist/engine/generators/DelegateHelpers.js.map +1 -0
  74. package/dist/engine/generators/DelegateRelations.d.ts +11 -0
  75. package/dist/engine/generators/DelegateRelations.d.ts.map +1 -0
  76. package/dist/engine/generators/DelegateRelations.js +794 -0
  77. package/dist/engine/generators/DelegateRelations.js.map +1 -0
  78. package/dist/engine/generators/DelegateTemplateBody.d.ts +8 -0
  79. package/dist/engine/generators/DelegateTemplateBody.d.ts.map +1 -0
  80. package/dist/engine/generators/DelegateTemplateBody.js +776 -0
  81. package/dist/engine/generators/DelegateTemplateBody.js.map +1 -0
  82. package/dist/engine/generators/GenerateRuntimeErrors.d.ts +2 -0
  83. package/dist/engine/generators/GenerateRuntimeErrors.d.ts.map +1 -0
  84. package/dist/engine/generators/GenerateRuntimeErrors.js +140 -0
  85. package/dist/engine/generators/GenerateRuntimeErrors.js.map +1 -0
  86. package/dist/engine/generators/GenerateRuntimeIndex.d.ts +2 -0
  87. package/dist/engine/generators/GenerateRuntimeIndex.d.ts.map +1 -0
  88. package/dist/engine/generators/GenerateRuntimeIndex.js +21 -0
  89. package/dist/engine/generators/GenerateRuntimeIndex.js.map +1 -0
  90. package/dist/engine/generators/GenerateRuntimeLogger.d.ts +2 -0
  91. package/dist/engine/generators/GenerateRuntimeLogger.d.ts.map +1 -0
  92. package/dist/engine/generators/GenerateRuntimeLogger.js +125 -0
  93. package/dist/engine/generators/GenerateRuntimeLogger.js.map +1 -0
  94. package/dist/engine/generators/GenerateRuntimePagination.d.ts +2 -0
  95. package/dist/engine/generators/GenerateRuntimePagination.d.ts.map +1 -0
  96. package/dist/engine/generators/GenerateRuntimePagination.js +159 -0
  97. package/dist/engine/generators/GenerateRuntimePagination.js.map +1 -0
  98. package/dist/engine/generators/GenerateRuntimeQuery.d.ts +2 -0
  99. package/dist/engine/generators/GenerateRuntimeQuery.d.ts.map +1 -0
  100. package/dist/engine/generators/GenerateRuntimeQuery.js +427 -0
  101. package/dist/engine/generators/GenerateRuntimeQuery.js.map +1 -0
  102. package/dist/engine/generators/GenerateRuntimeRelations.d.ts +2 -0
  103. package/dist/engine/generators/GenerateRuntimeRelations.d.ts.map +1 -0
  104. package/dist/engine/generators/GenerateRuntimeRelations.js +130 -0
  105. package/dist/engine/generators/GenerateRuntimeRelations.js.map +1 -0
  106. package/dist/engine/generators/RuntimeGenerator.d.ts +16 -0
  107. package/dist/engine/generators/RuntimeGenerator.d.ts.map +1 -0
  108. package/dist/engine/generators/RuntimeGenerator.js +16 -0
  109. package/dist/engine/generators/RuntimeGenerator.js.map +1 -0
  110. package/dist/engine/generators/SDLInputTypesGenerator.d.ts +6 -0
  111. package/dist/engine/generators/SDLInputTypesGenerator.d.ts.map +1 -0
  112. package/dist/engine/generators/SDLInputTypesGenerator.js +763 -0
  113. package/dist/engine/generators/SDLInputTypesGenerator.js.map +1 -0
  114. package/dist/engine/generators/TypeFilterTypes.d.ts +2 -0
  115. package/dist/engine/generators/TypeFilterTypes.d.ts.map +1 -0
  116. package/dist/engine/generators/TypeFilterTypes.js +220 -0
  117. package/dist/engine/generators/TypeFilterTypes.js.map +1 -0
  118. package/dist/engine/generators/TypeGenerator.d.ts +16 -0
  119. package/dist/engine/generators/TypeGenerator.d.ts.map +1 -0
  120. package/dist/engine/generators/TypeGenerator.js +493 -0
  121. package/dist/engine/generators/TypeGenerator.js.map +1 -0
  122. package/dist/engine/generators/helpers.d.ts +13 -0
  123. package/dist/engine/generators/helpers.d.ts.map +1 -0
  124. package/dist/engine/generators/helpers.js +316 -0
  125. package/dist/engine/generators/helpers.js.map +1 -0
  126. package/dist/errors/index.d.ts +3 -0
  127. package/dist/errors/index.d.ts.map +1 -1
  128. package/dist/errors/index.js +11 -1
  129. package/dist/errors/index.js.map +1 -1
  130. package/dist/index.d.ts +0 -1
  131. package/dist/index.d.ts.map +1 -1
  132. package/dist/index.js +2 -4
  133. package/dist/index.js.map +1 -1
  134. package/package.json +10 -4
@@ -1,4 +1,4 @@
1
- import { GraphQLDirective, DirectiveLocation, GraphQLString, GraphQLNonNull, GraphQLBoolean } from 'graphql';
1
+ import { GraphQLDirective, DirectiveLocation, GraphQLString, GraphQLNonNull, GraphQLBoolean, GraphQLList } from 'graphql';
2
2
  // Определение всех директив Lenz ORM
3
3
  export const modelDirective = new GraphQLDirective({
4
4
  name: 'model',
@@ -8,11 +8,31 @@ export const modelDirective = new GraphQLDirective({
8
8
  export const idDirective = new GraphQLDirective({
9
9
  name: 'id',
10
10
  locations: [DirectiveLocation.FIELD_DEFINITION],
11
+ args: {
12
+ name: {
13
+ type: GraphQLString,
14
+ description: 'Name for the primary key constraint (Prisma @id map parameter)'
15
+ },
16
+ map: {
17
+ type: GraphQLString,
18
+ description: 'Custom name for the underlying index in the database'
19
+ }
20
+ },
11
21
  description: 'Marks a field as primary key (auto-generated ObjectId)'
12
22
  });
13
23
  export const uniqueDirective = new GraphQLDirective({
14
24
  name: 'unique',
15
25
  locations: [DirectiveLocation.FIELD_DEFINITION],
26
+ args: {
27
+ name: {
28
+ type: GraphQLString,
29
+ description: 'Name for the unique constraint (Prisma @unique map parameter)'
30
+ },
31
+ map: {
32
+ type: GraphQLString,
33
+ description: 'Custom name for the underlying index in the database'
34
+ }
35
+ },
16
36
  description: 'Creates a unique index on the field'
17
37
  });
18
38
  export const indexDirective = new GraphQLDirective({
@@ -25,16 +45,24 @@ export const defaultDirective = new GraphQLDirective({
25
45
  locations: [DirectiveLocation.FIELD_DEFINITION],
26
46
  args: {
27
47
  value: {
28
- type: new GraphQLNonNull(GraphQLString),
29
- description: 'Default value for the field'
48
+ type: GraphQLString,
49
+ description: 'Default value for the field (static value)'
50
+ },
51
+ generator: {
52
+ type: GraphQLString,
53
+ description: 'Default value generator: "uuid", "now", "cuid"'
30
54
  }
31
55
  },
32
- description: 'Sets a default value for a field'
56
+ description: 'Sets a default value or generator for a field'
33
57
  });
34
58
  export const relationDirective = new GraphQLDirective({
35
59
  name: 'relation',
36
60
  locations: [DirectiveLocation.FIELD_DEFINITION],
37
61
  args: {
62
+ name: {
63
+ type: GraphQLString,
64
+ description: 'Name for the relation (required when a model has multiple relations to the same target model)'
65
+ },
38
66
  field: {
39
67
  type: new GraphQLNonNull(GraphQLString),
40
68
  description: 'The field that stores the foreign key'
@@ -49,7 +77,11 @@ export const relationDirective = new GraphQLDirective({
49
77
  },
50
78
  onDelete: {
51
79
  type: GraphQLString,
52
- description: 'Cascade delete behavior: "Cascade" (delete related), "SetNull" (nullify FK), or "NoAction" (default, no cascade)'
80
+ description: 'Cascade delete behavior: "Cascade" (delete related), "SetNull" (nullify FK), "Restrict" (prevent delete), or "NoAction" (default, no cascade)'
81
+ },
82
+ onUpdate: {
83
+ type: GraphQLString,
84
+ description: 'Cascade update behavior: "SetNull" (nullify FK), "Cascade" (update related), "Restrict" (prevent update), or "NoAction" (default, no cascade)'
53
85
  }
54
86
  },
55
87
  description: 'Defines a relationship between models'
@@ -74,6 +106,110 @@ export const hideDirective = new GraphQLDirective({
74
106
  locations: [DirectiveLocation.FIELD_DEFINITION],
75
107
  description: 'Excludes field from query results by default. Can be explicitly selected via select option.'
76
108
  });
109
+ export const mapDirective = new GraphQLDirective({
110
+ name: 'map',
111
+ locations: [DirectiveLocation.FIELD_DEFINITION],
112
+ args: {
113
+ name: {
114
+ type: new GraphQLNonNull(GraphQLString),
115
+ description: 'The database field name to map to'
116
+ }
117
+ },
118
+ description: 'Maps a field to a different database column name (Prisma @map)'
119
+ });
120
+ export const modelMapDirective = new GraphQLDirective({
121
+ name: 'modelMap',
122
+ locations: [DirectiveLocation.OBJECT],
123
+ args: {
124
+ name: {
125
+ type: new GraphQLNonNull(GraphQLString),
126
+ description: 'The database collection name to map to (Prisma @@map)'
127
+ }
128
+ },
129
+ description: 'Maps a model to a different database collection name (Prisma @@map)'
130
+ });
131
+ export const ignoreDirective = new GraphQLDirective({
132
+ name: 'ignore',
133
+ locations: [DirectiveLocation.FIELD_DEFINITION],
134
+ description: 'Excludes a field from database operations entirely (Prisma @ignore)'
135
+ });
136
+ export const compoundUniqueDirective = new GraphQLDirective({
137
+ name: 'compoundUnique',
138
+ locations: [DirectiveLocation.OBJECT],
139
+ args: {
140
+ fields: {
141
+ type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(GraphQLString))),
142
+ description: 'Field names to include in the compound unique index'
143
+ },
144
+ name: {
145
+ type: GraphQLString,
146
+ description: 'Optional name for the unique constraint (maps to Prisma @@unique map parameter)'
147
+ }
148
+ },
149
+ description: 'Creates a compound unique index on multiple fields (Prisma @@unique)'
150
+ });
151
+ export const compoundIndexDirective = new GraphQLDirective({
152
+ name: 'compoundIndex',
153
+ locations: [DirectiveLocation.OBJECT],
154
+ args: {
155
+ fields: {
156
+ type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(GraphQLString))),
157
+ description: 'Field names to include in the compound index'
158
+ },
159
+ name: {
160
+ type: GraphQLString,
161
+ description: 'Optional name for the index (maps to Prisma @@index map parameter)'
162
+ }
163
+ },
164
+ description: 'Creates a compound index on multiple fields (Prisma @@index)'
165
+ });
166
+ export const compoundIdDirective = new GraphQLDirective({
167
+ name: 'compoundId',
168
+ locations: [DirectiveLocation.OBJECT],
169
+ args: {
170
+ fields: {
171
+ type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(GraphQLString))),
172
+ description: 'Field names to include in the compound primary key'
173
+ },
174
+ name: {
175
+ type: GraphQLString,
176
+ description: 'Optional name for the primary key constraint'
177
+ }
178
+ },
179
+ description: 'Defines a compound primary key on multiple fields (Prisma @@id)'
180
+ });
181
+ export const fulltextDirective = new GraphQLDirective({
182
+ name: 'fulltext',
183
+ locations: [DirectiveLocation.OBJECT, DirectiveLocation.FIELD_DEFINITION],
184
+ args: {
185
+ fields: {
186
+ type: new GraphQLList(new GraphQLNonNull(GraphQLString)),
187
+ description: 'Field names to include in the full-text index (for object-level usage: @@fulltext(fields: ["title", "description"]))'
188
+ }
189
+ },
190
+ description: 'Creates a MongoDB text index on specified field(s) for full-text search'
191
+ });
192
+ export const emailDirective = new GraphQLDirective({
193
+ name: 'email',
194
+ locations: [DirectiveLocation.FIELD_DEFINITION],
195
+ description: 'Validates that the field value is a valid email address'
196
+ });
197
+ export const urlDirective = new GraphQLDirective({
198
+ name: 'url',
199
+ locations: [DirectiveLocation.FIELD_DEFINITION],
200
+ description: 'Validates that the field value is a valid URL'
201
+ });
202
+ export const regexDirective = new GraphQLDirective({
203
+ name: 'regex',
204
+ locations: [DirectiveLocation.FIELD_DEFINITION],
205
+ args: {
206
+ pattern: {
207
+ type: new GraphQLNonNull(GraphQLString),
208
+ description: 'Regular expression pattern to validate the field value against'
209
+ }
210
+ },
211
+ description: 'Validates that the field value matches a regular expression pattern'
212
+ });
77
213
  // Экспорт всех директив
78
214
  export const lenzDirectives = [
79
215
  modelDirective,
@@ -85,7 +221,17 @@ export const lenzDirectives = [
85
221
  createdAtDirective,
86
222
  updatedAtDirective,
87
223
  embeddedDirective,
88
- hideDirective
224
+ hideDirective,
225
+ mapDirective,
226
+ modelMapDirective,
227
+ ignoreDirective,
228
+ compoundUniqueDirective,
229
+ compoundIndexDirective,
230
+ compoundIdDirective,
231
+ fulltextDirective,
232
+ emailDirective,
233
+ urlDirective,
234
+ regexDirective
89
235
  ];
90
236
  // Утилита для проверки, является ли директива директивой Lenz
91
237
  export function isLenzDirective(directiveName) {
@@ -1 +1 @@
1
- {"version":3,"file":"directives.js","sourceRoot":"","sources":["../../src/engine/directives.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"directives.js","sourceRoot":"","sources":["../../src/engine/directives.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { GraphQLModel } from '../GraphQLParser.js';
2
+ export declare class ClientGenerator {
3
+ generateIndex(clientName: string): string;
4
+ generateClient(clientName: string, models: GraphQLModel[]): string;
5
+ getModelsForRuntime(models: GraphQLModel[]): any[];
6
+ }
7
+ //# sourceMappingURL=ClientGenerator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClientGenerator.d.ts","sourceRoot":"","sources":["../../../src/engine/generators/ClientGenerator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGnD,qBAAa,eAAe;IAC1B,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAkBzC,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM;IA4VlE,mBAAmB,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,GAAG,EAAE;CAmBnD"}
@@ -0,0 +1,386 @@
1
+ import { toCamelCase } from './helpers.js';
2
+ export class ClientGenerator {
3
+ generateIndex(clientName) {
4
+ return `// This file was auto-generated by Lenz. Do not edit manually.
5
+ // @generated
6
+
7
+ export { ${clientName} } from './client'
8
+ export * from './types'
9
+ export * from './enums'
10
+
11
+ import { ${clientName} } from './client'
12
+
13
+ /**
14
+ * Default export for the Lenz client
15
+ */
16
+ const lenz = new ${clientName}()
17
+ export default lenz
18
+ `;
19
+ }
20
+ generateClient(clientName, models) {
21
+ return `// This file was auto-generated by Lenz. Do not edit manually.
22
+ // @generated
23
+
24
+ import { MongoClient, Db, ObjectId, Collection, Document } from 'mongodb'
25
+ import type { LenzConfig } from './types'
26
+ import { QueryBuilder } from './runtime/query'
27
+ import { RelationResolver } from './runtime/relations'
28
+ import { Logger } from './runtime/logger'
29
+
30
+ ${models.map(model => `
31
+ import { ${model.name}Delegate } from './models/${model.name}'`).join('\n')}
32
+
33
+ export class ${clientName} {
34
+ private mongoClient: MongoClient | null = null
35
+ private db: Db | null = null
36
+ private config: LenzConfig
37
+ private database: string
38
+ private supportsTransactions: boolean = false
39
+ private logger: Logger
40
+
41
+ // Model delegates
42
+ ${models.map(model => ` public ${toCamelCase(model.name)}: ${model.name}Delegate`).join('\n')}
43
+
44
+ private extractDatabaseFromUrl(url: string): string {
45
+ try {
46
+ const parsed = new URL(url);
47
+ const db = parsed.pathname.replace(/^\//, '').split('/')[0];
48
+ return db || 'myapp';
49
+ } catch {
50
+ return 'myapp';
51
+ }
52
+ }
53
+
54
+ constructor(config: LenzConfig = {}) {
55
+ this.config = {
56
+ ...config,
57
+ url: config.url || process.env.MONGODB_URI || 'mongodb://localhost:27017/myapp',
58
+ log: config.log || []
59
+ };
60
+ this.database = config.database || this.extractDatabaseFromUrl(this.config.url);
61
+ this.logger = new Logger(this.config.log);
62
+
63
+ // Initialize model delegates
64
+ ${models.map(model => ` this.${toCamelCase(model.name)} = new ${model.name}Delegate(this)`).join('\n')}
65
+ }
66
+
67
+ // Extensions storage ($extends support)
68
+ private extensions: Array<{
69
+ query?: Record<string, Record<string, (params: { args: any; query: (args: any) => Promise<any> }) => Promise<any>>>
70
+ result?: Record<string, Record<string, { needs?: Record<string, boolean>; compute: (parent: any) => any }>>
71
+ client?: Record<string, (...args: any[]) => any>
72
+ }> = []
73
+
74
+ /**
75
+ * Prisma-compatible $extends — add query interception, computed fields, and client methods
76
+ * @example
77
+ * const xprisma = lenz.$extends({
78
+ * query: {
79
+ * user: {
80
+ * findMany: async ({ args, query }) => {
81
+ * args.where = { ...args.where, deleted: false }
82
+ * return query(args)
83
+ * }
84
+ * }
85
+ * },
86
+ * result: {
87
+ * user: {
88
+ * fullName: {
89
+ * needs: { firstName: true, lastName: true },
90
+ * compute: (user) => \`\${user.firstName} \${user.lastName}\`
91
+ * }
92
+ * }
93
+ * },
94
+ * client: {
95
+ * ping: async () => lenz.$mongo.client.db().admin().ping()
96
+ * }
97
+ * })
98
+ */
99
+ $extends(extension: any): this {
100
+ this.extensions.push(extension)
101
+
102
+ if (extension.client) {
103
+ for (const [key, fn] of Object.entries(extension.client)) {
104
+ ;(this as any)[key] = fn
105
+ }
106
+ }
107
+
108
+ return this
109
+ }
110
+
111
+ getQueryExtension(modelName: string, method: string): ((params: { args: any; query: (args: any) => Promise<any> }) => Promise<any>) | null {
112
+ for (const ext of this.extensions) {
113
+ if (ext.query?.[modelName]?.[method]) {
114
+ return ext.query[modelName][method]
115
+ }
116
+ }
117
+ return null
118
+ }
119
+
120
+ getResultExtensions(modelName: string): Array<{ name: string; compute: (parent: any) => any }> | null {
121
+ const exts: Array<{ name: string; compute: (parent: any) => any }> = []
122
+ for (const ext of this.extensions) {
123
+ if (ext.result?.[modelName]) {
124
+ for (const [name, config] of Object.entries(ext.result[modelName])) {
125
+ exts.push({ name, compute: (config as any).compute })
126
+ }
127
+ }
128
+ }
129
+ return exts.length > 0 ? exts : null
130
+ }
131
+
132
+ $on(event: string, callback: any): void {
133
+ this.logger.on(event, callback)
134
+ }
135
+
136
+ get $logger(): Logger {
137
+ return this.logger
138
+ }
139
+
140
+ async $connect(): Promise<void> {
141
+ if (this.mongoClient) return
142
+
143
+ this.mongoClient = new MongoClient(this.config.url, {
144
+ maxPoolSize: this.config.maxPoolSize || 10,
145
+ connectTimeoutMS: this.config.connectTimeoutMS || 10000,
146
+ socketTimeoutMS: this.config.socketTimeoutMS || 45000
147
+ })
148
+
149
+ await this.mongoClient.connect()
150
+ this.db = this.mongoClient.db(this.database)
151
+
152
+ await this.db.command({ ping: 1 })
153
+
154
+ try {
155
+ const serverInfo = await this.db.admin().serverInfo()
156
+ this.supportsTransactions = serverInfo.repl?.replSetName !== undefined
157
+
158
+ if (!this.supportsTransactions) {
159
+ console.warn('⚠️ MongoDB is running in standalone mode. Transactions will not work.')
160
+ console.warn(' Consider setting up a replica set for transaction support.')
161
+ console.warn(' Example: mongod --replSet rs0 --port 27017')
162
+ }
163
+ } catch (error) {
164
+ console.warn('⚠️ Could not determine MongoDB deployment type:', error.message)
165
+ this.supportsTransactions = false
166
+ }
167
+
168
+ await this.initializeCollections()
169
+
170
+ if (this.config.log?.includes('info')) {
171
+ console.log('✅ Connected to MongoDB')
172
+ }
173
+ }
174
+
175
+ async $disconnect(): Promise<void> {
176
+ if (this.mongoClient) {
177
+ await this.mongoClient.close()
178
+ this.mongoClient = null
179
+ this.db = null
180
+
181
+ if (this.config.log?.includes('info')) {
182
+ console.log('👋 Disconnected from MongoDB')
183
+ }
184
+ }
185
+ }
186
+
187
+ async $transaction<T>(
188
+ args: Array<(tx: any) => Promise<any>> | ((tx: any) => Promise<T>),
189
+ options?: { maxRetry?: number; timeout?: number }
190
+ ): Promise<any> {
191
+ if (!this.mongoClient) {
192
+ throw new Error('Not connected to database')
193
+ }
194
+
195
+ if (!this.supportsTransactions) {
196
+ throw new Error(
197
+ 'Transactions are not supported in standalone MongoDB. ' +
198
+ 'Set up a replica set or use alternative consistency patterns. ' +
199
+ 'During development: mongod --replSet rs0 --port 27017'
200
+ )
201
+ }
202
+
203
+ const maxRetry = options?.maxRetry ?? 3;
204
+
205
+ const isTransientError = (error: any): boolean => {
206
+ return error?.code === 112 ||
207
+ error?.code === 245 ||
208
+ error?.code === 246 ||
209
+ error?.errorLabels?.includes('TransientTransactionError') ||
210
+ error?.errorLabels?.includes('UnknownTransactionCommitResult')
211
+ }
212
+
213
+ if (Array.isArray(args)) {
214
+ const session = this.mongoClient.startSession()
215
+ try {
216
+ session.startTransaction()
217
+ const fns = args as Array<(tx: any) => Promise<any>>;
218
+ const results: any[] = [];
219
+ for (const fn of fns) {
220
+ results.push(await fn(session));
221
+ }
222
+ await session.commitTransaction()
223
+ return results
224
+ } catch (error) {
225
+ await session.abortTransaction().catch(() => {})
226
+ throw error
227
+ } finally {
228
+ session.endSession()
229
+ }
230
+ }
231
+
232
+ let lastError: any;
233
+ for (let attempt = 0; attempt <= maxRetry; attempt++) {
234
+ const session = this.mongoClient.startSession()
235
+ try {
236
+ session.startTransaction()
237
+
238
+ const result = await (args as (tx: any) => Promise<T>)(session)
239
+
240
+ let committed = false;
241
+ for (let commitAttempt = 0; commitAttempt < 3; commitAttempt++) {
242
+ try {
243
+ await session.commitTransaction()
244
+ committed = true;
245
+ break;
246
+ } catch (commitError: any) {
247
+ if (commitAttempt < 2 && isTransientError(commitError)) {
248
+ await new Promise(r => setTimeout(r, Math.min(100 * Math.pow(2, commitAttempt), 1000)))
249
+ continue
250
+ }
251
+ throw commitError
252
+ }
253
+ }
254
+
255
+ if (!committed) {
256
+ throw new Error('Failed to commit transaction after retries')
257
+ }
258
+
259
+ return result
260
+ } catch (error: any) {
261
+ await session.abortTransaction().catch(() => {})
262
+
263
+ if (attempt < maxRetry && isTransientError(error)) {
264
+ const delay = Math.min(100 * Math.pow(2, attempt), 2000)
265
+ await new Promise(r => setTimeout(r, delay))
266
+ lastError = error
267
+ continue
268
+ }
269
+
270
+ throw error
271
+ } finally {
272
+ session.endSession()
273
+ }
274
+ }
275
+
276
+ throw lastError || new Error('Transaction failed')
277
+ }
278
+
279
+ $supportsTransactions(): boolean {
280
+ return this.supportsTransactions
281
+ }
282
+
283
+ private async initializeCollections(): Promise<void> {
284
+ if (!this.db) return
285
+
286
+ const models = ${JSON.stringify(this.getModelsForRuntime(models), null, 2)}
287
+
288
+ for (const model of models) {
289
+ if (!model.collectionName) continue
290
+
291
+ const collections = await this.db.listCollections({ name: model.collectionName }).toArray()
292
+
293
+ if (collections.length === 0) {
294
+ await this.db.createCollection(model.collectionName)
295
+
296
+ if (model.indexes.length > 0) {
297
+ const indexes = model.indexes.map(index => {
298
+ const spec: any = {
299
+ key: index.fields.reduce((acc, field) => {
300
+ const dbField = model.fieldDbNames?.[field] || field
301
+ acc[dbField] = 1
302
+ return acc
303
+ }, {}),
304
+ unique: index.unique,
305
+ sparse: index.sparse || false
306
+ };
307
+ if (index.name) spec.name = index.name;
308
+ return spec;
309
+ })
310
+
311
+ try {
312
+ await this.db.collection(model.collectionName).createIndexes(indexes)
313
+ } catch (error) {
314
+ console.warn(\`Failed to create indexes for \${model.name}:\`, error)
315
+ }
316
+ }
317
+
318
+ // Create full-text search index (if configured)
319
+ if (model.fulltextFields && model.fulltextFields.length > 0) {
320
+ try {
321
+ const textIndex: any = {};
322
+ for (const field of model.fulltextFields) {
323
+ const dbField = model.fieldDbNames?.[field] || field
324
+ textIndex[dbField] = 'text'
325
+ }
326
+ await this.db.collection(model.collectionName).createIndex(textIndex, { name: \`\${model.collectionName}_text\` })
327
+ } catch (error) {
328
+ console.warn(\`Failed to create text index for \${model.name}:\`, error)
329
+ }
330
+ }
331
+ }
332
+ }
333
+ }
334
+
335
+ $isConnected(): boolean {
336
+ return this.mongoClient !== null
337
+ }
338
+
339
+ get $db(): Db {
340
+ if (!this.db) {
341
+ throw new Error('Database not connected. Call $connect() first.')
342
+ }
343
+ return this.db
344
+ }
345
+
346
+ get $mongo(): { client: MongoClient; ObjectId: any } {
347
+ if (!this.mongoClient) {
348
+ throw new Error('Database not connected. Call $connect() first.')
349
+ }
350
+ return {
351
+ client: this.mongoClient,
352
+ ObjectId: ObjectId
353
+ }
354
+ }
355
+
356
+ get $raw(): { collection: (name: string) => Collection<Document> } {
357
+ if (!this.db) {
358
+ throw new Error('Database not connected. Call $connect() first.')
359
+ }
360
+ return {
361
+ collection: (name: string) => this.db!.collection(name)
362
+ }
363
+ }
364
+ }
365
+ `;
366
+ }
367
+ getModelsForRuntime(models) {
368
+ return models.map(model => ({
369
+ name: model.name,
370
+ collectionName: model.collectionName,
371
+ fieldDbNames: Object.fromEntries(model.fields.filter(f => f.dbName).map(f => [f.name, f.dbName])),
372
+ indexes: model.indexes.map(index => {
373
+ const idx = {
374
+ fields: index.fields,
375
+ unique: index.unique,
376
+ sparse: index.sparse ?? false
377
+ };
378
+ if (index.name)
379
+ idx.name = index.name;
380
+ return idx;
381
+ }),
382
+ fulltextFields: model.fulltextFields
383
+ }));
384
+ }
385
+ }
386
+ //# sourceMappingURL=ClientGenerator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClientGenerator.js","sourceRoot":"","sources":["../../../src/engine/generators/ClientGenerator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,MAAM,OAAO,eAAe;IAC1B,aAAa,CAAC,UAAkB;QAC9B,OAAO;;;WAGA,UAAU;;;;WAIV,UAAU;;;;;mBAKF,UAAU;;CAE5B,CAAC;IACA,CAAC;IAED,cAAc,CAAC,UAAkB,EAAE,MAAsB;QACvD,OAAO;;;;;;;;;EAST,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;WACX,KAAK,CAAC,IAAI,6BAA6B,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;;eAE5D,UAAU;;;;;;;;;EASvB,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,IAAI,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;EAsB5F,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,KAAK,CAAC,IAAI,gBAAgB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBA8NpF,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+E7E,CAAC;IACA,CAAC;IAED,mBAAmB,CAAC,MAAsB;QACxC,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC1B,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,cAAc,EAAE,KAAK,CAAC,cAAc;YACpC,YAAY,EAAE,MAAM,CAAC,WAAW,CAC9B,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAChE;YACD,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;gBACjC,MAAM,GAAG,GAAQ;oBACf,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,KAAK;iBAC9B,CAAC;gBACF,IAAI,KAAK,CAAC,IAAI;oBAAE,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;gBACtC,OAAO,GAAG,CAAC;YACb,CAAC,CAAC;YACF,cAAc,EAAE,KAAK,CAAC,cAAc;SACrC,CAAC,CAAC,CAAC;IACN,CAAC;CACF"}
@@ -0,0 +1,10 @@
1
+ import { GraphQLModel } from '../GraphQLParser.js';
2
+ export declare class CrudModuleGenerator {
3
+ private inputTypesPath;
4
+ constructor(inputTypesPath?: string);
5
+ generate(models: GraphQLModel[]): Record<string, string>;
6
+ private genBarrelIndex;
7
+ /** Validate that all required SDL input types exist in the schema SDL string */
8
+ validate(models: GraphQLModel[], schemaSDL: string): void;
9
+ }
10
+ //# sourceMappingURL=CrudModuleGenerator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CrudModuleGenerator.d.ts","sourceRoot":"","sources":["../../../src/engine/generators/CrudModuleGenerator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAqFnD,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,cAAc,CAAS;gBAEnB,cAAc,GAAE,MAAiD;IAI7E,QAAQ,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAoBxD,OAAO,CAAC,cAAc;IAsBtB,gFAAgF;IAChF,QAAQ,CAAC,MAAM,EAAE,YAAY,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;CA0B1D"}