@comet/admin-generator 8.0.0-beta.4 → 8.0.0-beta.6

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.
@@ -1,5 +1,8 @@
1
1
  #!/usr/bin/env node
2
+
2
3
  require("ts-node").register({
3
4
  require: ["tsconfig-paths/register"],
5
+ transpileOnly: true,
4
6
  });
7
+
5
8
  require("../lib/adminGenerator");
@@ -0,0 +1 @@
1
+ export declare function parseConfig(file: string): Promise<any>;
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
36
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
37
+ return new (P || (P = Promise))(function (resolve, reject) {
38
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
39
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
40
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
41
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
42
+ });
43
+ };
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ exports.parseConfig = parseConfig;
46
+ const fs_1 = require("fs");
47
+ const path_1 = require("path");
48
+ const transformConfig_1 = require("./transformConfig");
49
+ function parseConfig(file) {
50
+ return __awaiter(this, void 0, void 0, function* () {
51
+ //1. parse config file using TypeScript Complier Api and transform it (replace imports and functions that can't be executed)
52
+ const transformedConfig = (0, transformConfig_1.transformConfigFile)(file, yield fs_1.promises.readFile(file, "utf-8"));
53
+ //2. save modified config file to temp file
54
+ const tempFileName = `${(0, path_1.dirname)(file)}/.temp-${(0, path_1.basename)(file)}`;
55
+ yield fs_1.promises.writeFile(tempFileName, transformedConfig, "utf-8");
56
+ //3. import (=execute) temp modified config file
57
+ let executedConfig;
58
+ try {
59
+ const configFile = yield Promise.resolve(`${tempFileName.replace(/\.tsx?$/, "")}`).then(s => __importStar(require(s)));
60
+ if (!configFile.default) {
61
+ throw new Error(`No default export found in ${file}`);
62
+ }
63
+ executedConfig = configFile.default;
64
+ }
65
+ catch (e) {
66
+ console.error(e);
67
+ throw new Error(`Error executing config file ${file}: ${e}`);
68
+ }
69
+ yield fs_1.promises.rm(tempFileName);
70
+ return executedConfig;
71
+ });
72
+ }
@@ -0,0 +1 @@
1
+ export declare function transformConfigFile(fileName: string, sourceText: string): string;
@@ -0,0 +1,239 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.transformConfigFile = transformConfigFile;
37
+ const ts = __importStar(require("typescript"));
38
+ const supportedImportPaths = [
39
+ "[type=grid].columns.filterOperators",
40
+ "[type=grid].columns.block",
41
+ "[type=grid].columns.component",
42
+ // TODO implement in generator "[type=grid].columns.renderCell",
43
+ //support in up to 5 levels of nested fields (eg. fieldSet)
44
+ ...Array.from(Array(5).keys()).map((i) => `[type=form]${".fields".repeat(i + 1)}.validate`),
45
+ ...Array.from(Array(5).keys()).map((i) => `[type=form]${".fields".repeat(i + 1)}.block`),
46
+ ...Array.from(Array(5).keys()).map((i) => `[type=form]${".fields".repeat(i + 1)}.component`),
47
+ ];
48
+ const supportedInlineCodePaths = [
49
+ // TODO implement in generator "[type=grid].columns.filterOperators",
50
+ "[type=grid].columns.renderCell",
51
+ //support in up to 5 levels of nested fields (eg. fieldSet)
52
+ ...Array.from(Array(5).keys()).map((i) => `[type=form]${".fields".repeat(i + 1)}.validate`),
53
+ ];
54
+ // transform the config file to replace all imports and inline code with a { code, imports } object
55
+ // this is needed to be able to execute the config file in a node environment
56
+ function transformConfigFile(fileName, sourceText) {
57
+ const sourceFile = ts.createSourceFile(fileName, sourceText, ts.ScriptTarget.ES2024, // language version
58
+ true);
59
+ const importedIdentifiers = collectImports(sourceFile);
60
+ function configTransformer() {
61
+ return (context) => {
62
+ const visit = (node, path) => {
63
+ if (ts.isArrowFunction(node)) {
64
+ if (supportedInlineCodePaths.includes(path)) {
65
+ let code = node.getText();
66
+ if (code.endsWith(","))
67
+ code = code.slice(0, -1); // for some unknown reason node can contain the trailing comma
68
+ const imports = findUsedImports(node.body, importedIdentifiers); //find all imports used in the function body
69
+ // replace inline code with { code, imports } object
70
+ return ts.factory.createObjectLiteralExpression([
71
+ ts.factory.createPropertyAssignment("code", ts.factory.createStringLiteral(code)),
72
+ ts.factory.createPropertyAssignment("imports", ts.factory.createArrayLiteralExpression(imports.map((imprt) => {
73
+ return ts.factory.createObjectLiteralExpression([
74
+ ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(imprt.name)),
75
+ ts.factory.createPropertyAssignment("import", ts.factory.createStringLiteral(imprt.import)),
76
+ ]);
77
+ }))),
78
+ ], true);
79
+ }
80
+ else {
81
+ throw new Error(`Inline Function is not allowed here and calling the function is not supported: ${path}`);
82
+ }
83
+ }
84
+ else if (ts.isIdentifier(node)) {
85
+ const imported = importedIdentifiers.get(node.text);
86
+ if (imported) {
87
+ if (supportedImportPaths.includes(path)) {
88
+ // replace imported identifier with { name, import } object
89
+ return ts.factory.createObjectLiteralExpression([
90
+ ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(node.text)),
91
+ ts.factory.createPropertyAssignment("import", ts.factory.createStringLiteral(imported.import)),
92
+ ], true);
93
+ }
94
+ else {
95
+ throw new Error(`Following the import is not supported: ${path} ${node.text}`);
96
+ }
97
+ }
98
+ }
99
+ const transformKinds = [
100
+ ts.SyntaxKind.Identifier,
101
+ ts.SyntaxKind.ArrayLiteralExpression,
102
+ ts.SyntaxKind.ObjectLiteralExpression,
103
+ ts.SyntaxKind.TaggedTemplateExpression,
104
+ ts.SyntaxKind.SpreadElement,
105
+ ts.SyntaxKind.PropertyAssignment,
106
+ ts.SyntaxKind.ShorthandPropertyAssignment,
107
+ ];
108
+ if (!transformKinds.includes(node.kind)) {
109
+ // if the node is not one of the transformKinds, stop transformation at this level return it as is
110
+ return node;
111
+ }
112
+ let newPath = path;
113
+ if (path == "") {
114
+ // first entry of path is the type, then property names (. separated) are added
115
+ if (ts.isObjectLiteralExpression(node)) {
116
+ const typeProperty = getTypePropertyFromObjectLiteral(node);
117
+ newPath = typeProperty ? `[type=${typeProperty}]` : "";
118
+ }
119
+ }
120
+ else {
121
+ if (ts.isPropertyAssignment(node)) {
122
+ newPath = `${path}.${node.name.getText()}`;
123
+ }
124
+ }
125
+ return ts.visitEachChild(node, (child) => {
126
+ return visit(child, newPath);
127
+ }, context);
128
+ };
129
+ return (node) => ts.visitNode(node, (child) => visit(child, ""));
130
+ };
131
+ }
132
+ const configNode = findConfigNode(sourceFile);
133
+ const transformedConfigNode = ts.transform(configNode, [configTransformer()]).transformed[0];
134
+ const updatedSource = ts.transform(sourceFile, [
135
+ (context) => {
136
+ const visitor = (node) => {
137
+ if (node === configNode)
138
+ return transformedConfigNode;
139
+ return ts.visitEachChild(node, visitor, context);
140
+ };
141
+ return (node) => ts.visitNode(node, visitor);
142
+ },
143
+ ]).transformed[0];
144
+ const printer = ts.createPrinter();
145
+ return printer.printFile(updatedSource);
146
+ }
147
+ // finds the config node in the source file (=default export, might be wrapped in defineConfig or uses satisfies)
148
+ function findConfigNode(sourceFile) {
149
+ let ret;
150
+ sourceFile.forEachChild((node) => {
151
+ if (ts.isExportAssignment(node)) {
152
+ const exportedNode = node.expression;
153
+ if (ts.isCallExpression(exportedNode) && exportedNode.expression.getText() == "defineConfig") {
154
+ //export default defineConfig<Foo>({ ... });
155
+ const args = exportedNode.arguments;
156
+ if (args.length != 1) {
157
+ throw new Error(`Expected exactly one argument for defineConfig`);
158
+ }
159
+ ret = args[0];
160
+ return false;
161
+ }
162
+ else if (ts.isSatisfiesExpression(exportedNode)) {
163
+ //export default { ... } satisfies GeneratorConfig<Foo>;
164
+ if (ts.isObjectLiteralExpression(exportedNode.expression)) {
165
+ ret = exportedNode.expression;
166
+ return false;
167
+ }
168
+ }
169
+ else if (ts.isObjectLiteralExpression(exportedNode)) {
170
+ //export default { ... };
171
+ ret = exportedNode;
172
+ return false;
173
+ }
174
+ }
175
+ });
176
+ if (!ret) {
177
+ throw new Error(`No default export found, please export the GeneratorConfig as default, preferrable using defineConfig helper.`);
178
+ }
179
+ return ret;
180
+ }
181
+ // simple helper that extracts the value of the type property from a object literal ({ type: "grid" } returns "grid")
182
+ function getTypePropertyFromObjectLiteral(node) {
183
+ for (const property of node.properties) {
184
+ if (ts.isPropertyAssignment(property)) {
185
+ if (property.name.getText() == "type") {
186
+ const propertyAssignmentInitializer = property.initializer;
187
+ if (ts.isStringLiteral(propertyAssignmentInitializer)) {
188
+ return propertyAssignmentInitializer.text;
189
+ }
190
+ }
191
+ }
192
+ }
193
+ return null;
194
+ }
195
+ // visits ast and collects all imports statements in the source file
196
+ function collectImports(rootNode) {
197
+ const importedIdentifiers = new Map();
198
+ function visit(node) {
199
+ if (ts.isImportDeclaration(node) &&
200
+ node.importClause &&
201
+ node.importClause.namedBindings &&
202
+ ts.isNamedImports(node.importClause.namedBindings)) {
203
+ const moduleSpecifier = node.moduleSpecifier.text;
204
+ for (const element of node.importClause.namedBindings.elements) {
205
+ const localName = element.name.text;
206
+ const originalName = element.propertyName ? element.propertyName.text : localName;
207
+ importedIdentifiers.set(localName, {
208
+ name: originalName,
209
+ import: moduleSpecifier,
210
+ });
211
+ }
212
+ }
213
+ ts.forEachChild(node, visit);
214
+ }
215
+ visit(rootNode);
216
+ return importedIdentifiers;
217
+ }
218
+ // visits ast and collects all identifiers that are an import
219
+ function findUsedImports(rootNode, importedIdentifiers) {
220
+ const imports = [];
221
+ const usedNames = new Set();
222
+ // Collect all identifiers used in the rootNode
223
+ function collectUsedIdentifiers(node) {
224
+ if (ts.isIdentifier(node)) {
225
+ usedNames.add(node.text);
226
+ }
227
+ ts.forEachChild(node, collectUsedIdentifiers);
228
+ }
229
+ collectUsedIdentifiers(rootNode);
230
+ // Match used identifiers to imported ones
231
+ // NOTE: this is not 100% correct as it doesn't recognize cases where a import is overwritten by a local variable. But it is fast.
232
+ for (const name of usedNames) {
233
+ const imported = importedIdentifiers.get(name);
234
+ if (imported) {
235
+ imports.push(imported);
236
+ }
237
+ }
238
+ return imports;
239
+ }
@@ -106,15 +106,6 @@ export type FormConfig<T extends {
106
106
  createMutation?: string;
107
107
  fields: (FormFieldConfig<T> | FormLayoutConfig<T> | ComponentFormFieldConfig)[];
108
108
  };
109
- type TabsConfig<T extends {
110
- __typename?: string;
111
- }> = {
112
- type: "tabs";
113
- tabs: {
114
- name: string;
115
- content: GeneratorConfig<T>;
116
- }[];
117
- };
118
109
  type BaseColumnConfig = Pick<GridColDef, "headerName" | "width" | "minWidth" | "maxWidth" | "flex" | "pinned" | "disableExport"> & {
119
110
  headerInfoTooltip?: string;
120
111
  visible?: ColumnVisibleOption;
@@ -125,11 +116,18 @@ export type StaticSelectLabelCellContent = {
125
116
  secondaryText?: string;
126
117
  icon?: Icon;
127
118
  };
119
+ type StaticSelectValue = string | number | boolean;
120
+ type StaticSelectValueObject = {
121
+ value: StaticSelectValue;
122
+ label: string | StaticSelectLabelCellContent;
123
+ };
128
124
  export type GridColumnConfig<T extends GridValidRowModel> = ({
129
125
  type: "text";
130
126
  renderCell?: (params: GridRenderCellParams<T, any, any>) => JSX.Element;
131
127
  } | {
132
128
  type: "number";
129
+ currency?: string;
130
+ decimals?: number;
133
131
  renderCell?: (params: GridRenderCellParams<T, any, any>) => JSX.Element;
134
132
  } | {
135
133
  type: "boolean";
@@ -142,10 +140,7 @@ export type GridColumnConfig<T extends GridValidRowModel> = ({
142
140
  renderCell?: (params: GridRenderCellParams<T, any, any>) => JSX.Element;
143
141
  } | {
144
142
  type: "staticSelect";
145
- values?: Array<{
146
- value: string;
147
- label: string | StaticSelectLabelCellContent;
148
- } | string>;
143
+ values?: Array<StaticSelectValue | StaticSelectValueObject>;
149
144
  } | {
150
145
  type: "block";
151
146
  block: BlockInterface;
@@ -193,10 +188,14 @@ export type GridConfig<T extends {
193
188
  newEntryText?: string;
194
189
  rowActionProp?: boolean;
195
190
  selectionProps?: "multiSelect" | "singleSelect";
191
+ rowReordering?: {
192
+ enabled: boolean;
193
+ dragPreviewField?: UsableFields<T>;
194
+ };
196
195
  };
197
196
  export type GeneratorConfig<T extends {
198
197
  __typename?: string;
199
- }> = FormConfig<T> | GridConfig<T> | TabsConfig<T>;
198
+ }> = FormConfig<T> | GridConfig<T>;
200
199
  export declare function defineConfig<T extends {
201
200
  __typename?: string;
202
201
  }>(config: GeneratorConfig<T>): GeneratorConfig<T>;
@@ -20,9 +20,9 @@ const fs_1 = require("fs");
20
20
  const glob_1 = require("glob");
21
21
  const graphql_1 = require("graphql");
22
22
  const path_1 = require("path");
23
+ const parseConfig_1 = require("./config/parseConfig");
23
24
  const generateForm_1 = require("./generateForm/generateForm");
24
25
  const generateGrid_1 = require("./generateGrid/generateGrid");
25
- const tsMorphHelper_1 = require("./utils/tsMorphHelper");
26
26
  const writeGenerated_1 = require("./utils/writeGenerated");
27
27
  function isFormFieldConfig(arg) {
28
28
  return !isFormLayoutConfig(arg);
@@ -50,13 +50,12 @@ function runGenerate() {
50
50
  const targetDirectory = `${(0, path_1.dirname)(file)}/generated`;
51
51
  const baseOutputFilename = (0, path_1.basename)(file).replace(/\.cometGen\.tsx?$/, "");
52
52
  console.log(`generating ${file}`);
53
- const config = (0, tsMorphHelper_1.configFromSourceFile)((0, tsMorphHelper_1.morphTsSource)(file));
53
+ const config = yield (0, parseConfig_1.parseConfig)(file);
54
+ const codeOuputFilename = `${targetDirectory}/${(0, path_1.basename)(file.replace(/\.cometGen\.tsx?$/, ""))}.tsx`;
55
+ yield fs_1.promises.rm(codeOuputFilename, { force: true });
54
56
  const exportName = (_a = file.match(/([^/]+)\.cometGen\.tsx?$/)) === null || _a === void 0 ? void 0 : _a[1];
55
57
  if (!exportName)
56
58
  throw new Error("Can not determine exportName");
57
- //const configs = await import(`${process.cwd()}/${file.replace(/\.ts$/, "")}`);
58
- const codeOuputFilename = `${targetDirectory}/${(0, path_1.basename)(file.replace(/\.cometGen\.tsx?$/, ""))}.tsx`;
59
- yield fs_1.promises.rm(codeOuputFilename, { force: true });
60
59
  let generated;
61
60
  if (config.type == "form") {
62
61
  generated = (0, generateForm_1.generateForm)({ exportName, gqlIntrospection, baseOutputFilename, targetDirectory }, config);
@@ -65,7 +64,7 @@ function runGenerate() {
65
64
  generated = (0, generateGrid_1.generateGrid)({ exportName, gqlIntrospection, baseOutputFilename, targetDirectory }, config);
66
65
  }
67
66
  else {
68
- throw new Error(`Unknown config type: ${config.type}`);
67
+ throw new Error(`Unknown config type`);
69
68
  }
70
69
  outputCode += generated.code;
71
70
  for (const queryName in generated.gqlDocuments) {
@@ -83,6 +82,7 @@ function runGenerate() {
83
82
  `;
84
83
  yield (0, writeGenerated_1.writeGenerated)(gqlDocumentsOuputFilename, gqlDocumentsOutputCode);
85
84
  }
85
+ console.log("");
86
86
  }
87
87
  });
88
88
  }
@@ -48,7 +48,43 @@ config) {
48
48
  const instanceGqlType = gqlType[0].toLowerCase() + gqlType.substring(1);
49
49
  const formFragmentName = (_a = config.fragmentName) !== null && _a !== void 0 ? _a : `${gqlType}Form`;
50
50
  const gqlDocuments = {};
51
- const imports = [];
51
+ const imports = [
52
+ { name: "FormattedMessage", importPath: "react-intl" },
53
+ { name: "useApolloClient", importPath: "@apollo/client" },
54
+ { name: "useQuery", importPath: "@apollo/client" },
55
+ { name: "gql", importPath: "@apollo/client" },
56
+ { name: "AsyncSelectField", importPath: "@comet/admin" },
57
+ { name: "CheckboxField", importPath: "@comet/admin" },
58
+ { name: "Field", importPath: "@comet/admin" },
59
+ { name: "filterByFragment", importPath: "@comet/admin" },
60
+ { name: "FinalForm", importPath: "@comet/admin" },
61
+ { name: "FinalFormInput", importPath: "@comet/admin" },
62
+ { name: "FinalFormRangeInput", importPath: "@comet/admin" },
63
+ { name: "FinalFormSelect", importPath: "@comet/admin" },
64
+ { name: "FinalFormSubmitEvent", importPath: "@comet/admin" },
65
+ { name: "Loading", importPath: "@comet/admin" },
66
+ { name: "NumberField", importPath: "@comet/admin" },
67
+ { name: "RadioGroupField", importPath: "@comet/admin" },
68
+ { name: "TextAreaField", importPath: "@comet/admin" },
69
+ { name: "TextField", importPath: "@comet/admin" },
70
+ { name: "useFormApiRef", importPath: "@comet/admin" },
71
+ { name: "useStackSwitchApi", importPath: "@comet/admin" },
72
+ { name: "ArrowLeft", importPath: "@comet/admin-icons" },
73
+ { name: "Lock", importPath: "@comet/admin-icons" },
74
+ { name: "DateTimeField", importPath: "@comet/admin-date-time" },
75
+ { name: "FinalFormDatePicker", importPath: "@comet/admin-date-time" },
76
+ { name: "BlockState", importPath: "@comet/cms-admin" },
77
+ { name: "createFinalFormBlock", importPath: "@comet/cms-admin" },
78
+ { name: "queryUpdatedAt", importPath: "@comet/cms-admin" },
79
+ { name: "resolveHasSaveConflict", importPath: "@comet/cms-admin" },
80
+ { name: "useFormSaveConflict", importPath: "@comet/cms-admin" },
81
+ { name: "FileUploadField", importPath: "@comet/cms-admin" },
82
+ { name: "IconButton", importPath: "@mui/material" },
83
+ { name: "MenuItem", importPath: "@mui/material" },
84
+ { name: "InputAdornment", importPath: "@mui/material" },
85
+ { name: "FormApi", importPath: "final-form" },
86
+ { name: "useMemo", importPath: "react" },
87
+ ];
52
88
  const props = [];
53
89
  const mode = (_b = config.mode) !== null && _b !== void 0 ? _b : "all";
54
90
  const editMode = mode === "edit" || mode == "all";
@@ -219,10 +255,12 @@ config) {
219
255
  name: `GQL${documentName}${type[0].toUpperCase() + type.substring(1)}`,
220
256
  importPath: `./${baseOutputFilename}.gql.generated`,
221
257
  });
222
- imports.push({
223
- name: `GQL${documentName}${type[0].toUpperCase() + type.substring(1)}Variables`,
224
- importPath: `./${baseOutputFilename}.gql.generated`,
225
- });
258
+ if (type !== "fragment") {
259
+ imports.push({
260
+ name: `GQL${documentName}${type[0].toUpperCase() + type.substring(1)}Variables`,
261
+ importPath: `./${baseOutputFilename}.gql.generated`,
262
+ });
263
+ }
226
264
  }
227
265
  const finalFormSubscription = Object.keys((_e = (_d = generatedFields.finalFormConfig) === null || _d === void 0 ? void 0 : _d.subscription) !== null && _e !== void 0 ? _e : {});
228
266
  const finalFormRenderProps = Object.keys((_g = (_f = generatedFields.finalFormConfig) === null || _f === void 0 ? void 0 : _f.renderProps) !== null && _g !== void 0 ? _g : {});
@@ -248,34 +286,10 @@ config) {
248
286
  }`;
249
287
  filterByFragmentType = `${formFragmentName}Fragment`;
250
288
  }
251
- const code = `import { useApolloClient, useQuery, gql } from "@apollo/client";
252
- import {
253
- AsyncSelectField,
254
- CheckboxField,
255
- Field,
256
- filterByFragment,
257
- FinalForm,
258
- FinalFormInput,
259
- FinalFormRangeInput,
260
- FinalFormSelect,
261
- FinalFormSubmitEvent,
262
- Loading,
263
- NumberField,
264
- RadioGroupField,
265
- TextAreaField,
266
- TextField,
267
- useFormApiRef,
268
- useStackSwitchApi,
269
- } from "@comet/admin";
270
- import { ArrowLeft, Lock } from "@comet/admin-icons";
271
- import { DateTimeField, FinalFormDatePicker } from "@comet/admin-date-time";
272
- import { BlockState, createFinalFormBlock, queryUpdatedAt, resolveHasSaveConflict, useFormSaveConflict, FileUploadField } from "@comet/cms-admin";
273
- import { FormControlLabel, IconButton, MenuItem, InputAdornment } from "@mui/material";
274
- import { FormApi } from "final-form";
275
- import isEqual from "lodash.isequal";
276
- import { useMemo } from "react";
277
- import { FormattedMessage } from "react-intl";
289
+ const code = `
278
290
  ${(0, generateImportsCode_1.generateImportsCode)(imports)}
291
+ import isEqual from "lodash.isequal";
292
+
279
293
  ${rootBlockFields.length > 0
280
294
  ? `const rootBlocks = {
281
295
  ${rootBlockFields.map((field) => `${String(field.name)}: ${field.block.name}`)}
@@ -284,11 +298,11 @@ config) {
284
298
 
285
299
  ${customFilterByFragment}
286
300
 
287
- type FormValues = ${formValuesConfig.filter((config) => !!config.omitFromFragmentType).length > 0
288
- ? `Omit<${filterByFragmentType}, ${formValuesConfig
289
- .filter((config) => !!config.omitFromFragmentType)
290
- .map((config) => `"${config.omitFromFragmentType}"`)
291
- .join(" | ")}>`
301
+ type FormValues = ${formValuesConfig.filter((config) => !!config.omitFromFragmentType).length > 0 || rootBlockFields.length > 0
302
+ ? `Omit<${filterByFragmentType}, ${[
303
+ ...(rootBlockFields.length > 0 ? ["keyof typeof rootBlocks"] : []),
304
+ ...formValuesConfig.filter((config) => !!config.omitFromFragmentType).map((config) => `"${config.omitFromFragmentType}"`),
305
+ ].join(" | ")}>`
292
306
  : `${filterByFragmentType}`} ${formValuesConfig.filter((config) => !!config.typeCode).length > 0
293
307
  ? `& {
294
308
  ${formValuesConfig
@@ -159,7 +159,7 @@ function generateFormField({ gqlIntrospection, baseOutputFilename, config, formC
159
159
  ${validateCode}
160
160
  />`;
161
161
  if (!config.virtual && !required && !config.readOnly) {
162
- formValueToGqlInputCode = `${name}: formValues.${name} ?? "",`;
162
+ formValueToGqlInputCode = `${name}: formValues.${name} ?? null,`;
163
163
  }
164
164
  }
165
165
  else if (config.type == "number") {