@constructive-io/graphql-codegen 2.23.2 → 2.24.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 (90) hide show
  1. package/README.md +147 -2
  2. package/cli/codegen/babel-ast.d.ts +46 -0
  3. package/cli/codegen/babel-ast.js +145 -0
  4. package/cli/codegen/barrel.d.ts +7 -2
  5. package/cli/codegen/barrel.js +159 -97
  6. package/cli/codegen/client.js +61 -0
  7. package/cli/codegen/custom-mutations.d.ts +2 -12
  8. package/cli/codegen/custom-mutations.js +116 -124
  9. package/cli/codegen/custom-queries.d.ts +2 -10
  10. package/cli/codegen/custom-queries.js +246 -335
  11. package/cli/codegen/index.d.ts +3 -0
  12. package/cli/codegen/index.js +72 -3
  13. package/cli/codegen/invalidation.d.ts +20 -0
  14. package/cli/codegen/invalidation.js +327 -0
  15. package/cli/codegen/mutation-keys.d.ts +24 -0
  16. package/cli/codegen/mutation-keys.js +247 -0
  17. package/cli/codegen/mutations.d.ts +3 -19
  18. package/cli/codegen/mutations.js +372 -383
  19. package/cli/codegen/orm/barrel.d.ts +1 -1
  20. package/cli/codegen/orm/barrel.js +42 -10
  21. package/cli/codegen/orm/client-generator.d.ts +1 -19
  22. package/cli/codegen/orm/client-generator.js +108 -77
  23. package/cli/codegen/orm/custom-ops-generator.d.ts +1 -12
  24. package/cli/codegen/orm/custom-ops-generator.js +192 -235
  25. package/cli/codegen/orm/input-types-generator.d.ts +13 -1
  26. package/cli/codegen/orm/input-types-generator.js +403 -147
  27. package/cli/codegen/orm/model-generator.d.ts +1 -19
  28. package/cli/codegen/orm/model-generator.js +229 -234
  29. package/cli/codegen/queries.d.ts +3 -11
  30. package/cli/codegen/queries.js +582 -389
  31. package/cli/codegen/query-keys.d.ts +15 -0
  32. package/cli/codegen/query-keys.js +477 -0
  33. package/cli/codegen/scalars.js +1 -0
  34. package/cli/codegen/schema-types-generator.d.ts +15 -10
  35. package/cli/codegen/schema-types-generator.js +87 -175
  36. package/cli/codegen/type-resolver.d.ts +1 -30
  37. package/cli/codegen/type-resolver.js +0 -53
  38. package/cli/codegen/types.d.ts +1 -1
  39. package/cli/codegen/types.js +76 -21
  40. package/cli/commands/generate.js +1 -0
  41. package/cli/index.js +1 -0
  42. package/esm/cli/codegen/babel-ast.d.ts +46 -0
  43. package/esm/cli/codegen/babel-ast.js +97 -0
  44. package/esm/cli/codegen/barrel.d.ts +7 -2
  45. package/esm/cli/codegen/barrel.js +126 -97
  46. package/esm/cli/codegen/client.js +61 -0
  47. package/esm/cli/codegen/custom-mutations.d.ts +2 -12
  48. package/esm/cli/codegen/custom-mutations.js +83 -124
  49. package/esm/cli/codegen/custom-queries.d.ts +2 -10
  50. package/esm/cli/codegen/custom-queries.js +214 -336
  51. package/esm/cli/codegen/index.d.ts +3 -0
  52. package/esm/cli/codegen/index.js +68 -2
  53. package/esm/cli/codegen/invalidation.d.ts +20 -0
  54. package/esm/cli/codegen/invalidation.js +291 -0
  55. package/esm/cli/codegen/mutation-keys.d.ts +24 -0
  56. package/esm/cli/codegen/mutation-keys.js +211 -0
  57. package/esm/cli/codegen/mutations.d.ts +3 -19
  58. package/esm/cli/codegen/mutations.js +340 -384
  59. package/esm/cli/codegen/orm/barrel.d.ts +1 -1
  60. package/esm/cli/codegen/orm/barrel.js +10 -11
  61. package/esm/cli/codegen/orm/client-generator.d.ts +1 -19
  62. package/esm/cli/codegen/orm/client-generator.js +76 -78
  63. package/esm/cli/codegen/orm/custom-ops-generator.d.ts +1 -12
  64. package/esm/cli/codegen/orm/custom-ops-generator.js +160 -236
  65. package/esm/cli/codegen/orm/input-types-generator.d.ts +13 -1
  66. package/esm/cli/codegen/orm/input-types-generator.js +371 -148
  67. package/esm/cli/codegen/orm/model-generator.d.ts +1 -19
  68. package/esm/cli/codegen/orm/model-generator.js +197 -235
  69. package/esm/cli/codegen/queries.d.ts +3 -11
  70. package/esm/cli/codegen/queries.js +550 -390
  71. package/esm/cli/codegen/query-keys.d.ts +15 -0
  72. package/esm/cli/codegen/query-keys.js +441 -0
  73. package/esm/cli/codegen/scalars.js +1 -0
  74. package/esm/cli/codegen/schema-types-generator.d.ts +15 -10
  75. package/esm/cli/codegen/schema-types-generator.js +54 -175
  76. package/esm/cli/codegen/type-resolver.d.ts +1 -30
  77. package/esm/cli/codegen/type-resolver.js +0 -49
  78. package/esm/cli/codegen/types.d.ts +1 -1
  79. package/esm/cli/codegen/types.js +44 -22
  80. package/esm/cli/commands/generate.js +1 -0
  81. package/esm/cli/index.js +1 -0
  82. package/esm/types/config.d.ts +75 -0
  83. package/esm/types/config.js +19 -1
  84. package/package.json +6 -4
  85. package/types/config.d.ts +75 -0
  86. package/types/config.js +20 -2
  87. package/cli/codegen/ts-ast.d.ts +0 -124
  88. package/cli/codegen/ts-ast.js +0 -280
  89. package/esm/cli/codegen/ts-ast.d.ts +0 -124
  90. package/esm/cli/codegen/ts-ast.js +0 -260
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Barrel file generators for ORM client
2
+ * Barrel file generators for ORM client (Babel AST-based)
3
3
  *
4
4
  * Generates index.ts files that re-export all models and operations.
5
5
  */
@@ -1,13 +1,11 @@
1
- import { createProject, createSourceFile, getFormattedOutput, createFileHeader, } from '../ts-ast';
2
- import { getTableNames, lcFirst } from '../utils';
1
+ import * as t from '@babel/types';
2
+ import { generateCode } from '../babel-ast';
3
+ import { getTableNames, lcFirst, getGeneratedFileHeader } from '../utils';
3
4
  /**
4
5
  * Generate the models/index.ts barrel file
5
6
  */
6
7
  export function generateModelsBarrel(tables) {
7
- const project = createProject();
8
- const sourceFile = createSourceFile(project, 'index.ts');
9
- // Add file header
10
- sourceFile.insertText(0, createFileHeader('Models barrel export') + '\n\n');
8
+ const statements = [];
11
9
  // Export all model classes (Select types are now in input-types.ts)
12
10
  for (const table of tables) {
13
11
  const { typeName } = getTableNames(table);
@@ -15,14 +13,15 @@ export function generateModelsBarrel(tables) {
15
13
  // Use same naming logic as model-generator to avoid "index.ts" clash with barrel file
16
14
  const baseFileName = lcFirst(typeName);
17
15
  const moduleFileName = baseFileName === 'index' ? `${baseFileName}Model` : baseFileName;
18
- sourceFile.addExportDeclaration({
19
- moduleSpecifier: `./${moduleFileName}`,
20
- namedExports: [modelName],
21
- });
16
+ // Create: export { ModelName } from './moduleName';
17
+ const exportDecl = t.exportNamedDeclaration(null, [t.exportSpecifier(t.identifier(modelName), t.identifier(modelName))], t.stringLiteral(`./${moduleFileName}`));
18
+ statements.push(exportDecl);
22
19
  }
20
+ const header = getGeneratedFileHeader('Models barrel export');
21
+ const code = generateCode(statements);
23
22
  return {
24
23
  fileName: 'models/index.ts',
25
- content: getFormattedOutput(sourceFile),
24
+ content: header + '\n' + code,
26
25
  };
27
26
  }
28
27
  /**
@@ -1,25 +1,7 @@
1
1
  /**
2
- * ORM Client generator
2
+ * ORM Client generator (Babel AST-based)
3
3
  *
4
4
  * Generates the createClient() factory function and main client file.
5
- *
6
- * Example output:
7
- * ```typescript
8
- * import { OrmClient, OrmClientConfig } from './client';
9
- * import { UserModel } from './models/user';
10
- * import { queryOperations } from './query';
11
- * import { mutationOperations } from './mutation';
12
- *
13
- * export function createClient(config: OrmClientConfig) {
14
- * const client = new OrmClient(config);
15
- * return {
16
- * user: new UserModel(client),
17
- * post: new PostModel(client),
18
- * query: queryOperations(client),
19
- * mutation: mutationOperations(client),
20
- * };
21
- * }
22
- * ```
23
5
  */
24
6
  import type { CleanTable } from '../../../types/schema';
25
7
  export interface GeneratedClientFile {
@@ -1,5 +1,6 @@
1
- import { createProject, createSourceFile, getFormattedOutput, createFileHeader, createImport, } from '../ts-ast';
2
- import { getTableNames, lcFirst } from '../utils';
1
+ import * as t from '@babel/types';
2
+ import { generateCode, commentBlock } from '../babel-ast';
3
+ import { getTableNames, lcFirst, getGeneratedFileHeader } from '../utils';
3
4
  /**
4
5
  * Generate the main client.ts file (OrmClient class)
5
6
  * This is the runtime client that handles GraphQL execution
@@ -537,105 +538,102 @@ export type InferSelectResult<TEntity, TSelect> = TSelect extends undefined
537
538
  content,
538
539
  };
539
540
  }
541
+ function createImportDeclaration(moduleSpecifier, namedImports, typeOnly = false) {
542
+ const specifiers = namedImports.map((name) => t.importSpecifier(t.identifier(name), t.identifier(name)));
543
+ const decl = t.importDeclaration(specifiers, t.stringLiteral(moduleSpecifier));
544
+ decl.importKind = typeOnly ? 'type' : 'value';
545
+ return decl;
546
+ }
540
547
  /**
541
548
  * Generate the main index.ts with createClient factory
542
549
  */
543
550
  export function generateCreateClientFile(tables, hasCustomQueries, hasCustomMutations) {
544
- const project = createProject();
545
- const sourceFile = createSourceFile(project, 'index.ts');
546
- // Add file header
547
- sourceFile.insertText(0, createFileHeader('ORM Client - createClient factory') + '\n\n');
551
+ const statements = [];
548
552
  // Add imports
549
- const imports = [
550
- createImport({
551
- moduleSpecifier: './client',
552
- namedImports: ['OrmClient'],
553
- typeOnlyNamedImports: ['OrmClientConfig'],
554
- }),
555
- ];
553
+ // Import OrmClient (value) and OrmClientConfig (type) separately
554
+ statements.push(createImportDeclaration('./client', ['OrmClient']));
555
+ statements.push(createImportDeclaration('./client', ['OrmClientConfig'], true));
556
556
  // Import models
557
557
  for (const table of tables) {
558
558
  const { typeName } = getTableNames(table);
559
559
  const modelName = `${typeName}Model`;
560
560
  const fileName = lcFirst(typeName);
561
- imports.push(createImport({
562
- moduleSpecifier: `./models/${fileName}`,
563
- namedImports: [modelName],
564
- }));
561
+ statements.push(createImportDeclaration(`./models/${fileName}`, [modelName]));
565
562
  }
566
563
  // Import custom operations
567
564
  if (hasCustomQueries) {
568
- imports.push(createImport({
569
- moduleSpecifier: './query',
570
- namedImports: ['createQueryOperations'],
571
- }));
565
+ statements.push(createImportDeclaration('./query', ['createQueryOperations']));
572
566
  }
573
567
  if (hasCustomMutations) {
574
- imports.push(createImport({
575
- moduleSpecifier: './mutation',
576
- namedImports: ['createMutationOperations'],
577
- }));
568
+ statements.push(createImportDeclaration('./mutation', ['createMutationOperations']));
578
569
  }
579
- sourceFile.addImportDeclarations(imports);
580
570
  // Re-export types and classes
581
- sourceFile.addStatements('\n// Re-export types and classes');
582
- sourceFile.addStatements("export type { OrmClientConfig, QueryResult, GraphQLError } from './client';");
583
- sourceFile.addStatements("export { GraphQLRequestError } from './client';");
584
- sourceFile.addStatements("export { QueryBuilder } from './query-builder';");
585
- sourceFile.addStatements("export * from './select-types';");
586
- // Generate createClient function
587
- sourceFile.addStatements('\n// ============================================================================');
588
- sourceFile.addStatements('// Client Factory');
589
- sourceFile.addStatements('// ============================================================================\n');
590
- // Build the return object
591
- const modelEntries = tables.map((table) => {
571
+ // export type { OrmClientConfig, QueryResult, GraphQLError } from './client';
572
+ const typeExportDecl = t.exportNamedDeclaration(null, [
573
+ t.exportSpecifier(t.identifier('OrmClientConfig'), t.identifier('OrmClientConfig')),
574
+ t.exportSpecifier(t.identifier('QueryResult'), t.identifier('QueryResult')),
575
+ t.exportSpecifier(t.identifier('GraphQLError'), t.identifier('GraphQLError')),
576
+ ], t.stringLiteral('./client'));
577
+ typeExportDecl.exportKind = 'type';
578
+ statements.push(typeExportDecl);
579
+ // export { GraphQLRequestError } from './client';
580
+ statements.push(t.exportNamedDeclaration(null, [t.exportSpecifier(t.identifier('GraphQLRequestError'), t.identifier('GraphQLRequestError'))], t.stringLiteral('./client')));
581
+ // export { QueryBuilder } from './query-builder';
582
+ statements.push(t.exportNamedDeclaration(null, [t.exportSpecifier(t.identifier('QueryBuilder'), t.identifier('QueryBuilder'))], t.stringLiteral('./query-builder')));
583
+ // export * from './select-types';
584
+ statements.push(t.exportAllDeclaration(t.stringLiteral('./select-types')));
585
+ // Build the return object properties
586
+ const returnProperties = [];
587
+ for (const table of tables) {
592
588
  const { typeName, singularName } = getTableNames(table);
593
- return `${singularName}: new ${typeName}Model(client)`;
594
- });
595
- let returnObject = modelEntries.join(',\n ');
589
+ const modelName = `${typeName}Model`;
590
+ returnProperties.push(t.objectProperty(t.identifier(singularName), t.newExpression(t.identifier(modelName), [t.identifier('client')])));
591
+ }
596
592
  if (hasCustomQueries) {
597
- returnObject += ',\n query: createQueryOperations(client)';
593
+ returnProperties.push(t.objectProperty(t.identifier('query'), t.callExpression(t.identifier('createQueryOperations'), [t.identifier('client')])));
598
594
  }
599
595
  if (hasCustomMutations) {
600
- returnObject += ',\n mutation: createMutationOperations(client)';
596
+ returnProperties.push(t.objectProperty(t.identifier('mutation'), t.callExpression(t.identifier('createMutationOperations'), [t.identifier('client')])));
601
597
  }
602
- sourceFile.addFunction({
603
- name: 'createClient',
604
- isExported: true,
605
- parameters: [{ name: 'config', type: 'OrmClientConfig' }],
606
- statements: `const client = new OrmClient(config);
607
-
608
- return {
609
- ${returnObject},
610
- };`,
611
- docs: [
612
- {
613
- description: `Create an ORM client instance
614
-
615
- @example
616
- \`\`\`typescript
617
- const db = createClient({
618
- endpoint: 'https://api.example.com/graphql',
619
- headers: { Authorization: 'Bearer token' },
620
- });
621
-
622
- // Query users
623
- const users = await db.user.findMany({
624
- select: { id: true, name: true },
625
- first: 10,
626
- }).execute();
627
-
628
- // Create a user
629
- const newUser = await db.user.create({
630
- data: { name: 'John', email: 'john@example.com' },
631
- select: { id: true },
632
- }).execute();
633
- \`\`\``,
634
- },
635
- ],
636
- });
598
+ // Build the createClient function body
599
+ const clientDecl = t.variableDeclaration('const', [
600
+ t.variableDeclarator(t.identifier('client'), t.newExpression(t.identifier('OrmClient'), [t.identifier('config')])),
601
+ ]);
602
+ const returnStmt = t.returnStatement(t.objectExpression(returnProperties));
603
+ const configParam = t.identifier('config');
604
+ configParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('OrmClientConfig')));
605
+ const createClientFunc = t.functionDeclaration(t.identifier('createClient'), [configParam], t.blockStatement([clientDecl, returnStmt]));
606
+ // Add JSDoc comment
607
+ const jsdocComment = commentBlock(`*
608
+ * Create an ORM client instance
609
+ *
610
+ * @example
611
+ * \`\`\`typescript
612
+ * const db = createClient({
613
+ * endpoint: 'https://api.example.com/graphql',
614
+ * headers: { Authorization: 'Bearer token' },
615
+ * });
616
+ *
617
+ * // Query users
618
+ * const users = await db.user.findMany({
619
+ * select: { id: true, name: true },
620
+ * first: 10,
621
+ * }).execute();
622
+ *
623
+ * // Create a user
624
+ * const newUser = await db.user.create({
625
+ * data: { name: 'John', email: 'john@example.com' },
626
+ * select: { id: true },
627
+ * }).execute();
628
+ * \`\`\`
629
+ `);
630
+ const exportedFunc = t.exportNamedDeclaration(createClientFunc);
631
+ exportedFunc.leadingComments = [jsdocComment];
632
+ statements.push(exportedFunc);
633
+ const header = getGeneratedFileHeader('ORM Client - createClient factory');
634
+ const code = generateCode(statements);
637
635
  return {
638
636
  fileName: 'index.ts',
639
- content: getFormattedOutput(sourceFile),
637
+ content: header + '\n' + code,
640
638
  };
641
639
  }
@@ -1,19 +1,8 @@
1
1
  /**
2
- * Custom operations generator for ORM client
2
+ * Custom operations generator for ORM client (Babel AST-based)
3
3
  *
4
4
  * Generates db.query.* and db.mutation.* namespaces for non-table operations
5
5
  * like login, register, currentUser, etc.
6
- *
7
- * Example output:
8
- * ```typescript
9
- * // query/index.ts
10
- * export function createQueryOperations(client: OrmClient) {
11
- * return {
12
- * currentUser: (args?: { select?: CurrentUserSelect }) =>
13
- * new QueryBuilder({ ... }),
14
- * };
15
- * }
16
- * ```
17
6
  */
18
7
  import type { CleanOperation } from '../../../types/schema';
19
8
  export interface GeneratedCustomOpsFile {