@constructive-io/graphql-codegen 2.22.1 → 2.23.1

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 (99) hide show
  1. package/cli/codegen/barrel.d.ts +5 -1
  2. package/cli/codegen/barrel.js +13 -11
  3. package/cli/codegen/index.d.ts +3 -3
  4. package/cli/codegen/index.js +15 -9
  5. package/cli/codegen/orm/client-generator.js +3 -2
  6. package/cli/codegen/orm/custom-ops-generator.js +17 -4
  7. package/cli/codegen/orm/input-types-generator.js +129 -18
  8. package/cli/codegen/orm/model-generator.js +2 -1
  9. package/cli/codegen/orm/query-builder.d.ts +1 -1
  10. package/cli/codegen/orm/query-builder.js +2 -2
  11. package/cli/codegen/schema-types-generator.js +5 -5
  12. package/cli/codegen/utils.d.ts +6 -1
  13. package/cli/codegen/utils.js +23 -8
  14. package/cli/commands/generate-orm.d.ts +5 -3
  15. package/cli/commands/generate-orm.js +65 -84
  16. package/cli/commands/generate.d.ts +2 -0
  17. package/cli/commands/generate.js +66 -87
  18. package/cli/commands/shared.d.ts +74 -0
  19. package/cli/commands/shared.js +88 -0
  20. package/cli/index.js +75 -45
  21. package/cli/introspect/index.d.ts +8 -5
  22. package/cli/introspect/index.js +19 -7
  23. package/cli/introspect/infer-tables.d.ts +51 -0
  24. package/cli/introspect/infer-tables.js +550 -0
  25. package/cli/introspect/source/endpoint.d.ts +34 -0
  26. package/cli/introspect/source/endpoint.js +35 -0
  27. package/cli/introspect/source/file.d.ts +20 -0
  28. package/cli/introspect/source/file.js +103 -0
  29. package/cli/introspect/source/index.d.ts +48 -0
  30. package/cli/introspect/source/index.js +72 -0
  31. package/cli/introspect/source/types.d.ts +58 -0
  32. package/cli/introspect/source/types.js +27 -0
  33. package/cli/introspect/transform.d.ts +5 -6
  34. package/cli/introspect/transform.js +0 -173
  35. package/cli/watch/cache.d.ts +3 -4
  36. package/cli/watch/cache.js +6 -10
  37. package/cli/watch/poller.d.ts +1 -2
  38. package/cli/watch/poller.js +27 -45
  39. package/cli/watch/types.d.ts +0 -3
  40. package/core/ast.js +4 -4
  41. package/core/query-builder.js +12 -12
  42. package/esm/cli/codegen/barrel.d.ts +5 -1
  43. package/esm/cli/codegen/barrel.js +13 -11
  44. package/esm/cli/codegen/index.d.ts +3 -3
  45. package/esm/cli/codegen/index.js +18 -12
  46. package/esm/cli/codegen/orm/client-generator.js +3 -2
  47. package/esm/cli/codegen/orm/custom-ops-generator.js +18 -5
  48. package/esm/cli/codegen/orm/input-types-generator.js +130 -19
  49. package/esm/cli/codegen/orm/model-generator.js +3 -2
  50. package/esm/cli/codegen/orm/query-builder.d.ts +1 -1
  51. package/esm/cli/codegen/orm/query-builder.js +2 -2
  52. package/esm/cli/codegen/schema-types-generator.js +6 -6
  53. package/esm/cli/codegen/utils.d.ts +6 -1
  54. package/esm/cli/codegen/utils.js +22 -8
  55. package/esm/cli/commands/generate-orm.d.ts +5 -3
  56. package/esm/cli/commands/generate-orm.js +65 -84
  57. package/esm/cli/commands/generate.d.ts +2 -0
  58. package/esm/cli/commands/generate.js +66 -87
  59. package/esm/cli/commands/shared.d.ts +74 -0
  60. package/esm/cli/commands/shared.js +84 -0
  61. package/esm/cli/index.js +76 -46
  62. package/esm/cli/introspect/index.d.ts +8 -5
  63. package/esm/cli/introspect/index.js +10 -3
  64. package/esm/cli/introspect/infer-tables.d.ts +51 -0
  65. package/esm/cli/introspect/infer-tables.js +547 -0
  66. package/esm/cli/introspect/source/endpoint.d.ts +34 -0
  67. package/esm/cli/introspect/source/endpoint.js +31 -0
  68. package/esm/cli/introspect/source/file.d.ts +20 -0
  69. package/esm/cli/introspect/source/file.js +66 -0
  70. package/esm/cli/introspect/source/index.d.ts +48 -0
  71. package/esm/cli/introspect/source/index.js +54 -0
  72. package/esm/cli/introspect/source/types.d.ts +58 -0
  73. package/esm/cli/introspect/source/types.js +23 -0
  74. package/esm/cli/introspect/transform.d.ts +5 -6
  75. package/esm/cli/introspect/transform.js +0 -172
  76. package/esm/cli/watch/cache.d.ts +3 -4
  77. package/esm/cli/watch/cache.js +7 -11
  78. package/esm/cli/watch/poller.d.ts +1 -2
  79. package/esm/cli/watch/poller.js +28 -46
  80. package/esm/cli/watch/types.d.ts +0 -3
  81. package/esm/core/ast.js +4 -4
  82. package/esm/core/query-builder.js +12 -12
  83. package/esm/generators/mutations.js +3 -3
  84. package/esm/generators/select.js +7 -7
  85. package/esm/types/config.d.ts +21 -5
  86. package/esm/types/config.js +2 -1
  87. package/generators/mutations.js +3 -3
  88. package/generators/select.js +7 -7
  89. package/package.json +5 -3
  90. package/types/config.d.ts +21 -5
  91. package/types/config.js +2 -1
  92. package/cli/introspect/fetch-meta.d.ts +0 -31
  93. package/cli/introspect/fetch-meta.js +0 -108
  94. package/cli/introspect/meta-query.d.ts +0 -111
  95. package/cli/introspect/meta-query.js +0 -191
  96. package/esm/cli/introspect/fetch-meta.d.ts +0 -31
  97. package/esm/cli/introspect/fetch-meta.js +0 -104
  98. package/esm/cli/introspect/meta-query.d.ts +0 -111
  99. package/esm/cli/introspect/meta-query.js +0 -188
package/esm/core/ast.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as t from 'gql-ast';
2
- import * as inflection from 'inflection';
2
+ import { camelize, singularize } from 'inflekt';
3
3
  import { getCustomAst } from './custom-ast';
4
4
  const NON_MUTABLE_PROPS = ['createdAt', 'createdBy', 'updatedAt', 'updatedBy'];
5
5
  const objectToArray = (obj) => Object.keys(obj).map((k) => ({
@@ -279,7 +279,7 @@ export const createOne = ({ mutationName, operationName, mutation, selection, })
279
279
  if (!mutation.properties?.input?.properties) {
280
280
  throw new Error(`No input field for mutation: ${mutationName}`);
281
281
  }
282
- const modelName = inflection.camelize([inflection.singularize(mutation.model)].join('_'), true);
282
+ const modelName = camelize([singularize(mutation.model)].join('_'), true);
283
283
  const inputProperties = mutation.properties.input
284
284
  .properties;
285
285
  const modelProperties = inputProperties[modelName];
@@ -324,7 +324,7 @@ export const patchOne = ({ mutationName, operationName, mutation, selection, })
324
324
  if (!mutation.properties?.input?.properties) {
325
325
  throw new Error(`No input field for mutation: ${mutationName}`);
326
326
  }
327
- const modelName = inflection.camelize([inflection.singularize(mutation.model)].join('_'), true);
327
+ const modelName = camelize([singularize(mutation.model)].join('_'), true);
328
328
  const inputProperties = mutation.properties.input
329
329
  .properties;
330
330
  const patchProperties = inputProperties['patch'];
@@ -376,7 +376,7 @@ export const deleteOne = ({ mutationName, operationName, mutation, }) => {
376
376
  if (!mutation.properties?.input?.properties) {
377
377
  throw new Error(`No input field for mutation: ${mutationName}`);
378
378
  }
379
- const modelName = inflection.camelize([inflection.singularize(mutation.model)].join('_'), true);
379
+ const modelName = camelize([singularize(mutation.model)].join('_'), true);
380
380
  const inputProperties = mutation.properties.input
381
381
  .properties;
382
382
  const deleteAttrs = objectToArray(inputProperties);
@@ -1,5 +1,5 @@
1
1
  import { print as gqlPrint } from 'graphql';
2
- import * as inflection from 'inflection';
2
+ import { camelize, underscore, pluralize } from 'inflekt';
3
3
  import { createOne, deleteOne, getAll, getCount, getMany, getOne, patchOne, } from './ast';
4
4
  import { validateMetaObject } from './meta-object';
5
5
  export * as MetaObject from './meta-object';
@@ -88,13 +88,13 @@ export class QueryBuilder {
88
88
  const getInputName = (mutationType) => {
89
89
  switch (mutationType) {
90
90
  case 'delete': {
91
- return `Delete${inflection.camelize(this._model)}Input`;
91
+ return `Delete${camelize(this._model)}Input`;
92
92
  }
93
93
  case 'create': {
94
- return `Create${inflection.camelize(this._model)}Input`;
94
+ return `Create${camelize(this._model)}Input`;
95
95
  }
96
96
  case 'patch': {
97
- return `Update${inflection.camelize(this._model)}Input`;
97
+ return `Update${camelize(this._model)}Input`;
98
98
  }
99
99
  default:
100
100
  throw new Error('Unhandled mutation type' + mutationType);
@@ -123,7 +123,7 @@ export class QueryBuilder {
123
123
  getMany({ select } = {}) {
124
124
  this._op = 'getMany';
125
125
  this._key = this._findQuery();
126
- this.queryName(inflection.camelize(['get', inflection.underscore(this._key), 'query'].join('_'), true));
126
+ this.queryName(camelize(['get', underscore(this._key), 'query'].join('_'), true));
127
127
  const defn = this._introspection[this._key];
128
128
  this.select(select);
129
129
  this._ast = getMany({
@@ -138,7 +138,7 @@ export class QueryBuilder {
138
138
  all({ select } = {}) {
139
139
  this._op = 'getMany';
140
140
  this._key = this._findQuery();
141
- this.queryName(inflection.camelize(['get', inflection.underscore(this._key), 'query', 'all'].join('_'), true));
141
+ this.queryName(camelize(['get', underscore(this._key), 'query', 'all'].join('_'), true));
142
142
  const defn = this._introspection[this._key];
143
143
  this.select(select);
144
144
  this._ast = getAll({
@@ -152,7 +152,7 @@ export class QueryBuilder {
152
152
  count() {
153
153
  this._op = 'getMany';
154
154
  this._key = this._findQuery();
155
- this.queryName(inflection.camelize(['get', inflection.underscore(this._key), 'count', 'query'].join('_'), true));
155
+ this.queryName(camelize(['get', underscore(this._key), 'count', 'query'].join('_'), true));
156
156
  const defn = this._introspection[this._key];
157
157
  this._ast = getCount({
158
158
  queryName: this._queryName,
@@ -164,7 +164,7 @@ export class QueryBuilder {
164
164
  getOne({ select } = {}) {
165
165
  this._op = 'getOne';
166
166
  this._key = this._findQuery();
167
- this.queryName(inflection.camelize(['get', inflection.underscore(this._key), 'query'].join('_'), true));
167
+ this.queryName(camelize(['get', underscore(this._key), 'query'].join('_'), true));
168
168
  const defn = this._introspection[this._key];
169
169
  this.select(select);
170
170
  this._ast = getOne({
@@ -180,7 +180,7 @@ export class QueryBuilder {
180
180
  this._op = 'mutation';
181
181
  this._mutation = 'create';
182
182
  this._key = this._findMutation();
183
- this.queryName(inflection.camelize([inflection.underscore(this._key), 'mutation'].join('_'), true));
183
+ this.queryName(camelize([underscore(this._key), 'mutation'].join('_'), true));
184
184
  const defn = this._introspection[this._key];
185
185
  this.select(select);
186
186
  this._ast = createOne({
@@ -195,7 +195,7 @@ export class QueryBuilder {
195
195
  this._op = 'mutation';
196
196
  this._mutation = 'delete';
197
197
  this._key = this._findMutation();
198
- this.queryName(inflection.camelize([inflection.underscore(this._key), 'mutation'].join('_'), true));
198
+ this.queryName(camelize([underscore(this._key), 'mutation'].join('_'), true));
199
199
  const defn = this._introspection[this._key];
200
200
  this.select(select);
201
201
  this._ast = deleteOne({
@@ -209,7 +209,7 @@ export class QueryBuilder {
209
209
  this._op = 'mutation';
210
210
  this._mutation = 'patch';
211
211
  this._key = this._findMutation();
212
- this.queryName(inflection.camelize([inflection.underscore(this._key), 'mutation'].join('_'), true));
212
+ this.queryName(camelize([underscore(this._key), 'mutation'].join('_'), true));
213
213
  const defn = this._introspection[this._key];
214
214
  this.select(select);
215
215
  this._ast = patchOne({
@@ -371,5 +371,5 @@ function isRelationalField(fieldName, modelMeta) {
371
371
  // Get getMany op name from model
372
372
  // ie. UserSetting => userSettings
373
373
  function modelNameToGetMany(model) {
374
- return inflection.camelize(inflection.pluralize(inflection.underscore(model)), true);
374
+ return camelize(pluralize(underscore(model)), true);
375
375
  }
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import * as t from 'gql-ast';
6
6
  import { print } from 'graphql';
7
- import * as inflection from 'inflection';
7
+ import { camelize } from 'inflekt';
8
8
  import { TypedDocumentString } from '../client/typed-document';
9
9
  import { getCustomAstForCleanField, requiresSubfieldSelection, } from '../core/custom-ast';
10
10
  import { isRelationalField } from './field-selector';
@@ -32,7 +32,7 @@ function generateFieldSelections(table) {
32
32
  */
33
33
  export function buildPostGraphileCreate(table, _allTables, _options = {}) {
34
34
  const mutationName = `create${table.name}`;
35
- const singularName = inflection.camelize(table.name, true);
35
+ const singularName = camelize(table.name, true);
36
36
  // Create the variable definition for $input
37
37
  const variableDefinitions = [
38
38
  t.variableDefinition({
@@ -91,7 +91,7 @@ export function buildPostGraphileCreate(table, _allTables, _options = {}) {
91
91
  */
92
92
  export function buildPostGraphileUpdate(table, _allTables, _options = {}) {
93
93
  const mutationName = `update${table.name}`;
94
- const singularName = inflection.camelize(table.name, true);
94
+ const singularName = camelize(table.name, true);
95
95
  // Create the variable definition for $input
96
96
  const variableDefinitions = [
97
97
  t.variableDefinition({
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import * as t from 'gql-ast';
6
6
  import { print } from 'graphql';
7
- import * as inflection from 'inflection';
7
+ import { camelize, pluralize } from 'inflekt';
8
8
  import { TypedDocumentString } from '../client/typed-document';
9
9
  import { getCustomAstForCleanField, requiresSubfieldSelection, } from '../core/custom-ast';
10
10
  import { QueryBuilder } from '../core/query-builder';
@@ -16,9 +16,9 @@ import { convertToSelectionOptions, isRelationalField } from './field-selector';
16
16
  */
17
17
  export function toCamelCasePlural(tableName) {
18
18
  // First convert to camelCase (lowercase first letter)
19
- const camelCase = inflection.camelize(tableName, true);
19
+ const camelCase = camelize(tableName, true);
20
20
  // Then pluralize properly
21
- return inflection.pluralize(camelCase);
21
+ return pluralize(camelCase);
22
22
  }
23
23
  /**
24
24
  * Generate the PostGraphile OrderBy enum type name for a table
@@ -101,7 +101,7 @@ export function generateIntrospectionSchema(tables) {
101
101
  properties: convertFieldsToProperties(table.fields),
102
102
  };
103
103
  // Add getOne query (by ID)
104
- const singularName = inflection.camelize(modelName, true);
104
+ const singularName = camelize(modelName, true);
105
105
  schema[singularName] = {
106
106
  qtype: 'getOne',
107
107
  model: modelName,
@@ -122,8 +122,8 @@ export function generateIntrospectionSchema(tables) {
122
122
  isArray: false,
123
123
  isArrayNotNull: false,
124
124
  properties: {
125
- [inflection.camelize(modelName, true)]: {
126
- name: inflection.camelize(modelName, true),
125
+ [camelize(modelName, true)]: {
126
+ name: camelize(modelName, true),
127
127
  type: `${modelName}Input`,
128
128
  isNotNull: true,
129
129
  isArray: false,
@@ -549,7 +549,7 @@ function findRelatedTable(relationField, table, allTables) {
549
549
  * Generate FindOne query AST directly from CleanTable
550
550
  */
551
551
  function generateFindOneQueryAST(table) {
552
- const singularName = inflection.camelize(table.name, true);
552
+ const singularName = camelize(table.name, true);
553
553
  // Generate field selections (include all non-relational fields, including complex types)
554
554
  const fieldSelections = table.fields
555
555
  .filter((field) => !isRelationalField(field.name, table))
@@ -6,9 +6,15 @@
6
6
  */
7
7
  export interface GraphQLSDKConfig {
8
8
  /**
9
- * GraphQL endpoint URL (must expose _meta query)
9
+ * GraphQL endpoint URL for live introspection
10
+ * Either endpoint or schema must be provided
10
11
  */
11
- endpoint: string;
12
+ endpoint?: string;
13
+ /**
14
+ * Path to GraphQL schema file (.graphql) for file-based generation
15
+ * Either endpoint or schema must be provided
16
+ */
17
+ schema?: string;
12
18
  /**
13
19
  * Headers to include in introspection requests
14
20
  */
@@ -19,7 +25,7 @@ export interface GraphQLSDKConfig {
19
25
  */
20
26
  output?: string;
21
27
  /**
22
- * Table filtering options (for table-based CRUD operations from _meta)
28
+ * Table filtering options (for table-based CRUD operations)
23
29
  */
24
30
  tables?: {
25
31
  /** Tables to include (glob patterns supported) */
@@ -154,8 +160,17 @@ export interface ResolvedWatchConfig {
154
160
  /**
155
161
  * Resolved configuration with defaults applied
156
162
  */
157
- export interface ResolvedConfig extends Required<Omit<GraphQLSDKConfig, 'headers' | 'tables' | 'queries' | 'mutations' | 'hooks' | 'postgraphile' | 'codegen' | 'orm' | 'reactQuery' | 'watch'>> {
163
+ export interface ResolvedConfig {
164
+ /**
165
+ * GraphQL endpoint URL (empty string if using schema file)
166
+ */
167
+ endpoint: string;
168
+ /**
169
+ * Path to GraphQL schema file (null if using endpoint)
170
+ */
171
+ schema: string | null;
158
172
  headers: Record<string, string>;
173
+ output: string;
159
174
  tables: {
160
175
  include: string[];
161
176
  exclude: string[];
@@ -168,6 +183,7 @@ export interface ResolvedConfig extends Required<Omit<GraphQLSDKConfig, 'headers
168
183
  include: string[];
169
184
  exclude: string[];
170
185
  };
186
+ excludeFields: string[];
171
187
  hooks: {
172
188
  queries: boolean;
173
189
  mutations: boolean;
@@ -196,7 +212,7 @@ export declare const DEFAULT_WATCH_CONFIG: ResolvedWatchConfig;
196
212
  /**
197
213
  * Default configuration values
198
214
  */
199
- export declare const DEFAULT_CONFIG: Omit<ResolvedConfig, 'endpoint'>;
215
+ export declare const DEFAULT_CONFIG: Omit<ResolvedConfig, 'endpoint' | 'schema'>;
200
216
  /**
201
217
  * Default ORM configuration values
202
218
  */
@@ -65,7 +65,8 @@ export function defineConfig(config) {
65
65
  */
66
66
  export function resolveConfig(config) {
67
67
  return {
68
- endpoint: config.endpoint,
68
+ endpoint: config.endpoint ?? '',
69
+ schema: config.schema ?? null,
69
70
  headers: config.headers ?? DEFAULT_CONFIG.headers,
70
71
  output: config.output ?? DEFAULT_CONFIG.output,
71
72
  tables: {
@@ -42,7 +42,7 @@ exports.buildPostGraphileDelete = buildPostGraphileDelete;
42
42
  */
43
43
  const t = __importStar(require("gql-ast"));
44
44
  const graphql_1 = require("graphql");
45
- const inflection = __importStar(require("inflection"));
45
+ const inflekt_1 = require("inflekt");
46
46
  const typed_document_1 = require("../client/typed-document");
47
47
  const custom_ast_1 = require("../core/custom-ast");
48
48
  const field_selector_1 = require("./field-selector");
@@ -70,7 +70,7 @@ function generateFieldSelections(table) {
70
70
  */
71
71
  function buildPostGraphileCreate(table, _allTables, _options = {}) {
72
72
  const mutationName = `create${table.name}`;
73
- const singularName = inflection.camelize(table.name, true);
73
+ const singularName = (0, inflekt_1.camelize)(table.name, true);
74
74
  // Create the variable definition for $input
75
75
  const variableDefinitions = [
76
76
  t.variableDefinition({
@@ -129,7 +129,7 @@ function buildPostGraphileCreate(table, _allTables, _options = {}) {
129
129
  */
130
130
  function buildPostGraphileUpdate(table, _allTables, _options = {}) {
131
131
  const mutationName = `update${table.name}`;
132
- const singularName = inflection.camelize(table.name, true);
132
+ const singularName = (0, inflekt_1.camelize)(table.name, true);
133
133
  // Create the variable definition for $input
134
134
  const variableDefinitions = [
135
135
  t.variableDefinition({
@@ -47,7 +47,7 @@ exports.buildCount = buildCount;
47
47
  */
48
48
  const t = __importStar(require("gql-ast"));
49
49
  const graphql_1 = require("graphql");
50
- const inflection = __importStar(require("inflection"));
50
+ const inflekt_1 = require("inflekt");
51
51
  const typed_document_1 = require("../client/typed-document");
52
52
  const custom_ast_1 = require("../core/custom-ast");
53
53
  const query_builder_1 = require("../core/query-builder");
@@ -59,9 +59,9 @@ const field_selector_1 = require("./field-selector");
59
59
  */
60
60
  function toCamelCasePlural(tableName) {
61
61
  // First convert to camelCase (lowercase first letter)
62
- const camelCase = inflection.camelize(tableName, true);
62
+ const camelCase = (0, inflekt_1.camelize)(tableName, true);
63
63
  // Then pluralize properly
64
- return inflection.pluralize(camelCase);
64
+ return (0, inflekt_1.pluralize)(camelCase);
65
65
  }
66
66
  /**
67
67
  * Generate the PostGraphile OrderBy enum type name for a table
@@ -144,7 +144,7 @@ function generateIntrospectionSchema(tables) {
144
144
  properties: convertFieldsToProperties(table.fields),
145
145
  };
146
146
  // Add getOne query (by ID)
147
- const singularName = inflection.camelize(modelName, true);
147
+ const singularName = (0, inflekt_1.camelize)(modelName, true);
148
148
  schema[singularName] = {
149
149
  qtype: 'getOne',
150
150
  model: modelName,
@@ -165,8 +165,8 @@ function generateIntrospectionSchema(tables) {
165
165
  isArray: false,
166
166
  isArrayNotNull: false,
167
167
  properties: {
168
- [inflection.camelize(modelName, true)]: {
169
- name: inflection.camelize(modelName, true),
168
+ [(0, inflekt_1.camelize)(modelName, true)]: {
169
+ name: (0, inflekt_1.camelize)(modelName, true),
170
170
  type: `${modelName}Input`,
171
171
  isNotNull: true,
172
172
  isArray: false,
@@ -592,7 +592,7 @@ function findRelatedTable(relationField, table, allTables) {
592
592
  * Generate FindOne query AST directly from CleanTable
593
593
  */
594
594
  function generateFindOneQueryAST(table) {
595
- const singularName = inflection.camelize(table.name, true);
595
+ const singularName = (0, inflekt_1.camelize)(table.name, true);
596
596
  // Generate field selections (include all non-relational fields, including complex types)
597
597
  const fieldSelections = table.fields
598
598
  .filter((field) => !(0, field_selector_1.isRelationalField)(field.name, table))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@constructive-io/graphql-codegen",
3
- "version": "2.22.1",
3
+ "version": "2.23.1",
4
4
  "description": "CLI-based GraphQL SDK generator for PostGraphile endpoints with React Query hooks",
5
5
  "keywords": [
6
6
  "graphql",
@@ -43,6 +43,8 @@
43
43
  "test:watch": "jest --watch",
44
44
  "example:codegen:sdk": "node dist/cli/index.js generate --endpoint http://api.localhost:3000/graphql --output examples/output/generated-sdk",
45
45
  "example:codegen:orm": "node dist/cli/index.js generate-orm --endpoint http://api.localhost:3000/graphql --output examples/output/generated-orm",
46
+ "example:codegen:sdk:schema": "node dist/cli/index.js generate --schema examples/example.schema.graphql --output examples/output/generated-sdk-schema",
47
+ "example:codegen:orm:schema": "node dist/cli/index.js generate-orm --schema examples/example.schema.graphql --output examples/output/generated-orm-schema",
46
48
  "example:sdk": "tsx examples/react-query-sdk.ts",
47
49
  "example:orm": "tsx examples/orm-sdk.ts"
48
50
  },
@@ -51,7 +53,7 @@
51
53
  "commander": "^12.1.0",
52
54
  "gql-ast": "^2.4.6",
53
55
  "graphql": "15.10.1",
54
- "inflection": "^3.0.2",
56
+ "inflekt": "^0.1.2",
55
57
  "jiti": "^2.6.1",
56
58
  "prettier": "^3.7.4",
57
59
  "ts-morph": "^27.0.2"
@@ -79,5 +81,5 @@
79
81
  "tsx": "^4.21.0",
80
82
  "typescript": "^5.9.3"
81
83
  },
82
- "gitHead": "cb086f098f3d82ee9e4eced65383fc3f45253064"
84
+ "gitHead": "22c89cfc6f67879e77ca47f652c31c80828665f5"
83
85
  }
package/types/config.d.ts CHANGED
@@ -6,9 +6,15 @@
6
6
  */
7
7
  export interface GraphQLSDKConfig {
8
8
  /**
9
- * GraphQL endpoint URL (must expose _meta query)
9
+ * GraphQL endpoint URL for live introspection
10
+ * Either endpoint or schema must be provided
10
11
  */
11
- endpoint: string;
12
+ endpoint?: string;
13
+ /**
14
+ * Path to GraphQL schema file (.graphql) for file-based generation
15
+ * Either endpoint or schema must be provided
16
+ */
17
+ schema?: string;
12
18
  /**
13
19
  * Headers to include in introspection requests
14
20
  */
@@ -19,7 +25,7 @@ export interface GraphQLSDKConfig {
19
25
  */
20
26
  output?: string;
21
27
  /**
22
- * Table filtering options (for table-based CRUD operations from _meta)
28
+ * Table filtering options (for table-based CRUD operations)
23
29
  */
24
30
  tables?: {
25
31
  /** Tables to include (glob patterns supported) */
@@ -154,8 +160,17 @@ export interface ResolvedWatchConfig {
154
160
  /**
155
161
  * Resolved configuration with defaults applied
156
162
  */
157
- export interface ResolvedConfig extends Required<Omit<GraphQLSDKConfig, 'headers' | 'tables' | 'queries' | 'mutations' | 'hooks' | 'postgraphile' | 'codegen' | 'orm' | 'reactQuery' | 'watch'>> {
163
+ export interface ResolvedConfig {
164
+ /**
165
+ * GraphQL endpoint URL (empty string if using schema file)
166
+ */
167
+ endpoint: string;
168
+ /**
169
+ * Path to GraphQL schema file (null if using endpoint)
170
+ */
171
+ schema: string | null;
158
172
  headers: Record<string, string>;
173
+ output: string;
159
174
  tables: {
160
175
  include: string[];
161
176
  exclude: string[];
@@ -168,6 +183,7 @@ export interface ResolvedConfig extends Required<Omit<GraphQLSDKConfig, 'headers
168
183
  include: string[];
169
184
  exclude: string[];
170
185
  };
186
+ excludeFields: string[];
171
187
  hooks: {
172
188
  queries: boolean;
173
189
  mutations: boolean;
@@ -196,7 +212,7 @@ export declare const DEFAULT_WATCH_CONFIG: ResolvedWatchConfig;
196
212
  /**
197
213
  * Default configuration values
198
214
  */
199
- export declare const DEFAULT_CONFIG: Omit<ResolvedConfig, 'endpoint'>;
215
+ export declare const DEFAULT_CONFIG: Omit<ResolvedConfig, 'endpoint' | 'schema'>;
200
216
  /**
201
217
  * Default ORM configuration values
202
218
  */
package/types/config.js CHANGED
@@ -70,7 +70,8 @@ function defineConfig(config) {
70
70
  */
71
71
  function resolveConfig(config) {
72
72
  return {
73
- endpoint: config.endpoint,
73
+ endpoint: config.endpoint ?? '',
74
+ schema: config.schema ?? null,
74
75
  headers: config.headers ?? exports.DEFAULT_CONFIG.headers,
75
76
  output: config.output ?? exports.DEFAULT_CONFIG.output,
76
77
  tables: {
@@ -1,31 +0,0 @@
1
- /**
2
- * Fetch _meta query from a PostGraphile endpoint
3
- */
4
- import { type MetaQueryResponse } from './meta-query';
5
- export interface FetchMetaOptions {
6
- /** GraphQL endpoint URL */
7
- endpoint: string;
8
- /** Optional authorization header value (e.g., "Bearer token") */
9
- authorization?: string;
10
- /** Optional additional headers */
11
- headers?: Record<string, string>;
12
- /** Request timeout in milliseconds (default: 30000) */
13
- timeout?: number;
14
- }
15
- export interface FetchMetaResult {
16
- success: boolean;
17
- data?: MetaQueryResponse;
18
- error?: string;
19
- statusCode?: number;
20
- }
21
- /**
22
- * Fetch the _meta query from a PostGraphile endpoint
23
- */
24
- export declare function fetchMeta(options: FetchMetaOptions): Promise<FetchMetaResult>;
25
- /**
26
- * Validate that an endpoint URL is valid
27
- */
28
- export declare function validateEndpoint(endpoint: string): {
29
- valid: boolean;
30
- error?: string;
31
- };
@@ -1,108 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.fetchMeta = fetchMeta;
4
- exports.validateEndpoint = validateEndpoint;
5
- /**
6
- * Fetch _meta query from a PostGraphile endpoint
7
- */
8
- const meta_query_1 = require("./meta-query");
9
- /**
10
- * Fetch the _meta query from a PostGraphile endpoint
11
- */
12
- async function fetchMeta(options) {
13
- const { endpoint, authorization, headers = {}, timeout = 30000 } = options;
14
- // Build headers
15
- const requestHeaders = {
16
- 'Content-Type': 'application/json',
17
- Accept: 'application/json',
18
- ...headers,
19
- };
20
- if (authorization) {
21
- requestHeaders['Authorization'] = authorization;
22
- }
23
- // Create abort controller for timeout
24
- const controller = new AbortController();
25
- const timeoutId = setTimeout(() => controller.abort(), timeout);
26
- try {
27
- const response = await fetch(endpoint, {
28
- method: 'POST',
29
- headers: requestHeaders,
30
- body: JSON.stringify({
31
- query: meta_query_1.META_QUERY,
32
- variables: {},
33
- }),
34
- signal: controller.signal,
35
- });
36
- clearTimeout(timeoutId);
37
- if (!response.ok) {
38
- return {
39
- success: false,
40
- error: `HTTP ${response.status}: ${response.statusText}`,
41
- statusCode: response.status,
42
- };
43
- }
44
- const json = (await response.json());
45
- // Check for GraphQL errors
46
- if (json.errors && json.errors.length > 0) {
47
- const errorMessages = json.errors.map((e) => e.message).join('; ');
48
- return {
49
- success: false,
50
- error: `GraphQL errors: ${errorMessages}`,
51
- statusCode: response.status,
52
- };
53
- }
54
- // Check if _meta is present
55
- if (!json.data?._meta) {
56
- return {
57
- success: false,
58
- error: 'No _meta field in response. Make sure the endpoint has the PostGraphile meta plugin installed.',
59
- statusCode: response.status,
60
- };
61
- }
62
- return {
63
- success: true,
64
- data: json.data,
65
- statusCode: response.status,
66
- };
67
- }
68
- catch (err) {
69
- clearTimeout(timeoutId);
70
- if (err instanceof Error) {
71
- if (err.name === 'AbortError') {
72
- return {
73
- success: false,
74
- error: `Request timeout after ${timeout}ms`,
75
- };
76
- }
77
- return {
78
- success: false,
79
- error: err.message,
80
- };
81
- }
82
- return {
83
- success: false,
84
- error: 'Unknown error occurred',
85
- };
86
- }
87
- }
88
- /**
89
- * Validate that an endpoint URL is valid
90
- */
91
- function validateEndpoint(endpoint) {
92
- try {
93
- const url = new URL(endpoint);
94
- if (!['http:', 'https:'].includes(url.protocol)) {
95
- return {
96
- valid: false,
97
- error: 'Endpoint must use http or https protocol',
98
- };
99
- }
100
- return { valid: true };
101
- }
102
- catch {
103
- return {
104
- valid: false,
105
- error: 'Invalid URL format',
106
- };
107
- }
108
- }