@comet/admin-generator 9.0.0-canary-20251002124333 → 9.0.0-canary-20251113142723

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 (36) hide show
  1. package/lib/commands/generate/config/transformConfig.d.ts +6 -0
  2. package/lib/commands/generate/config/transformConfig.js +36 -8
  3. package/lib/commands/generate/generate-command.d.ts +49 -15
  4. package/lib/commands/generate/generate-command.js +5 -0
  5. package/lib/commands/generate/generateForm/asyncSelect/generateAsyncSelect.js +46 -22
  6. package/lib/commands/generate/generateForm/flatFormFieldsFromFormConfig.d.ts +2 -0
  7. package/lib/commands/generate/generateForm/flatFormFieldsFromFormConfig.js +22 -0
  8. package/lib/commands/generate/generateForm/formField/findIntrospectionFieldType.d.ts +6 -0
  9. package/lib/commands/generate/generateForm/formField/findIntrospectionFieldType.js +22 -0
  10. package/lib/commands/generate/generateForm/formField/options.d.ts +1 -5
  11. package/lib/commands/generate/generateForm/formField/options.js +2 -11
  12. package/lib/commands/generate/generateForm/generateComponentFormField.js +0 -1
  13. package/lib/commands/generate/generateForm/generateFields.d.ts +9 -4
  14. package/lib/commands/generate/generateForm/generateFields.js +0 -3
  15. package/lib/commands/generate/generateForm/generateForm.js +99 -132
  16. package/lib/commands/generate/generateForm/generateFormField.js +34 -44
  17. package/lib/commands/generate/generateForm/generateFormLayout.js +23 -44
  18. package/lib/commands/generate/generateForm/generateFormValues.d.ts +39 -0
  19. package/lib/commands/generate/generateForm/generateFormValues.js +217 -0
  20. package/lib/commands/generate/generateForm/generateFragmentByFormFragmentFields.d.ts +1 -1
  21. package/lib/commands/generate/generateForm/generateFragmentByFormFragmentFields.js +3 -36
  22. package/lib/commands/generate/generateForm/getForwardedGqlArgs.d.ts +4 -5
  23. package/lib/commands/generate/generateForm/getForwardedGqlArgs.js +18 -17
  24. package/lib/commands/generate/generateGrid/generateGrid.js +49 -35
  25. package/lib/commands/generate/generateGrid/getForwardedGqlArgs.d.ts +3 -3
  26. package/lib/commands/generate/generateGrid/getForwardedGqlArgs.js +12 -16
  27. package/lib/commands/generate/generateGrid/usableFields.d.ts +6 -1
  28. package/lib/commands/generate/utils/convertConfigImport.d.ts +1 -0
  29. package/lib/commands/generate/utils/convertConfigImport.js +1 -1
  30. package/lib/commands/generate/utils/generateGqlOperation.d.ts +12 -0
  31. package/lib/commands/generate/utils/generateGqlOperation.js +87 -0
  32. package/lib/commands/generate/utils/generateImportsCode.d.ts +1 -0
  33. package/lib/commands/generate/utils/generateImportsCode.js +6 -1
  34. package/lib/index.d.ts +2 -2
  35. package/lib/index.js +2 -1
  36. package/package.json +11 -8
@@ -1 +1,7 @@
1
+ import * as ts from "typescript";
1
2
  export declare function transformConfigFile(fileName: string, sourceText: string): string;
3
+ export declare function collectImports(rootNode: ts.Node): Map<string, {
4
+ name: string;
5
+ import: string;
6
+ defaultImport?: boolean;
7
+ }>;
@@ -34,6 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.transformConfigFile = transformConfigFile;
37
+ exports.collectImports = collectImports;
37
38
  const ts = __importStar(require("typescript"));
38
39
  const supportedImportPaths = [
39
40
  "[type=grid].columns.filterOperators",
@@ -60,6 +61,21 @@ function transformConfigFile(fileName, sourceText) {
60
61
  function configTransformer() {
61
62
  return (context) => {
62
63
  const visit = (node, path) => {
64
+ if (ts.isCallExpression(node)) {
65
+ if (node.expression.getText() === "injectFormVariables") {
66
+ if (!path.startsWith("[type=form].fields")) {
67
+ throw new Error(`injectFormVariables can only be used in form field definitions: ${path}`);
68
+ }
69
+ if (node.arguments.length !== 1) {
70
+ throw new Error(`injectFormVariables expects exactly one argument`);
71
+ }
72
+ const injectFormVariablesArg = node.arguments[0];
73
+ if (!ts.isArrowFunction(injectFormVariablesArg)) {
74
+ throw new Error(`injectFormVariables expects an arrow function as its argument`);
75
+ }
76
+ node = injectFormVariablesArg.body;
77
+ }
78
+ }
63
79
  if (ts.isArrowFunction(node)) {
64
80
  if (supportedInlineCodePaths.includes(path)) {
65
81
  let code = node.getText();
@@ -73,6 +89,9 @@ function transformConfigFile(fileName, sourceText) {
73
89
  return ts.factory.createObjectLiteralExpression([
74
90
  ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(imprt.name)),
75
91
  ts.factory.createPropertyAssignment("import", ts.factory.createStringLiteral(imprt.import)),
92
+ ...(imprt.defaultImport
93
+ ? [ts.factory.createPropertyAssignment("defaultImport", ts.factory.createTrue())]
94
+ : []),
76
95
  ]);
77
96
  }))),
78
97
  ], true);
@@ -193,16 +212,25 @@ function getTypePropertyFromObjectLiteral(node) {
193
212
  function collectImports(rootNode) {
194
213
  const importedIdentifiers = new Map();
195
214
  function visit(node) {
196
- if (ts.isImportDeclaration(node) &&
197
- node.importClause &&
198
- node.importClause.namedBindings &&
199
- ts.isNamedImports(node.importClause.namedBindings)) {
215
+ if (ts.isImportDeclaration(node) && node.importClause) {
200
216
  const moduleSpecifier = node.moduleSpecifier.text;
201
- for (const element of node.importClause.namedBindings.elements) {
202
- const localName = element.name.text;
203
- const originalName = element.propertyName ? element.propertyName.text : localName;
217
+ if (node.importClause.namedBindings && ts.isNamedImports(node.importClause.namedBindings)) {
218
+ //named import
219
+ for (const element of node.importClause.namedBindings.elements) {
220
+ const localName = element.name.text;
221
+ const originalName = element.propertyName ? element.propertyName.text : localName;
222
+ importedIdentifiers.set(localName, {
223
+ name: originalName,
224
+ import: moduleSpecifier,
225
+ });
226
+ }
227
+ }
228
+ else if (node.importClause.name && ts.isIdentifier(node.importClause.name)) {
229
+ //default import
230
+ const localName = node.importClause.name.text;
204
231
  importedIdentifiers.set(localName, {
205
- name: originalName,
232
+ defaultImport: true,
233
+ name: localName,
206
234
  import: moduleSpecifier,
207
235
  });
208
236
  }
@@ -1,12 +1,13 @@
1
+ import { type ApolloClient } from "@apollo/client";
1
2
  import { type GridColDef } from "@comet/admin";
2
3
  import { type IconName } from "@comet/admin-icons";
3
- import { type BlockInterface, type FinalFormFileUploadProps } from "@comet/cms-admin";
4
+ import { type BlockInterface, type ContentScope, type FinalFormFileUploadProps } from "@comet/cms-admin";
4
5
  import { type IconProps } from "@mui/material";
5
6
  import { type GridCellParams, type GridFilterItem, type GridFilterOperator, type GridRenderCellParams, type GridSortDirection, type GridValidRowModel } from "@mui/x-data-grid";
6
7
  import { Command } from "commander";
7
- import { type FieldValidator } from "final-form";
8
+ import { type FieldValidator, type FormApi } from "final-form";
8
9
  import { type ComponentType } from "react";
9
- import { type UsableFields } from "./generateGrid/usableFields";
10
+ import { type UsableFields, type UsableFormFields } from "./generateGrid/usableFields";
10
11
  import { type ColumnVisibleOption } from "./utils/columnVisibility";
11
12
  type IconObject = Pick<IconProps, "color" | "fontSize"> & {
12
13
  name: IconName;
@@ -60,37 +61,42 @@ type AsyncSelectFilter = {
60
61
  };
61
62
  export type FormFieldConfig<T> = (({
62
63
  type: "text";
63
- name: keyof T;
64
+ name: UsableFormFields<T>;
64
65
  multiline?: boolean;
65
66
  } & InputBaseFieldConfig) | ({
66
67
  type: "number";
67
- name: keyof T;
68
+ name: UsableFormFields<T>;
68
69
  decimals?: number;
69
70
  } & InputBaseFieldConfig) | ({
70
71
  type: "numberRange";
71
- name: keyof T;
72
+ name: UsableFormFields<T>;
72
73
  minValue: number;
73
74
  maxValue: number;
74
75
  disableSlider?: boolean;
75
76
  } & InputBaseFieldConfig) | {
76
77
  type: "boolean";
77
- name: keyof T;
78
+ name: UsableFormFields<T>;
78
79
  } | ({
79
80
  type: "date";
80
- name: keyof T;
81
+ name: UsableFormFields<T>;
81
82
  } & InputBaseFieldConfig) | ({
82
83
  type: "dateTime";
83
- name: keyof T;
84
+ name: UsableFormFields<T>;
84
85
  } & InputBaseFieldConfig) | ({
85
86
  type: "staticSelect";
86
- name: keyof T;
87
+ name: UsableFormFields<T>;
87
88
  values?: StaticSelectValue[];
88
89
  inputType?: "select" | "radio";
89
90
  } & Omit<InputBaseFieldConfig, "endAdornment">) | ({
90
91
  type: "asyncSelect";
91
- name: keyof T;
92
+ name: UsableFormFields<T>;
92
93
  rootQuery: string;
93
94
  labelField?: string;
95
+ /** Whether Autocomplete or Select should be used.
96
+ *
97
+ * defaults to true if rootQuery has a search argument
98
+ */
99
+ autocomplete?: boolean;
94
100
  /**
95
101
  * filter for query, passed as variable to graphql query
96
102
  */
@@ -101,24 +107,29 @@ export type FormFieldConfig<T> = (({
101
107
  loadValueQueryField: string;
102
108
  rootQuery: string;
103
109
  labelField?: string;
110
+ /** Whether Autocomplete or Select should be used.
111
+ *
112
+ * defaults to true if rootQuery has a search argument
113
+ */
114
+ autocomplete?: boolean;
104
115
  /**
105
116
  * filter for query, passed as variable to graphql query
106
117
  */
107
118
  filter?: AsyncSelectFilter;
108
119
  } & Omit<InputBaseFieldConfig, "endAdornment">) | {
109
120
  type: "block";
110
- name: keyof T;
121
+ name: UsableFormFields<T>;
111
122
  block: BlockInterface;
112
123
  } | ({
113
124
  type: "fileUpload";
114
125
  multiple?: false;
115
- name: keyof T;
126
+ name: UsableFormFields<T>;
116
127
  maxFiles?: 1;
117
128
  download?: boolean;
118
129
  } & Pick<Partial<FinalFormFileUploadProps<false>>, "maxFileSize" | "readOnly" | "layout" | "accept">) | ({
119
130
  type: "fileUpload";
120
131
  multiple: true;
121
- name: keyof T;
132
+ name: UsableFormFields<T>;
122
133
  maxFiles?: number;
123
134
  download?: boolean;
124
135
  } & Pick<Partial<FinalFormFileUploadProps<true>>, "maxFileSize" | "readOnly" | "layout" | "accept">)) & {
@@ -131,7 +142,7 @@ export type FormFieldConfig<T> = (({
131
142
  export declare function isFormFieldConfig<T>(arg: any): arg is FormFieldConfig<T>;
132
143
  type OptionalNestedFieldsConfig<T> = {
133
144
  type: "optionalNestedFields";
134
- name: keyof T;
145
+ name: UsableFormFields<T>;
135
146
  checkboxLabel?: string;
136
147
  fields: FormFieldConfig<any>[];
137
148
  };
@@ -153,8 +164,26 @@ export type FormConfig<T extends {
153
164
  mode?: "edit" | "add" | "all";
154
165
  fragmentName?: string;
155
166
  createMutation?: string;
167
+ /**
168
+ * If true, scope will be passed as prop, if false scope will be fetched from ContentScopeContext
169
+ * @default false
170
+ */
171
+ scopeAsProp?: boolean;
156
172
  fields: (FormFieldConfig<T> | FormLayoutConfig<T> | ComponentFormFieldConfig)[];
173
+ /**
174
+ * If true, the form will navigate to the edit page using stackSwitchApi.activatePage of the newly created item after a successful creation.
175
+ * @default true
176
+ */
177
+ navigateOnCreate?: boolean;
178
+ };
179
+ export type InjectedFormVariables = {
180
+ id?: string;
181
+ mode?: "edit" | "add";
182
+ client: ApolloClient<object>;
183
+ formApi: FormApi<unknown, Partial<unknown>>;
184
+ scope: ContentScope;
157
185
  };
186
+ export declare function injectFormVariables<T>(fn: (injectedVariables: InjectedFormVariables) => T): T;
158
187
  type BaseColumnConfig = Pick<GridColDef, "headerName" | "width" | "minWidth" | "maxWidth" | "flex" | "pinned" | "disableExport"> & {
159
188
  headerInfoTooltip?: string;
160
189
  visible?: ColumnVisibleOption;
@@ -262,6 +291,11 @@ export type GridConfig<T extends {
262
291
  enabled: boolean;
263
292
  dragPreviewField?: UsableFields<T>;
264
293
  };
294
+ /**
295
+ * If true, scope will be passed as prop, if false scope will be fetched from ContentScopeContext
296
+ * @default false
297
+ */
298
+ scopeAsProp?: boolean;
265
299
  };
266
300
  export type GeneratorConfig<T extends {
267
301
  __typename?: string;
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.generateCommand = void 0;
13
13
  exports.isFormFieldConfig = isFormFieldConfig;
14
14
  exports.isFormLayoutConfig = isFormLayoutConfig;
15
+ exports.injectFormVariables = injectFormVariables;
15
16
  exports.defineConfig = defineConfig;
16
17
  const graphql_file_loader_1 = require("@graphql-tools/graphql-file-loader");
17
18
  const load_1 = require("@graphql-tools/load");
@@ -33,6 +34,10 @@ function isFormFieldConfig(arg) {
33
34
  function isFormLayoutConfig(arg) {
34
35
  return arg.type !== undefined && ["fieldSet", "optionalNestedFields"].includes(arg.type);
35
36
  }
37
+ function injectFormVariables(fn) {
38
+ // this function is only used in config but never called at runtime
39
+ return fn({});
40
+ }
36
41
  function defineConfig(config) {
37
42
  return config;
38
43
  }
@@ -4,6 +4,7 @@ exports.findIntrospectionObjectType = findIntrospectionObjectType;
4
4
  exports.generateAsyncSelect = generateAsyncSelect;
5
5
  const generate_command_1 = require("../../generate-command");
6
6
  const findQueryType_1 = require("../../utils/findQueryType");
7
+ const generateGqlOperation_1 = require("../../utils/generateGqlOperation");
7
8
  const isFieldOptional_1 = require("../../utils/isFieldOptional");
8
9
  const options_1 = require("../formField/options");
9
10
  const generateFields_1 = require("../generateFields");
@@ -100,21 +101,21 @@ function findIntrospectionObjectType({ config, gqlIntrospection, gqlType, }) {
100
101
  }
101
102
  }
102
103
  function generateAsyncSelect({ gqlIntrospection, baseOutputFilename, config, formConfig, gqlType, namePrefix, }) {
103
- var _a, _b;
104
+ var _a, _b, _c;
104
105
  const imports = [];
105
106
  const formProps = [];
106
107
  const { name, fieldLabel, startAdornment,
107
108
  //endAdornment,
108
- imports: optionsImports, } = (0, options_1.buildFormFieldOptions)({ config, formConfig, gqlIntrospection, gqlType });
109
+ imports: optionsImports, } = (0, options_1.buildFormFieldOptions)({ config, formConfig });
109
110
  imports.push(...optionsImports);
110
111
  const nameWithPrefix = `${namePrefix ? `${namePrefix}.` : ``}${name}`;
111
112
  const required = !(0, isFieldOptional_1.isFieldOptional)({ config, gqlIntrospection, gqlType });
112
113
  const formValueConfig = {
113
- destructFromFormValues: config.type == "asyncSelectFilter" ? name : undefined,
114
+ fieldName: name,
115
+ destructFromFormValues: config.type == "asyncSelectFilter",
114
116
  };
115
117
  let finalFormConfig;
116
118
  let code = "";
117
- let formValueToGqlInputCode = "";
118
119
  const { objectType, multiple } = findIntrospectionObjectType({
119
120
  config,
120
121
  gqlIntrospection,
@@ -154,6 +155,16 @@ function generateAsyncSelect({ gqlIntrospection, baseOutputFilename, config, for
154
155
  else {
155
156
  formFragmentFields = [`${name}.id`, `${name}.${labelField}`];
156
157
  }
158
+ const rootQueryHasSearchArg = rootQueryType.args.find((arg) => arg.name === "search");
159
+ const useAutocomplete = (_c = config.autocomplete) !== null && _c !== void 0 ? _c : !!rootQueryHasSearchArg;
160
+ if (useAutocomplete) {
161
+ if (!rootQueryHasSearchArg) {
162
+ throw new Error(`Field ${String(config.name)}: Autocomplete is enabled but root query "${rootQuery}" has no search argument.`);
163
+ }
164
+ if (rootQueryHasSearchArg.type.kind !== "SCALAR" || rootQueryHasSearchArg.type.name !== "String") {
165
+ throw new Error(`Field ${String(config.name)}: Autocomplete is enabled but root query "${rootQuery}" has search argument that is not a string.`);
166
+ }
167
+ }
157
168
  const filterConfig = config.filter
158
169
  ? (() => {
159
170
  var _a;
@@ -267,14 +278,14 @@ function generateAsyncSelect({ gqlIntrospection, baseOutputFilename, config, for
267
278
  if (config.type != "asyncSelectFilter") {
268
279
  if (!multiple) {
269
280
  if (!required) {
270
- formValueToGqlInputCode = `${name}: formValues.${name} ? formValues.${name}.id : null,`;
281
+ formValueConfig.formValueToGqlInputCode = `$fieldName ? $fieldName.id : null`;
271
282
  }
272
283
  else {
273
- formValueToGqlInputCode = `${name}: formValues.${name}?.id,`;
284
+ formValueConfig.formValueToGqlInputCode = `$fieldName?.id`;
274
285
  }
275
286
  }
276
287
  else {
277
- formValueToGqlInputCode = `${name}: formValues.${name}.map((item) => item.id),`;
288
+ formValueConfig.formValueToGqlInputCode = `$fieldName.map((item) => item.id)`;
278
289
  }
279
290
  }
280
291
  imports.push({
@@ -285,13 +296,19 @@ function generateAsyncSelect({ gqlIntrospection, baseOutputFilename, config, for
285
296
  name: `GQL${queryName}QueryVariables`,
286
297
  importPath: `./${baseOutputFilename}.generated`,
287
298
  });
299
+ if (useAutocomplete) {
300
+ imports.push({ name: "AsyncAutocompleteField", importPath: "@comet/admin" });
301
+ }
302
+ else {
303
+ imports.push({ name: "AsyncSelectField", importPath: "@comet/admin" });
304
+ }
288
305
  const instanceGqlType = gqlType[0].toLowerCase() + gqlType.substring(1);
289
306
  if (config.type == "asyncSelectFilter") {
290
307
  // add (in the gql schema) non existing value for virtual filter field
291
- formValueConfig.typeCode = `${name}?: { id: string; ${labelField}: string };`;
292
- formValueConfig.initializationCode = `${name}: data.${instanceGqlType}.${config.loadValueQueryField.replace(/\./g, "?.")}`;
308
+ formValueConfig.typeCode = { nullable: true, type: `{ id: string; ${labelField}: string }` };
309
+ formValueConfig.initializationCode = `data.${instanceGqlType}.${config.loadValueQueryField.replace(/\./g, "?.")}`;
293
310
  }
294
- code = `<AsyncSelectField
311
+ code = `<${useAutocomplete ? "AsyncAutocompleteField" : "AsyncSelectField"}
295
312
  ${required ? "required" : ""}
296
313
  variant="horizontal"
297
314
  fullWidth
@@ -300,18 +317,26 @@ function generateAsyncSelect({ gqlIntrospection, baseOutputFilename, config, for
300
317
  name="${nameWithPrefix}"
301
318
  label={${fieldLabel}}
302
319
  ${config.startAdornment ? `startAdornment={<InputAdornment position="start">${startAdornment.adornmentString}</InputAdornment>}` : ""}
303
- loadOptions={async () => {
320
+ loadOptions={async (${useAutocomplete ? `search?: string` : ""}) => {
304
321
  const { data } = await client.query<GQL${queryName}Query, GQL${queryName}QueryVariables>({
305
- query: gql\`query ${queryName}${filterConfig
306
- ? `($${filterConfig.filterVarName}: ${filterConfig.filterType.typeClass}${filterConfig.filterType.required ? `!` : ``})`
307
- : ``} {
308
- ${rootQuery}${filterConfig ? `(${filterConfig.filterVarName}: $${filterConfig.filterVarName})` : ``} {
309
- nodes {
310
- id
311
- ${labelField}
312
- }
313
- }
314
- }\`${filterConfig ? `, variables: { ${filterConfig.filterVarName}: ${filterConfig.filterVarValue} }` : ``}
322
+ query: gql\`${(0, generateGqlOperation_1.generateGqlOperation)({
323
+ type: "query",
324
+ operationName: queryName,
325
+ rootOperation: rootQuery,
326
+ fields: ["nodes.id", `nodes.${labelField}`],
327
+ variables: [
328
+ useAutocomplete ? { name: "search", type: "String" } : undefined,
329
+ filterConfig
330
+ ? {
331
+ name: filterConfig.filterVarName,
332
+ type: filterConfig.filterType.typeClass + (filterConfig.filterType.required ? `!` : ``),
333
+ }
334
+ : undefined,
335
+ ].filter((v) => v !== undefined),
336
+ })}\`${filterConfig || useAutocomplete ? ", variables: { " : ""}
337
+ ${filterConfig ? `${filterConfig.filterVarName}: ${filterConfig.filterVarValue},` : ``}
338
+ ${useAutocomplete ? `search,` : ``}
339
+ ${filterConfig || useAutocomplete ? " }" : ""}
315
340
  });
316
341
  return data.${rootQuery}.nodes;
317
342
  }}
@@ -329,7 +354,6 @@ function generateAsyncSelect({ gqlIntrospection, baseOutputFilename, config, for
329
354
  return {
330
355
  code,
331
356
  hooksCode: "",
332
- formValueToGqlInputCode,
333
357
  formFragmentFields,
334
358
  gqlDocuments: {},
335
359
  imports,
@@ -0,0 +1,2 @@
1
+ import { type FormConfig, type FormFieldConfig } from "../generate-command";
2
+ export declare function flatFormFieldsFromFormConfig(config: FormConfig<any>): FormFieldConfig<any>[];
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.flatFormFieldsFromFormConfig = flatFormFieldsFromFormConfig;
4
+ const generate_command_1 = require("../generate-command");
5
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6
+ function flatFormFieldsFromFormConfig(config) {
7
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
8
+ return config.fields.reduce((acc, field) => {
9
+ if ((0, generate_command_1.isFormLayoutConfig)(field)) {
10
+ // using forEach instead of acc.push(...field.fields.filter(isFormFieldConfig)) because typescript can't handle mixed typing
11
+ field.fields.forEach((nestedFieldConfig) => {
12
+ if ((0, generate_command_1.isFormFieldConfig)(nestedFieldConfig)) {
13
+ acc.push(nestedFieldConfig);
14
+ }
15
+ });
16
+ }
17
+ else if ((0, generate_command_1.isFormFieldConfig)(field)) {
18
+ acc.push(field);
19
+ }
20
+ return acc;
21
+ }, []);
22
+ }
@@ -0,0 +1,6 @@
1
+ import { type IntrospectionQuery } from "graphql";
2
+ export declare function findIntrospectionFieldType({ name, gqlType, gqlIntrospection, }: {
3
+ name: string;
4
+ gqlType: string;
5
+ gqlIntrospection: IntrospectionQuery;
6
+ }): import("graphql").IntrospectionNamedTypeRef<import("graphql").IntrospectionOutputType> | import("graphql").IntrospectionListTypeRef<import("graphql").IntrospectionOutputTypeRef> | undefined;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.findIntrospectionFieldType = findIntrospectionFieldType;
4
+ function findIntrospectionFieldType({ name, gqlType, gqlIntrospection, }) {
5
+ let introspectionFieldType;
6
+ for (const namePart of name.split(".")) {
7
+ const introspectionObject = gqlIntrospection.__schema.types.find((type) => type.kind === "OBJECT" && type.name === gqlType);
8
+ if (!introspectionObject)
9
+ throw new Error(`didn't find object ${gqlType} in gql introspection`);
10
+ const introspectionField = introspectionObject.fields.find((field) => field.name === namePart);
11
+ introspectionFieldType = introspectionField
12
+ ? introspectionField.type.kind === "NON_NULL"
13
+ ? introspectionField.type.ofType
14
+ : introspectionField.type
15
+ : undefined;
16
+ if ((introspectionFieldType === null || introspectionFieldType === void 0 ? void 0 : introspectionFieldType.kind) === "OBJECT") {
17
+ // for next loop iteration (nested fields)
18
+ gqlType = introspectionFieldType.name;
19
+ }
20
+ }
21
+ return introspectionFieldType;
22
+ }
@@ -1,4 +1,3 @@
1
- import { type IntrospectionQuery } from "graphql";
2
1
  import { type FormConfig, type FormFieldConfig } from "../../generate-command";
3
2
  import { type Imports } from "../../utils/generateImportsCode";
4
3
  type AdornmentData = {
@@ -11,11 +10,9 @@ type AdornmentData = {
11
10
  /**
12
11
  * Helper function that builds various options needed for generating form fields.
13
12
  */
14
- export declare function buildFormFieldOptions({ config, formConfig, gqlIntrospection, gqlType, }: {
13
+ export declare function buildFormFieldOptions({ config, formConfig, }: {
15
14
  config: FormFieldConfig<any>;
16
15
  formConfig: FormConfig<any>;
17
- gqlIntrospection: IntrospectionQuery;
18
- gqlType: string;
19
16
  }): {
20
17
  name: string;
21
18
  formattedMessageRootId: any;
@@ -23,6 +20,5 @@ export declare function buildFormFieldOptions({ config, formConfig, gqlIntrospec
23
20
  startAdornment: AdornmentData;
24
21
  endAdornment: AdornmentData;
25
22
  imports: Imports;
26
- introspectionFieldType: import("graphql").IntrospectionNamedTypeRef<import("graphql").IntrospectionOutputType> | import("graphql").IntrospectionListTypeRef<import("graphql").IntrospectionOutputTypeRef> | undefined;
27
23
  };
28
24
  export {};
@@ -51,22 +51,13 @@ const buildAdornmentData = ({ adornmentData }) => {
51
51
  /**
52
52
  * Helper function that builds various options needed for generating form fields.
53
53
  */
54
- function buildFormFieldOptions({ config, formConfig, gqlIntrospection, gqlType, }) {
54
+ function buildFormFieldOptions({ config, formConfig, }) {
55
55
  var _a;
56
56
  const rootGqlType = formConfig.gqlType;
57
57
  const name = String(config.name);
58
58
  const label = (_a = config.label) !== null && _a !== void 0 ? _a : (0, camelCaseToHumanReadable_1.camelCaseToHumanReadable)(name);
59
59
  const formattedMessageRootId = rootGqlType[0].toLowerCase() + rootGqlType.substring(1);
60
60
  const fieldLabel = `<FormattedMessage id="${formattedMessageRootId}.${name}" defaultMessage="${label}" />`;
61
- const introspectionObject = gqlIntrospection.__schema.types.find((type) => type.kind === "OBJECT" && type.name === gqlType);
62
- if (!introspectionObject)
63
- throw new Error(`didn't find object ${gqlType} in gql introspection`);
64
- const introspectionField = introspectionObject.fields.find((field) => field.name === name);
65
- const introspectionFieldType = introspectionField
66
- ? introspectionField.type.kind === "NON_NULL"
67
- ? introspectionField.type.ofType
68
- : introspectionField.type
69
- : undefined;
70
61
  const imports = [];
71
62
  let startAdornment = { adornmentString: "" };
72
63
  let endAdornment = { adornmentString: "" };
@@ -86,5 +77,5 @@ function buildFormFieldOptions({ config, formConfig, gqlIntrospection, gqlType,
86
77
  imports.push(endAdornment.adornmentImport);
87
78
  }
88
79
  }
89
- return { name, formattedMessageRootId, fieldLabel, startAdornment, endAdornment, imports, introspectionFieldType };
80
+ return { name, formattedMessageRootId, fieldLabel, startAdornment, endAdornment, imports };
90
81
  }
@@ -14,7 +14,6 @@ function generateComponentFormField({ config }) {
14
14
  formProps: [],
15
15
  hooksCode: "",
16
16
  formFragmentFields: [],
17
- formValueToGqlInputCode: "",
18
17
  formValuesConfig: [],
19
18
  finalFormConfig: undefined,
20
19
  code,
@@ -6,14 +6,19 @@ export type GenerateFieldsReturn = GeneratorReturn & {
6
6
  imports: Imports;
7
7
  hooksCode: string;
8
8
  formFragmentFields: string[];
9
- formValueToGqlInputCode: string;
10
9
  formProps: Prop[];
11
10
  formValuesConfig: {
12
- omitFromFragmentType?: string;
13
- destructFromFormValues?: string;
14
- typeCode?: string;
11
+ fieldName: string;
12
+ omitFromFragmentType?: boolean;
13
+ destructFromFormValues?: boolean;
14
+ typeCode?: {
15
+ nullable: boolean;
16
+ type: string;
17
+ };
15
18
  initializationCode?: string;
16
19
  defaultInitializationCode?: string;
20
+ formValueToGqlInputCode?: string;
21
+ wrapFormValueToGqlInputCode?: string;
17
22
  }[];
18
23
  finalFormConfig?: {
19
24
  subscription?: {
@@ -22,7 +22,6 @@ function findFieldByName(name, fields) {
22
22
  function generateFields({ gqlIntrospection, baseOutputFilename, fields, formFragmentName, formConfig, gqlType, namePrefix, }) {
23
23
  const gqlDocuments = {};
24
24
  let hooksCode = "";
25
- let formValueToGqlInputCode = "";
26
25
  const formFragmentFields = [];
27
26
  const imports = [];
28
27
  const formProps = [];
@@ -68,7 +67,6 @@ function generateFields({ gqlIntrospection, baseOutputFilename, fields, formFrag
68
67
  imports.push(...generated.imports);
69
68
  formProps.push(...generated.formProps);
70
69
  hooksCode += generated.hooksCode;
71
- formValueToGqlInputCode += generated.formValueToGqlInputCode;
72
70
  formFragmentFields.push(...generated.formFragmentFields);
73
71
  formValuesConfig.push(...generated.formValuesConfig);
74
72
  finalFormConfig.subscription = Object.assign(Object.assign({}, finalFormConfig.subscription), (_a = generated.finalFormConfig) === null || _a === void 0 ? void 0 : _a.subscription);
@@ -79,7 +77,6 @@ function generateFields({ gqlIntrospection, baseOutputFilename, fields, formFrag
79
77
  return {
80
78
  code,
81
79
  hooksCode,
82
- formValueToGqlInputCode,
83
80
  formFragmentFields,
84
81
  gqlDocuments,
85
82
  imports,