@constructive-io/graphql-codegen 4.1.2 → 4.1.3

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.
@@ -69,8 +69,40 @@ function buildErrorCatch(errorMessage) {
69
69
  t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('process'), t.identifier('exit')), [t.numericLiteral(1)])),
70
70
  ]));
71
71
  }
72
- function buildOrmCustomCall(opKind, opName, argsExpr) {
73
- return t.callExpression(t.memberExpression(t.callExpression(t.memberExpression(t.memberExpression(t.identifier('client'), t.identifier(opKind)), t.identifier(opName)), [argsExpr]), t.identifier('execute')), []);
72
+ /**
73
+ * Unwrap NON_NULL / LIST wrappers to get the underlying named type.
74
+ */
75
+ function unwrapType(ref) {
76
+ if ((ref.kind === 'NON_NULL' || ref.kind === 'LIST') && ref.ofType) {
77
+ return unwrapType(ref.ofType);
78
+ }
79
+ return ref;
80
+ }
81
+ /**
82
+ * Build a select object expression from return-type fields.
83
+ * If the return type has known fields, generates { field1: true, field2: true, ... }.
84
+ * Falls back to { clientMutationId: true } for mutations without known fields.
85
+ */
86
+ function buildSelectObject(returnType, isMutation) {
87
+ const base = unwrapType(returnType);
88
+ if (base.fields && base.fields.length > 0) {
89
+ return t.objectExpression(base.fields.map((f) => t.objectProperty(t.identifier(f.name), t.booleanLiteral(true))));
90
+ }
91
+ // Fallback: all PostGraphile mutation payloads have clientMutationId
92
+ if (isMutation) {
93
+ return t.objectExpression([
94
+ t.objectProperty(t.identifier('clientMutationId'), t.booleanLiteral(true)),
95
+ ]);
96
+ }
97
+ return t.objectExpression([]);
98
+ }
99
+ function buildOrmCustomCall(opKind, opName, argsExpr, selectExpr) {
100
+ return t.callExpression(t.memberExpression(t.callExpression(t.memberExpression(t.memberExpression(t.identifier('client'), t.identifier(opKind)), t.identifier(opName)), [
101
+ argsExpr,
102
+ t.objectExpression([
103
+ t.objectProperty(t.identifier('select'), selectExpr),
104
+ ]),
105
+ ]), t.identifier('execute')), []);
74
106
  }
75
107
  function generateCustomCommand(op, options) {
76
108
  const commandName = (0, komoji_1.toKebabCase)(op.name);
@@ -81,8 +113,19 @@ function generateCustomCommand(op, options) {
81
113
  if (options?.saveToken) {
82
114
  imports.push('getStore');
83
115
  }
116
+ // Check if any argument is an INPUT_OBJECT (i.e. takes JSON input like { input: SomeInput })
117
+ const hasInputObjectArg = op.args.some((arg) => {
118
+ const base = unwrapType(arg.type);
119
+ return base.kind === 'INPUT_OBJECT';
120
+ });
121
+ const utilsPath = options?.executorImportPath
122
+ ? options.executorImportPath.replace(/\/executor$/, '/utils')
123
+ : '../utils';
84
124
  statements.push(createImportDeclaration('inquirerer', ['CLIOptions', 'Inquirerer']));
85
125
  statements.push(createImportDeclaration(executorPath, imports));
126
+ if (hasInputObjectArg) {
127
+ statements.push(createImportDeclaration(utilsPath, ['parseMutationInput']));
128
+ }
86
129
  const questionsArray = op.args.length > 0
87
130
  ? (0, arg_mapper_1.buildQuestionsArray)(op.args)
88
131
  : t.arrayExpression([]);
@@ -111,11 +154,23 @@ function generateCustomCommand(op, options) {
111
154
  bodyStatements.push(t.variableDeclaration('const', [
112
155
  t.variableDeclarator(t.identifier('client'), t.callExpression(t.identifier('getClient'), getClientArgs)),
113
156
  ]));
157
+ // For mutations with INPUT_OBJECT args (like `input: SignUpInput`),
158
+ // parse JSON strings from CLI into proper objects
159
+ if (hasInputObjectArg && op.args.length > 0) {
160
+ bodyStatements.push(t.variableDeclaration('const', [
161
+ t.variableDeclarator(t.identifier('parsedAnswers'), t.callExpression(t.identifier('parseMutationInput'), [
162
+ t.identifier('answers'),
163
+ ])),
164
+ ]));
165
+ }
114
166
  const argsExpr = op.args.length > 0
115
- ? t.identifier('answers')
167
+ ? (hasInputObjectArg
168
+ ? t.identifier('parsedAnswers')
169
+ : t.identifier('answers'))
116
170
  : t.objectExpression([]);
171
+ const selectExpr = buildSelectObject(op.returnType, op.kind === 'mutation');
117
172
  bodyStatements.push(t.variableDeclaration('const', [
118
- t.variableDeclarator(t.identifier('result'), t.awaitExpression(buildOrmCustomCall(opKind, op.name, argsExpr))),
173
+ t.variableDeclarator(t.identifier('result'), t.awaitExpression(buildOrmCustomCall(opKind, op.name, argsExpr, selectExpr))),
119
174
  ]));
120
175
  if (options?.saveToken) {
121
176
  bodyStatements.push(t.ifStatement(t.logicalExpression('&&', t.memberExpression(t.identifier('argv'), t.identifier('saveToken')), t.identifier('result')), t.blockStatement([
@@ -33,8 +33,40 @@ function buildErrorCatch(errorMessage) {
33
33
  t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('process'), t.identifier('exit')), [t.numericLiteral(1)])),
34
34
  ]));
35
35
  }
36
- function buildOrmCustomCall(opKind, opName, argsExpr) {
37
- return t.callExpression(t.memberExpression(t.callExpression(t.memberExpression(t.memberExpression(t.identifier('client'), t.identifier(opKind)), t.identifier(opName)), [argsExpr]), t.identifier('execute')), []);
36
+ /**
37
+ * Unwrap NON_NULL / LIST wrappers to get the underlying named type.
38
+ */
39
+ function unwrapType(ref) {
40
+ if ((ref.kind === 'NON_NULL' || ref.kind === 'LIST') && ref.ofType) {
41
+ return unwrapType(ref.ofType);
42
+ }
43
+ return ref;
44
+ }
45
+ /**
46
+ * Build a select object expression from return-type fields.
47
+ * If the return type has known fields, generates { field1: true, field2: true, ... }.
48
+ * Falls back to { clientMutationId: true } for mutations without known fields.
49
+ */
50
+ function buildSelectObject(returnType, isMutation) {
51
+ const base = unwrapType(returnType);
52
+ if (base.fields && base.fields.length > 0) {
53
+ return t.objectExpression(base.fields.map((f) => t.objectProperty(t.identifier(f.name), t.booleanLiteral(true))));
54
+ }
55
+ // Fallback: all PostGraphile mutation payloads have clientMutationId
56
+ if (isMutation) {
57
+ return t.objectExpression([
58
+ t.objectProperty(t.identifier('clientMutationId'), t.booleanLiteral(true)),
59
+ ]);
60
+ }
61
+ return t.objectExpression([]);
62
+ }
63
+ function buildOrmCustomCall(opKind, opName, argsExpr, selectExpr) {
64
+ return t.callExpression(t.memberExpression(t.callExpression(t.memberExpression(t.memberExpression(t.identifier('client'), t.identifier(opKind)), t.identifier(opName)), [
65
+ argsExpr,
66
+ t.objectExpression([
67
+ t.objectProperty(t.identifier('select'), selectExpr),
68
+ ]),
69
+ ]), t.identifier('execute')), []);
38
70
  }
39
71
  export function generateCustomCommand(op, options) {
40
72
  const commandName = toKebabCase(op.name);
@@ -45,8 +77,19 @@ export function generateCustomCommand(op, options) {
45
77
  if (options?.saveToken) {
46
78
  imports.push('getStore');
47
79
  }
80
+ // Check if any argument is an INPUT_OBJECT (i.e. takes JSON input like { input: SomeInput })
81
+ const hasInputObjectArg = op.args.some((arg) => {
82
+ const base = unwrapType(arg.type);
83
+ return base.kind === 'INPUT_OBJECT';
84
+ });
85
+ const utilsPath = options?.executorImportPath
86
+ ? options.executorImportPath.replace(/\/executor$/, '/utils')
87
+ : '../utils';
48
88
  statements.push(createImportDeclaration('inquirerer', ['CLIOptions', 'Inquirerer']));
49
89
  statements.push(createImportDeclaration(executorPath, imports));
90
+ if (hasInputObjectArg) {
91
+ statements.push(createImportDeclaration(utilsPath, ['parseMutationInput']));
92
+ }
50
93
  const questionsArray = op.args.length > 0
51
94
  ? buildQuestionsArray(op.args)
52
95
  : t.arrayExpression([]);
@@ -75,11 +118,23 @@ export function generateCustomCommand(op, options) {
75
118
  bodyStatements.push(t.variableDeclaration('const', [
76
119
  t.variableDeclarator(t.identifier('client'), t.callExpression(t.identifier('getClient'), getClientArgs)),
77
120
  ]));
121
+ // For mutations with INPUT_OBJECT args (like `input: SignUpInput`),
122
+ // parse JSON strings from CLI into proper objects
123
+ if (hasInputObjectArg && op.args.length > 0) {
124
+ bodyStatements.push(t.variableDeclaration('const', [
125
+ t.variableDeclarator(t.identifier('parsedAnswers'), t.callExpression(t.identifier('parseMutationInput'), [
126
+ t.identifier('answers'),
127
+ ])),
128
+ ]));
129
+ }
78
130
  const argsExpr = op.args.length > 0
79
- ? t.identifier('answers')
131
+ ? (hasInputObjectArg
132
+ ? t.identifier('parsedAnswers')
133
+ : t.identifier('answers'))
80
134
  : t.objectExpression([]);
135
+ const selectExpr = buildSelectObject(op.returnType, op.kind === 'mutation');
81
136
  bodyStatements.push(t.variableDeclaration('const', [
82
- t.variableDeclarator(t.identifier('result'), t.awaitExpression(buildOrmCustomCall(opKind, op.name, argsExpr))),
137
+ t.variableDeclarator(t.identifier('result'), t.awaitExpression(buildOrmCustomCall(opKind, op.name, argsExpr, selectExpr))),
83
138
  ]));
84
139
  if (options?.saveToken) {
85
140
  bodyStatements.push(t.ifStatement(t.logicalExpression('&&', t.memberExpression(t.identifier('argv'), t.identifier('saveToken')), t.identifier('result')), t.blockStatement([
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@constructive-io/graphql-codegen",
3
- "version": "4.1.2",
3
+ "version": "4.1.3",
4
4
  "description": "GraphQL SDK generator for Constructive databases with React Query hooks",
5
5
  "keywords": [
6
6
  "graphql",
@@ -100,5 +100,5 @@
100
100
  "tsx": "^4.21.0",
101
101
  "typescript": "^5.9.3"
102
102
  },
103
- "gitHead": "f6fa9972bcbf6ffaa6340c514462e7a6d0cb4426"
103
+ "gitHead": "f80e2e5e112cab91eac53e61c5b257f4ac88efb2"
104
104
  }