@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,23 +1,15 @@
1
1
  "use strict";
2
- var __rest = (this && this.__rest) || function (s, e) {
3
- var t = {};
4
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
- t[p] = s[p];
6
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
- t[p[i]] = s[p[i]];
10
- }
11
- return t;
12
- };
13
2
  Object.defineProperty(exports, "__esModule", { value: true });
14
3
  exports.generateForm = generateForm;
15
4
  const generate_command_1 = require("../generate-command");
16
5
  const convertConfigImport_1 = require("../utils/convertConfigImport");
17
6
  const findMutationType_1 = require("../utils/findMutationType");
7
+ const generateGqlOperation_1 = require("../utils/generateGqlOperation");
18
8
  const generateImportsCode_1 = require("../utils/generateImportsCode");
19
9
  const runtimeTypeGuards_1 = require("../utils/runtimeTypeGuards");
10
+ const flatFormFieldsFromFormConfig_1 = require("./flatFormFieldsFromFormConfig");
20
11
  const generateFields_1 = require("./generateFields");
12
+ const generateFormValues_1 = require("./generateFormValues");
21
13
  const generateFragmentByFormFragmentFields_1 = require("./generateFragmentByFormFragmentFields");
22
14
  const getForwardedGqlArgs_1 = require("./getForwardedGqlArgs");
23
15
  function generateFormPropsCode(props) {
@@ -54,7 +46,6 @@ config) {
54
46
  { name: "useApolloClient", importPath: "@apollo/client" },
55
47
  { name: "useQuery", importPath: "@apollo/client" },
56
48
  { name: "gql", importPath: "@apollo/client" },
57
- { name: "AsyncSelectField", importPath: "@comet/admin" },
58
49
  { name: "CheckboxField", importPath: "@comet/admin" },
59
50
  { name: "Field", importPath: "@comet/admin" },
60
51
  { name: "filterByFragment", importPath: "@comet/admin" },
@@ -91,31 +82,28 @@ config) {
91
82
  const editMode = mode === "edit" || mode == "all";
92
83
  const addMode = mode === "add" || mode == "all";
93
84
  const createMutationType = addMode && (0, findMutationType_1.findMutationTypeOrThrow)((_c = config.createMutation) !== null && _c !== void 0 ? _c : `create${gqlType}`, gqlIntrospection);
94
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
95
- const formFields = config.fields.reduce((acc, field) => {
96
- if ((0, generate_command_1.isFormLayoutConfig)(field)) {
97
- // using forEach instead of acc.push(...field.fields.filter(isFormFieldConfig)) because typescript can't handle mixed typing
98
- field.fields.forEach((nestedFieldConfig) => {
99
- if ((0, generate_command_1.isFormFieldConfig)(nestedFieldConfig)) {
100
- acc.push(nestedFieldConfig);
101
- }
102
- });
103
- }
104
- else if ((0, generate_command_1.isFormFieldConfig)(field)) {
105
- acc.push(field);
106
- }
107
- return acc;
108
- }, []);
85
+ const formFields = (0, flatFormFieldsFromFormConfig_1.flatFormFieldsFromFormConfig)(config);
86
+ let useScopeFromContext = false;
109
87
  const gqlArgs = [];
110
88
  if (createMutationType) {
111
- const { imports: forwardedGqlArgsImports, props: forwardedGqlArgsProps, gqlArgs: forwardedGqlArgs, } = (0, getForwardedGqlArgs_1.getForwardedGqlArgs)({
89
+ const forwardedArgs = (0, getForwardedGqlArgs_1.getForwardedGqlArgs)({
112
90
  fields: formFields,
113
91
  gqlOperation: createMutationType,
114
92
  gqlIntrospection,
115
93
  });
116
- imports.push(...forwardedGqlArgsImports);
117
- formProps.push(...forwardedGqlArgsProps);
118
- gqlArgs.push(...forwardedGqlArgs);
94
+ for (const forwardedArg of forwardedArgs) {
95
+ imports.push(...forwardedArg.imports);
96
+ if (forwardedArg.gqlArg.name === "scope" && !forwardedArg.gqlArg.isInputArgSubfield && !config.scopeAsProp) {
97
+ useScopeFromContext = true;
98
+ }
99
+ else {
100
+ formProps.push(forwardedArg.prop);
101
+ gqlArgs.push(forwardedArg.gqlArg);
102
+ }
103
+ }
104
+ }
105
+ if (useScopeFromContext) {
106
+ imports.push({ name: "useContentScope", importPath: "@comet/cms-admin" });
119
107
  }
120
108
  if (editMode) {
121
109
  if (mode === "all") {
@@ -145,17 +133,17 @@ config) {
145
133
  imports.push({ name: "GQLFinalFormFileUploadDownloadableFragment", importPath: "@comet/cms-admin" });
146
134
  }
147
135
  let hooksCode = "";
148
- let formValueToGqlInputCode = "";
149
136
  const formFragmentFields = [];
150
137
  const formValuesConfig = [];
151
- const _h = (0, generateFields_1.generateFields)({
138
+ const generatedFields = (0, generateFields_1.generateFields)({
152
139
  gqlIntrospection,
153
140
  baseOutputFilename,
154
141
  fields: config.fields,
155
142
  formFragmentName,
156
143
  formConfig: config,
157
144
  gqlType: config.gqlType,
158
- }), { code: fieldsCode } = _h, generatedFields = __rest(_h, ["code"]);
145
+ });
146
+ const fieldsCode = generatedFields.code;
159
147
  for (const name in generatedFields.gqlDocuments) {
160
148
  gqlDocuments[name] = {
161
149
  document: generatedFields.gqlDocuments[name].document,
@@ -165,9 +153,13 @@ config) {
165
153
  imports.push(...generatedFields.imports);
166
154
  formProps.push(...generatedFields.formProps);
167
155
  hooksCode += generatedFields.hooksCode;
168
- formValueToGqlInputCode += generatedFields.formValueToGqlInputCode;
169
156
  formFragmentFields.push(...generatedFields.formFragmentFields);
170
157
  formValuesConfig.push(...generatedFields.formValuesConfig);
158
+ formProps.push({
159
+ name: "onCreate",
160
+ optional: true,
161
+ type: `(id: string) => void`,
162
+ });
171
163
  const { formPropsTypeCode, formPropsParamsCode } = generateFormPropsCode(formProps);
172
164
  gqlDocuments[`${instanceGqlType}FormFragment`] = {
173
165
  document: (0, generateFragmentByFormFragmentFields_1.generateFragmentByFormFragmentFields)({ formFragmentName, gqlType, formFragmentFields }),
@@ -175,60 +167,66 @@ config) {
175
167
  };
176
168
  if (editMode) {
177
169
  gqlDocuments[`${instanceGqlType}Query`] = {
178
- document: `
179
- query ${gqlType}($id: ID!) {
180
- ${instanceGqlType}(id: $id) {
181
- id
182
- updatedAt
183
- ...${formFragmentName}
184
- }
185
- }
186
- \${${`${instanceGqlType}FormFragment`}}
187
- `,
170
+ document: (0, generateGqlOperation_1.generateGqlOperation)({
171
+ type: "query",
172
+ operationName: gqlType,
173
+ rootOperation: instanceGqlType,
174
+ fields: ["id", "updatedAt", `...${formFragmentName}`],
175
+ variables: [
176
+ {
177
+ name: "id",
178
+ type: "ID!",
179
+ },
180
+ ],
181
+ fragmentVariables: [`\${${`${instanceGqlType}FormFragment`}}`],
182
+ }),
188
183
  export: true,
189
184
  };
190
185
  }
191
186
  if (addMode && createMutationType) {
192
187
  gqlDocuments[`create${gqlType}Mutation`] = {
193
- document: `
194
- mutation Create${gqlType}(${gqlArgs.filter((gqlArg) => !gqlArg.isInputArgSubfield).length
195
- ? `${gqlArgs
196
- .filter((gqlArg) => !gqlArg.isInputArgSubfield)
197
- .map((gqlArg) => {
198
- return `$${gqlArg.name}: ${gqlArg.type}!`;
199
- })
200
- .join(", ")}, `
201
- : ``}$input: ${gqlType}Input!) {
202
- ${createMutationType.name}(${gqlArgs.filter((gqlArg) => !gqlArg.isInputArgSubfield).length
203
- ? `${gqlArgs
204
- .filter((gqlArg) => !gqlArg.isInputArgSubfield)
205
- .map((gqlArg) => {
206
- return `${gqlArg.name}: $${gqlArg.name}`;
207
- })
208
- .join(", ")}, `
209
- : ``}input: $input) {
210
- id
211
- updatedAt
212
- ...${formFragmentName}
213
- }
214
- }
215
- \${${`${instanceGqlType}FormFragment`}}
216
- `,
188
+ document: (0, generateGqlOperation_1.generateGqlOperation)({
189
+ type: "mutation",
190
+ operationName: `Create${gqlType}`,
191
+ rootOperation: createMutationType.name,
192
+ fields: ["id", "updatedAt", `...${formFragmentName}`],
193
+ fragmentVariables: [`\${${`${instanceGqlType}FormFragment`}}`],
194
+ variables: [
195
+ ...gqlArgs
196
+ .filter((gqlArg) => !gqlArg.isInputArgSubfield)
197
+ .map((gqlArg) => ({
198
+ name: gqlArg.name,
199
+ type: `${gqlArg.type}!`,
200
+ })),
201
+ ...(useScopeFromContext ? [{ name: "scope", type: `${gqlType}ContentScopeInput!` }] : []),
202
+ {
203
+ name: "input",
204
+ type: `${gqlType}Input!`,
205
+ },
206
+ ],
207
+ }),
217
208
  export: true,
218
209
  };
219
210
  }
220
211
  if (editMode) {
221
212
  gqlDocuments[`update${gqlType}Mutation`] = {
222
- document: `
223
- mutation Update${gqlType}($id: ID!, $input: ${gqlType}UpdateInput!) {
224
- update${gqlType}(id: $id, input: $input) {
225
- id
226
- updatedAt
227
- ...${formFragmentName}
228
- }
229
- }
230
- \${${`${instanceGqlType}FormFragment`}}
231
- `,
213
+ document: (0, generateGqlOperation_1.generateGqlOperation)({
214
+ type: "mutation",
215
+ operationName: `Update${gqlType}`,
216
+ rootOperation: `update${gqlType}`,
217
+ fields: ["id", "updatedAt", `...${formFragmentName}`],
218
+ fragmentVariables: [`\${${`${instanceGqlType}FormFragment`}}`],
219
+ variables: [
220
+ {
221
+ name: "id",
222
+ type: "ID!",
223
+ },
224
+ {
225
+ name: "input",
226
+ type: `${gqlType}UpdateInput!`,
227
+ },
228
+ ],
229
+ }),
232
230
  export: true,
233
231
  };
234
232
  }
@@ -290,19 +288,7 @@ config) {
290
288
 
291
289
  ${customFilterByFragment}
292
290
 
293
- type FormValues = ${formValuesConfig.filter((config) => !!config.omitFromFragmentType).length > 0 || rootBlockFields.length > 0
294
- ? `Omit<${filterByFragmentType}, ${[
295
- ...(rootBlockFields.length > 0 ? ["keyof typeof rootBlocks"] : []),
296
- ...formValuesConfig.filter((config) => !!config.omitFromFragmentType).map((config) => `"${config.omitFromFragmentType}"`),
297
- ].join(" | ")}>`
298
- : `${filterByFragmentType}`} ${formValuesConfig.filter((config) => !!config.typeCode).length > 0
299
- ? `& {
300
- ${formValuesConfig
301
- .filter((config) => !!config.typeCode)
302
- .map((config) => config.typeCode)
303
- .join("\n")}
304
- }`
305
- : ""};
291
+ ${(0, generateFormValues_1.generateFormValuesType)({ formValuesConfig, filterByFragmentType, gqlIntrospection, gqlType })}
306
292
 
307
293
  ${formPropsTypeCode}
308
294
 
@@ -311,6 +297,7 @@ config) {
311
297
  ${mode == "all" ? `const mode = id ? "edit" : "add";` : ""}
312
298
  const formApiRef = useFormApiRef<FormValues>();
313
299
  ${addMode ? `const stackSwitchApi = useStackSwitchApi();` : ""}
300
+ ${useScopeFromContext ? `const { scope } = useContentScope();` : ""}
314
301
 
315
302
  ${editMode
316
303
  ? `
@@ -321,28 +308,8 @@ config) {
321
308
  `
322
309
  : ""}
323
310
 
324
- ${editMode
325
- ? `const initialValues = useMemo<Partial<FormValues>>(() => data?.${instanceGqlType}
326
- ? {
327
- ...filterByFragment<${filterByFragmentType}>(${instanceGqlType}FormFragment, data.${instanceGqlType}),
328
- ${formValuesConfig
329
- .filter((config) => !!config.initializationCode)
330
- .map((config) => config.initializationCode)
331
- .join(",\n")}
332
- }
333
- : {
334
- ${formValuesConfig
335
- .filter((config) => !!config.defaultInitializationCode)
336
- .map((config) => config.defaultInitializationCode)
337
- .join(",\n")}
338
- }
339
- , [data]);`
340
- : `const initialValues = {
341
- ${formValuesConfig
342
- .filter((config) => !!config.defaultInitializationCode)
343
- .map((config) => config.defaultInitializationCode)
344
- .join(",\n")}
345
- };`}
311
+ ${(0, generateFormValues_1.generateInitialValues)({ mode, formValuesConfig, filterByFragmentType, gqlIntrospection, gqlType })}
312
+
346
313
 
347
314
  ${editMode
348
315
  ? `
@@ -359,17 +326,14 @@ config) {
359
326
  `
360
327
  : ""}
361
328
 
362
- const handleSubmit = async (${formValuesConfig.filter((config) => !!config.destructFromFormValues).length
363
- ? `{ ${formValuesConfig
364
- .filter((config) => !!config.destructFromFormValues)
365
- .map((config) => config.destructFromFormValues)
366
- .join(", ")}, ...formValues }`
367
- : `formValues`}: FormValues, form: FormApi<FormValues>${addMode ? `, event: FinalFormSubmitEvent` : ""}) => {
329
+ const handleSubmit = async (${(0, generateFormValues_1.generateDestructFormValueForInput)({
330
+ formValuesConfig,
331
+ gqlIntrospection,
332
+ gqlType,
333
+ })}: FormValues, form: FormApi<FormValues>${addMode ? `, event: FinalFormSubmitEvent` : ""}) => {
368
334
  ${editMode ? `if (await saveConflict.checkForConflicts()) throw new Error("Conflicts detected");` : ""}
369
- const output = {
370
- ...formValues,
371
- ${formValueToGqlInputCode}
372
- };
335
+ ${(0, generateFormValues_1.generateFormValuesToGqlInput)({ formValuesConfig, gqlIntrospection, gqlType })}
336
+
373
337
  ${mode == "all" ? `if (mode === "edit") {` : ""}
374
338
  ${editMode
375
339
  ? `
@@ -386,7 +350,9 @@ config) {
386
350
  ? `
387
351
  const { data: mutationResponse } = await client.mutate<GQLCreate${gqlType}Mutation, GQLCreate${gqlType}MutationVariables>({
388
352
  mutation: create${gqlType}Mutation,
389
- variables: { input: ${gqlArgs.filter((prop) => prop.isInputArgSubfield).length
353
+ variables: {
354
+ ${useScopeFromContext ? `scope,` : ""}
355
+ input: ${gqlArgs.filter((prop) => prop.isInputArgSubfield).length
390
356
  ? `{ ...output, ${gqlArgs
391
357
  .filter((prop) => prop.isInputArgSubfield)
392
358
  .map((prop) => prop.name)
@@ -398,13 +364,14 @@ config) {
398
364
  .join(",")}`
399
365
  : ""} },
400
366
  });
401
- if (!event.navigatingBack) {
402
- const id = mutationResponse?.${createMutationType.name}.id;
403
- if (id) {
404
- setTimeout(() => {
405
- stackSwitchApi.activatePage(\`edit\`, id);
406
- });
407
- }
367
+ const id = mutationResponse?.${createMutationType.name}.id;
368
+ if (id) {
369
+ setTimeout(() => {
370
+ onCreate?.(id);
371
+ ${config.navigateOnCreate === true || config.navigateOnCreate === undefined
372
+ ? `if (!event.navigatingBack) { stackSwitchApi.activatePage(\`edit\`, id);`
373
+ : ``}
374
+ });
408
375
  }
409
376
  `
410
377
  : ""}
@@ -6,6 +6,7 @@ const convertConfigImport_1 = require("../utils/convertConfigImport");
6
6
  const isFieldOptional_1 = require("../utils/isFieldOptional");
7
7
  const runtimeTypeGuards_1 = require("../utils/runtimeTypeGuards");
8
8
  const generateAsyncSelect_1 = require("./asyncSelect/generateAsyncSelect");
9
+ const findIntrospectionFieldType_1 = require("./formField/findIntrospectionFieldType");
9
10
  const options_1 = require("./formField/options");
10
11
  function generateFormField({ gqlIntrospection, baseOutputFilename, config, formConfig, gqlType, namePrefix, }) {
11
12
  if (config.type == "asyncSelect" || config.type == "asyncSelectFilter") {
@@ -13,9 +14,9 @@ function generateFormField({ gqlIntrospection, baseOutputFilename, config, formC
13
14
  }
14
15
  const imports = [];
15
16
  const formProps = [];
16
- const { name, formattedMessageRootId, fieldLabel, startAdornment, endAdornment, imports: optionsImports, } = (0, options_1.buildFormFieldOptions)({ config, formConfig, gqlType, gqlIntrospection });
17
+ const { name, formattedMessageRootId, fieldLabel, startAdornment, endAdornment, imports: optionsImports, } = (0, options_1.buildFormFieldOptions)({ config, formConfig });
17
18
  imports.push(...optionsImports);
18
- let { introspectionFieldType } = (0, options_1.buildFormFieldOptions)({ config, formConfig, gqlType, gqlIntrospection });
19
+ let introspectionFieldType = (0, findIntrospectionFieldType_1.findIntrospectionFieldType)({ name, gqlIntrospection, gqlType });
19
20
  const nameWithPrefix = `${namePrefix ? `${namePrefix}.` : ``}${name}`;
20
21
  const rootGqlType = formConfig.gqlType;
21
22
  const dataRootName = rootGqlType[0].toLowerCase() + rootGqlType.substring(1); // TODO should probably be deteced via query
@@ -24,7 +25,9 @@ function generateFormField({ gqlIntrospection, baseOutputFilename, config, formC
24
25
  const endAdornmentWithLockIconProp = `endAdornment={<InputAdornment position="end"><Lock /></InputAdornment>}`;
25
26
  const readOnlyProps = `readOnly disabled`;
26
27
  const readOnlyPropsWithLock = `${readOnlyProps} ${endAdornmentWithLockIconProp}`;
27
- let formValuesConfig = [{}]; // FormFields should only contain one entry
28
+ const formValueConfig = {
29
+ fieldName: nameWithPrefix,
30
+ };
28
31
  const gqlDocuments = {};
29
32
  const hooksCode = "";
30
33
  let finalFormConfig;
@@ -40,7 +43,6 @@ function generateFormField({ gqlIntrospection, baseOutputFilename, config, formC
40
43
  }
41
44
  }
42
45
  let code = "";
43
- let formValueToGqlInputCode = "";
44
46
  let formFragmentFields = [name];
45
47
  if (config.type == "text") {
46
48
  const TextInputComponent = config.multiline ? "TextAreaField" : "TextField";
@@ -62,7 +64,7 @@ function generateFormField({ gqlIntrospection, baseOutputFilename, config, formC
62
64
  ${validateCode}
63
65
  />`;
64
66
  if (!required && !config.readOnly) {
65
- formValueToGqlInputCode = `${name}: formValues.${name} ?? null,`;
67
+ formValueConfig.formValueToGqlInputCode = `$fieldName ?? null`;
66
68
  }
67
69
  }
68
70
  else if (config.type == "number") {
@@ -85,22 +87,21 @@ function generateFormField({ gqlIntrospection, baseOutputFilename, config, formC
85
87
  ${validateCode}
86
88
  />`;
87
89
  //TODO MUI suggest not using type=number https://mui.com/material-ui/react-text-field/#type-quot-number-quot
88
- let assignment = `parseFloat(formValues.${nameWithPrefix})`;
90
+ let assignment = `parseFloat($fieldName)`;
89
91
  if ((0, isFieldOptional_1.isFieldOptional)({ config, gqlIntrospection: gqlIntrospection, gqlType: gqlType })) {
90
- assignment = `formValues.${nameWithPrefix} ? ${assignment} : null`;
92
+ assignment = `$fieldName ? ${assignment} : null`;
91
93
  }
92
- formValueToGqlInputCode = `${name}: ${assignment},`;
94
+ formValueConfig.formValueToGqlInputCode = `${assignment}`;
93
95
  let initializationAssignment = `String(data.${dataRootName}.${nameWithPrefix})`;
94
96
  if (!required) {
95
97
  initializationAssignment = `data.${dataRootName}.${nameWithPrefix} ? ${initializationAssignment} : undefined`;
96
98
  }
97
- formValuesConfig = [
98
- {
99
- omitFromFragmentType: name,
100
- typeCode: `${name}${!required ? `?` : ``}: string;`,
101
- initializationCode: `${name}: ${initializationAssignment}`,
102
- },
103
- ];
99
+ formValueConfig.omitFromFragmentType = true;
100
+ formValueConfig.typeCode = {
101
+ nullable: !required,
102
+ type: "string",
103
+ };
104
+ formValueConfig.initializationCode = `${initializationAssignment}`;
104
105
  }
105
106
  else if (config.type === "numberRange") {
106
107
  code = `
@@ -140,11 +141,7 @@ function generateFormField({ gqlIntrospection, baseOutputFilename, config, formC
140
141
  : ""}
141
142
  ${validateCode}
142
143
  />`;
143
- formValuesConfig = [
144
- {
145
- defaultInitializationCode: `${name}: false`,
146
- },
147
- ];
144
+ formValueConfig.defaultInitializationCode = `false`;
148
145
  }
149
146
  else if (config.type == "date") {
150
147
  imports.push({
@@ -169,7 +166,7 @@ function generateFormField({ gqlIntrospection, baseOutputFilename, config, formC
169
166
  ${validateCode}
170
167
  />`;
171
168
  if (!required && !config.readOnly) {
172
- formValueToGqlInputCode = `${name}: formValues.${name} ?? null,`;
169
+ formValueConfig.formValueToGqlInputCode = `$fieldName ?? null`;
173
170
  }
174
171
  }
175
172
  else if (config.type == "dateTime") {
@@ -193,31 +190,25 @@ function generateFormField({ gqlIntrospection, baseOutputFilename, config, formC
193
190
  : ""}
194
191
  ${validateCode}
195
192
  />`;
196
- formValuesConfig = [
197
- {
198
- initializationCode: `${name}: data.${dataRootName}.${nameWithPrefix} ? new Date(data.${dataRootName}.${nameWithPrefix}) : undefined`,
199
- omitFromFragmentType: name,
200
- typeCode: `${name}${!required ? "?" : ""}: Date${!required ? " | null" : ""};`,
201
- },
202
- ];
193
+ formValueConfig.initializationCode = `data.${dataRootName}.${nameWithPrefix} ? new Date(data.${dataRootName}.${nameWithPrefix}) : undefined`;
194
+ formValueConfig.omitFromFragmentType = true;
195
+ formValueConfig.typeCode = {
196
+ nullable: !required,
197
+ type: `Date${!required ? " | null" : ""}`,
198
+ };
203
199
  if (!config.readOnly) {
204
- formValueToGqlInputCode = required
205
- ? `${name}: formValues.${name}.toISOString(),`
206
- : `${name}: formValues.${name} ? formValues.${name}.toISOString() : null,`;
200
+ formValueConfig.formValueToGqlInputCode = required ? `$fieldName.toISOString()` : `$fieldName ? $fieldName.toISOString() : null`;
207
201
  }
208
202
  }
209
203
  else if (config.type == "block") {
210
204
  code = `<Field name="${nameWithPrefix}" isEqual={isEqual} label={${fieldLabel}} variant="horizontal" fullWidth>
211
205
  {createFinalFormBlock(rootBlocks.${String(config.name)})}
212
206
  </Field>`;
213
- formValueToGqlInputCode = `${name}: rootBlocks.${name}.state2Output(formValues.${nameWithPrefix}),`;
214
- formValuesConfig = [
215
- {
216
- typeCode: `${name}: BlockState<typeof rootBlocks.${name}>;`,
217
- initializationCode: `${name}: rootBlocks.${name}.input2State(data.${dataRootName}.${nameWithPrefix})`,
218
- defaultInitializationCode: `${name}: rootBlocks.${name}.defaultValues()`,
219
- },
220
- ];
207
+ formValueConfig.formValueToGqlInputCode = `rootBlocks.${name}.state2Output($fieldName)`;
208
+ formValueConfig.omitFromFragmentType = true;
209
+ formValueConfig.typeCode = { nullable: false, type: `BlockState<typeof rootBlocks.${name}>` };
210
+ formValueConfig.initializationCode = `rootBlocks.${name}.input2State(data.${dataRootName}.${nameWithPrefix})`;
211
+ formValueConfig.defaultInitializationCode = `rootBlocks.${name}.defaultValues()`;
221
212
  }
222
213
  else if (config.type === "fileUpload") {
223
214
  const multiple = config.multiple || (typeof config.maxFiles === "number" && config.maxFiles > 1);
@@ -231,12 +222,12 @@ function generateFormField({ gqlIntrospection, baseOutputFilename, config, formC
231
222
  ${config.accept ? `accept="${config.accept}"` : ""}
232
223
  />`;
233
224
  if (multiple) {
234
- formValueToGqlInputCode = `${name}: formValues.${name}?.map(({ id }) => id),`;
225
+ formValueConfig.formValueToGqlInputCode = `$fieldName?.map(({ id }) => id)`;
235
226
  }
236
227
  else {
237
- formValueToGqlInputCode = `${name}: formValues.${name} ? formValues.${name}.id : null,`;
228
+ formValueConfig.formValueToGqlInputCode = `$fieldName ? $fieldName.id : null`;
238
229
  }
239
- formFragmentFields = [`${name} { ...${config.download ? "FinalFormFileUploadDownloadable" : "FinalFormFileUpload"} }`];
230
+ formFragmentFields = [`${name}...${config.download ? "FinalFormFileUploadDownloadable" : "FinalFormFileUpload"}`];
240
231
  }
241
232
  else if (config.type == "staticSelect") {
242
233
  const multiple = (introspectionFieldType === null || introspectionFieldType === void 0 ? void 0 : introspectionFieldType.kind) === "LIST";
@@ -336,12 +327,11 @@ function generateFormField({ gqlIntrospection, baseOutputFilename, config, formC
336
327
  return {
337
328
  code,
338
329
  hooksCode,
339
- formValueToGqlInputCode,
340
330
  formFragmentFields,
341
331
  gqlDocuments,
342
332
  imports,
343
333
  formProps,
344
- formValuesConfig,
334
+ formValuesConfig: [formValueConfig],
345
335
  finalFormConfig,
346
336
  };
347
337
  }
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generateFormLayout = generateFormLayout;
4
4
  const camelCaseToHumanReadable_1 = require("../utils/camelCaseToHumanReadable");
5
+ const findIntrospectionFieldType_1 = require("./formField/findIntrospectionFieldType");
5
6
  const generateFields_1 = require("./generateFields");
6
7
  function generateFormLayout({ gqlIntrospection, baseOutputFilename, config, formFragmentName, formConfig, gqlType, namePrefix, }) {
7
8
  var _a, _b, _c, _d, _e;
@@ -10,7 +11,6 @@ function generateFormLayout({ gqlIntrospection, baseOutputFilename, config, form
10
11
  const dataRootName = rootGqlType[0].toLowerCase() + rootGqlType.substring(1); // TODO should probably be deteced via query
11
12
  let code = "";
12
13
  let hooksCode = "";
13
- let formValueToGqlInputCode = "";
14
14
  const formFragmentFields = [];
15
15
  const gqlDocuments = {};
16
16
  const imports = [];
@@ -29,7 +29,6 @@ function generateFormLayout({ gqlIntrospection, baseOutputFilename, config, form
29
29
  namePrefix,
30
30
  });
31
31
  hooksCode += generatedFields.hooksCode;
32
- formValueToGqlInputCode += generatedFields.formValueToGqlInputCode;
33
32
  formFragmentFields.push(...generatedFields.formFragmentFields);
34
33
  for (const name in generatedFields.gqlDocuments) {
35
34
  gqlDocuments[name] = generatedFields.gqlDocuments[name];
@@ -66,16 +65,10 @@ function generateFormLayout({ gqlIntrospection, baseOutputFilename, config, form
66
65
  }
67
66
  else if (config.type === "optionalNestedFields") {
68
67
  const name = String(config.name);
69
- const introspectionObject = gqlIntrospection.__schema.types.find((type) => type.kind === "OBJECT" && type.name === gqlType);
70
- if (!introspectionObject)
71
- throw new Error(`didn't find object ${gqlType} in gql introspection`);
72
- const introspectionField = introspectionObject.fields.find((field) => field.name === name);
73
- if (!introspectionField)
74
- throw new Error(`didn't find field ${name} in gql introspection type ${gqlType}`);
75
- if (introspectionField.type.kind === "NON_NULL") {
76
- throw new Error(`field ${name} in gql introspection type ${gqlType} must not be required to be usable with optionalNestedFields`);
77
- }
78
- if (introspectionField.type.kind !== "OBJECT")
68
+ const introspectionFieldType = (0, findIntrospectionFieldType_1.findIntrospectionFieldType)({ name, gqlType, gqlIntrospection });
69
+ if (!introspectionFieldType)
70
+ throw new Error(`field ${name} in gql introspection type ${gqlType} not found`);
71
+ if (introspectionFieldType.kind !== "OBJECT")
79
72
  throw new Error(`field ${name} in gql introspection type ${gqlType} has to be OBJECT`);
80
73
  const checkboxLabel = (_e = config.checkboxLabel) !== null && _e !== void 0 ? _e : `Enable ${(0, camelCaseToHumanReadable_1.camelCaseToHumanReadable)(String(config.name))}`;
81
74
  const generatedFields = (0, generateFields_1.generateFields)({
@@ -84,7 +77,7 @@ function generateFormLayout({ gqlIntrospection, baseOutputFilename, config, form
84
77
  fields: config.fields,
85
78
  formFragmentName,
86
79
  formConfig,
87
- gqlType: introspectionField.type.name,
80
+ gqlType: introspectionFieldType.name,
88
81
  namePrefix: name,
89
82
  });
90
83
  hooksCode += generatedFields.hooksCode;
@@ -93,39 +86,26 @@ function generateFormLayout({ gqlIntrospection, baseOutputFilename, config, form
93
86
  gqlDocuments[name] = generatedFields.gqlDocuments[name];
94
87
  }
95
88
  imports.push(...generatedFields.imports);
96
- const wrappingFormValuesConfig = {
97
- omitFromFragmentType: name,
98
- destructFromFormValues: `${name}Enabled`,
99
- typeCode: `${name}Enabled: boolean;`,
100
- initializationCode: `${name}Enabled: !!data.${dataRootName}.${name}`,
101
- };
102
- const subfieldsFormValuesTypeCode = generatedFields.formValuesConfig
103
- .filter((config) => !!config.omitFromFragmentType)
104
- .map((config) => `"${config.omitFromFragmentType}"`);
105
- if (subfieldsFormValuesTypeCode.length) {
106
- wrappingFormValuesConfig.typeCode = `${wrappingFormValuesConfig.typeCode}
107
- ${name}: Omit<NonNullable<GQL${formFragmentName}Fragment["${name}"]>, ${subfieldsFormValuesTypeCode.join(" | ")}> & {
108
- ${generatedFields.formValuesConfig.map((config) => config.typeCode).join("\n")}
109
- };`;
110
- }
111
- const subfieldsFormValuesInitCode = generatedFields.formValuesConfig
112
- .filter((config) => !!config.initializationCode)
113
- .map((config) => config.initializationCode);
114
- if (subfieldsFormValuesInitCode.length) {
115
- wrappingFormValuesConfig.initializationCode = `${wrappingFormValuesConfig.initializationCode},
116
- ${name}: data.${dataRootName}.${name} ? { ${subfieldsFormValuesInitCode.join(", ")}} : undefined `;
117
- }
118
- const subfieldsFormValuesDefaultInitCode = generatedFields.formValuesConfig
119
- .filter((config) => !!config.defaultInitializationCode)
120
- .map((config) => config.defaultInitializationCode);
121
- if (subfieldsFormValuesDefaultInitCode.length) {
122
- wrappingFormValuesConfig.defaultInitializationCode = `${name}: { ${subfieldsFormValuesDefaultInitCode.join(", ")}}`;
123
- }
124
- formValuesConfig.push(wrappingFormValuesConfig);
89
+ formValuesConfig.push(...generatedFields.formValuesConfig);
90
+ // first field is the "enabled" checkbox
91
+ formValuesConfig.push({
92
+ fieldName: `${name}Enabled`,
93
+ omitFromFragmentType: false,
94
+ destructFromFormValues: true,
95
+ typeCode: {
96
+ nullable: false,
97
+ type: "boolean",
98
+ },
99
+ initializationCode: `!!data.${dataRootName}.${name}`,
100
+ });
101
+ // second field is the nested object, which is not a final-form field itself
102
+ formValuesConfig.push({
103
+ fieldName: `${name}`,
104
+ wrapFormValueToGqlInputCode: `${name.split(".").pop()}Enabled && $fieldName ? $inner : null`,
105
+ });
125
106
  imports.push({ name: "FinalFormSwitch", importPath: "@comet/admin" });
126
107
  imports.push({ name: "messages", importPath: "@comet/admin" });
127
108
  imports.push({ name: "FormControlLabel", importPath: "@mui/material" });
128
- formValueToGqlInputCode += `${String(config.name)}: ${String(config.name)}Enabled && formValues.${String(config.name)} ? {${generatedFields.formValueToGqlInputCode}} : null,`;
129
109
  code = `<Field
130
110
  fullWidth
131
111
  name="${String(config.name)}Enabled"
@@ -155,7 +135,6 @@ function generateFormLayout({ gqlIntrospection, baseOutputFilename, config, form
155
135
  return {
156
136
  code,
157
137
  hooksCode,
158
- formValueToGqlInputCode,
159
138
  formFragmentFields,
160
139
  gqlDocuments,
161
140
  imports,