@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.
- package/lib/commands/generate/config/transformConfig.d.ts +6 -0
- package/lib/commands/generate/config/transformConfig.js +36 -8
- package/lib/commands/generate/generate-command.d.ts +49 -15
- package/lib/commands/generate/generate-command.js +5 -0
- package/lib/commands/generate/generateForm/asyncSelect/generateAsyncSelect.js +46 -22
- package/lib/commands/generate/generateForm/flatFormFieldsFromFormConfig.d.ts +2 -0
- package/lib/commands/generate/generateForm/flatFormFieldsFromFormConfig.js +22 -0
- package/lib/commands/generate/generateForm/formField/findIntrospectionFieldType.d.ts +6 -0
- package/lib/commands/generate/generateForm/formField/findIntrospectionFieldType.js +22 -0
- package/lib/commands/generate/generateForm/formField/options.d.ts +1 -5
- package/lib/commands/generate/generateForm/formField/options.js +2 -11
- package/lib/commands/generate/generateForm/generateComponentFormField.js +0 -1
- package/lib/commands/generate/generateForm/generateFields.d.ts +9 -4
- package/lib/commands/generate/generateForm/generateFields.js +0 -3
- package/lib/commands/generate/generateForm/generateForm.js +99 -132
- package/lib/commands/generate/generateForm/generateFormField.js +34 -44
- package/lib/commands/generate/generateForm/generateFormLayout.js +23 -44
- package/lib/commands/generate/generateForm/generateFormValues.d.ts +39 -0
- package/lib/commands/generate/generateForm/generateFormValues.js +217 -0
- package/lib/commands/generate/generateForm/generateFragmentByFormFragmentFields.d.ts +1 -1
- package/lib/commands/generate/generateForm/generateFragmentByFormFragmentFields.js +3 -36
- package/lib/commands/generate/generateForm/getForwardedGqlArgs.d.ts +4 -5
- package/lib/commands/generate/generateForm/getForwardedGqlArgs.js +18 -17
- package/lib/commands/generate/generateGrid/generateGrid.js +49 -35
- package/lib/commands/generate/generateGrid/getForwardedGqlArgs.d.ts +3 -3
- package/lib/commands/generate/generateGrid/getForwardedGqlArgs.js +12 -16
- package/lib/commands/generate/generateGrid/usableFields.d.ts +6 -1
- package/lib/commands/generate/utils/convertConfigImport.d.ts +1 -0
- package/lib/commands/generate/utils/convertConfigImport.js +1 -1
- package/lib/commands/generate/utils/generateGqlOperation.d.ts +12 -0
- package/lib/commands/generate/utils/generateGqlOperation.js +87 -0
- package/lib/commands/generate/utils/generateImportsCode.d.ts +1 -0
- package/lib/commands/generate/utils/generateImportsCode.js +6 -1
- package/lib/index.d.ts +2 -2
- package/lib/index.js +2 -1
- package/package.json +11 -8
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type IntrospectionQuery } from "graphql";
|
|
2
|
+
import { type GenerateFieldsReturn } from "./generateFields";
|
|
3
|
+
type FormValuesConfigTreeNode = {
|
|
4
|
+
config?: GenerateFieldsReturn["formValuesConfig"][0];
|
|
5
|
+
nullable?: boolean;
|
|
6
|
+
children: FormValuesConfigTree;
|
|
7
|
+
};
|
|
8
|
+
type FormValuesConfigTree = {
|
|
9
|
+
[key: string]: FormValuesConfigTreeNode;
|
|
10
|
+
};
|
|
11
|
+
export declare function formValuesConfigToTree({ formValuesConfig, gqlIntrospection, gqlType, }: {
|
|
12
|
+
formValuesConfig: GenerateFieldsReturn["formValuesConfig"];
|
|
13
|
+
gqlIntrospection: IntrospectionQuery;
|
|
14
|
+
gqlType: string;
|
|
15
|
+
}): FormValuesConfigTree;
|
|
16
|
+
export declare function generateFormValuesType({ formValuesConfig, filterByFragmentType, gqlIntrospection, gqlType, }: {
|
|
17
|
+
formValuesConfig: GenerateFieldsReturn["formValuesConfig"];
|
|
18
|
+
filterByFragmentType: string;
|
|
19
|
+
gqlIntrospection: IntrospectionQuery;
|
|
20
|
+
gqlType: string;
|
|
21
|
+
}): string;
|
|
22
|
+
export declare function generateInitialValues({ mode, formValuesConfig, filterByFragmentType, gqlIntrospection, gqlType, }: {
|
|
23
|
+
mode: "all" | "edit" | "add";
|
|
24
|
+
formValuesConfig: GenerateFieldsReturn["formValuesConfig"];
|
|
25
|
+
filterByFragmentType: string;
|
|
26
|
+
gqlIntrospection: IntrospectionQuery;
|
|
27
|
+
gqlType: string;
|
|
28
|
+
}): string;
|
|
29
|
+
export declare function generateDestructFormValueForInput({ formValuesConfig, gqlIntrospection, gqlType, }: {
|
|
30
|
+
formValuesConfig: GenerateFieldsReturn["formValuesConfig"];
|
|
31
|
+
gqlIntrospection: IntrospectionQuery;
|
|
32
|
+
gqlType: string;
|
|
33
|
+
}): string;
|
|
34
|
+
export declare function generateFormValuesToGqlInput({ formValuesConfig, gqlIntrospection, gqlType, }: {
|
|
35
|
+
formValuesConfig: GenerateFieldsReturn["formValuesConfig"];
|
|
36
|
+
gqlIntrospection: IntrospectionQuery;
|
|
37
|
+
gqlType: string;
|
|
38
|
+
}): string;
|
|
39
|
+
export {};
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.formValuesConfigToTree = formValuesConfigToTree;
|
|
4
|
+
exports.generateFormValuesType = generateFormValuesType;
|
|
5
|
+
exports.generateInitialValues = generateInitialValues;
|
|
6
|
+
exports.generateDestructFormValueForInput = generateDestructFormValueForInput;
|
|
7
|
+
exports.generateFormValuesToGqlInput = generateFormValuesToGqlInput;
|
|
8
|
+
// internal represenstation of formValuesConfig as tree to allow recursive processing
|
|
9
|
+
function formValuesConfigToTree({ formValuesConfig, gqlIntrospection, gqlType, }) {
|
|
10
|
+
const treeRoot = { children: {} };
|
|
11
|
+
for (const formValueConfig of formValuesConfig) {
|
|
12
|
+
const fieldName = formValueConfig.fieldName;
|
|
13
|
+
let currentTreeNode = treeRoot;
|
|
14
|
+
let currentGqlType = gqlType;
|
|
15
|
+
for (const part of fieldName.split(".")) {
|
|
16
|
+
const introspectionObject = gqlIntrospection.__schema.types.find((type) => type.kind === "OBJECT" && type.name === currentGqlType);
|
|
17
|
+
if (!introspectionObject)
|
|
18
|
+
throw new Error(`didn't find object ${gqlType} in gql introspection`);
|
|
19
|
+
const introspectionField = introspectionObject.fields.find((field) => field.name === part);
|
|
20
|
+
const introspectionFieldType = introspectionField
|
|
21
|
+
? introspectionField.type.kind === "NON_NULL"
|
|
22
|
+
? introspectionField.type.ofType
|
|
23
|
+
: introspectionField.type
|
|
24
|
+
: undefined;
|
|
25
|
+
if ((introspectionFieldType === null || introspectionFieldType === void 0 ? void 0 : introspectionFieldType.kind) === "OBJECT") {
|
|
26
|
+
// for next loop iteration (nested fields)
|
|
27
|
+
currentGqlType = introspectionFieldType.name;
|
|
28
|
+
}
|
|
29
|
+
if (!currentTreeNode.children[part]) {
|
|
30
|
+
currentTreeNode.children[part] = { children: {} };
|
|
31
|
+
}
|
|
32
|
+
currentTreeNode.children[part].nullable = (introspectionField === null || introspectionField === void 0 ? void 0 : introspectionField.type.kind) !== "NON_NULL";
|
|
33
|
+
currentTreeNode = currentTreeNode.children[part];
|
|
34
|
+
}
|
|
35
|
+
currentTreeNode.config = formValueConfig;
|
|
36
|
+
}
|
|
37
|
+
return treeRoot.children;
|
|
38
|
+
}
|
|
39
|
+
function generateFormValuesTypeFromTree(tree, currentTypeName, currentIsNullable) {
|
|
40
|
+
var _a, _b, _c;
|
|
41
|
+
const omitKeys = [];
|
|
42
|
+
let appendCode = "";
|
|
43
|
+
for (const [key, value] of Object.entries(tree)) {
|
|
44
|
+
if (Object.keys(value.children).length > 0) {
|
|
45
|
+
let childRootType = `${currentTypeName}["${key}"]`;
|
|
46
|
+
if (currentIsNullable) {
|
|
47
|
+
childRootType = `NonNullable<${currentTypeName}>["${key}"]`;
|
|
48
|
+
}
|
|
49
|
+
const childOmit = generateFormValuesTypeFromTree(value.children, childRootType, (_a = value.nullable) !== null && _a !== void 0 ? _a : false);
|
|
50
|
+
if (childOmit !== childRootType) {
|
|
51
|
+
appendCode += `${key}: ${childOmit}`;
|
|
52
|
+
omitKeys.push(key);
|
|
53
|
+
}
|
|
54
|
+
if ((_b = value.config) === null || _b === void 0 ? void 0 : _b.typeCode) {
|
|
55
|
+
throw new Error("Field has both subfields and direct typeCode, which is not supported.");
|
|
56
|
+
}
|
|
57
|
+
if ((_c = value.config) === null || _c === void 0 ? void 0 : _c.omitFromFragmentType) {
|
|
58
|
+
throw new Error("Field has both subfields and direct omitFromFragmentType, which is not supported.");
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
else if (value.config) {
|
|
62
|
+
if (value.config.typeCode) {
|
|
63
|
+
appendCode += `${key}${value.config.typeCode.nullable ? "?" : ""}: ${value.config.typeCode.type}; `;
|
|
64
|
+
}
|
|
65
|
+
if (value.config.omitFromFragmentType) {
|
|
66
|
+
omitKeys.push(key);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
let code = omitKeys.length
|
|
71
|
+
? `Omit<${currentIsNullable ? `NonNullable<` : ""}${currentTypeName}${currentIsNullable ? `>` : ""}, ${omitKeys.map((k) => `"${k}"`).join(" | ")}>`
|
|
72
|
+
: currentTypeName;
|
|
73
|
+
if (appendCode.length) {
|
|
74
|
+
code += ` & { ${appendCode} }`;
|
|
75
|
+
}
|
|
76
|
+
return code;
|
|
77
|
+
}
|
|
78
|
+
function generateFormValuesType({ formValuesConfig, filterByFragmentType, gqlIntrospection, gqlType, }) {
|
|
79
|
+
const tree = formValuesConfigToTree({ formValuesConfig, gqlIntrospection, gqlType });
|
|
80
|
+
return `type FormValues = ${generateFormValuesTypeFromTree(tree, filterByFragmentType, false)};`;
|
|
81
|
+
}
|
|
82
|
+
function generateInitialValuesFromTree(tree, dataObject, generationType) {
|
|
83
|
+
var _a;
|
|
84
|
+
let code = "";
|
|
85
|
+
for (const [key, value] of Object.entries(tree)) {
|
|
86
|
+
if (Object.keys(value.children).length > 0) {
|
|
87
|
+
let childCode = generateInitialValuesFromTree(value.children, `${dataObject}.${key}`, generationType);
|
|
88
|
+
if (childCode.length) {
|
|
89
|
+
if (generationType == "initializationCode") {
|
|
90
|
+
childCode = `{ ...${dataObject}.${key}, ${childCode} }`;
|
|
91
|
+
if (value.nullable) {
|
|
92
|
+
code += `${key}: ${dataObject}.${key} ? ${childCode} : undefined, `;
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
code += `${key}: ${childCode}, `;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
code += `${key}: { ${childCode} }, `;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if ((_a = value.config) === null || _a === void 0 ? void 0 : _a[generationType]) {
|
|
103
|
+
throw new Error("Field has both subfields and direct initialization code, which is not supported.");
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
else if (value.config) {
|
|
107
|
+
if (value.config[generationType]) {
|
|
108
|
+
code += `${key}: ${value.config[generationType]}, `;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return code;
|
|
113
|
+
}
|
|
114
|
+
function generateInitialValues({ mode, formValuesConfig, filterByFragmentType, gqlIntrospection, gqlType, }) {
|
|
115
|
+
const instanceGqlType = gqlType[0].toLowerCase() + gqlType.substring(1);
|
|
116
|
+
const editMode = mode === "edit" || mode == "all";
|
|
117
|
+
const tree = formValuesConfigToTree({ formValuesConfig, gqlIntrospection, gqlType });
|
|
118
|
+
if (editMode) {
|
|
119
|
+
return `const initialValues = useMemo<Partial<FormValues>>(() => data?.${instanceGqlType}
|
|
120
|
+
? {
|
|
121
|
+
...filterByFragment<${filterByFragmentType}>(${instanceGqlType}FormFragment, data.${instanceGqlType}),
|
|
122
|
+
${generateInitialValuesFromTree(tree, `data.${instanceGqlType}`, "initializationCode")}
|
|
123
|
+
}
|
|
124
|
+
: {
|
|
125
|
+
${generateInitialValuesFromTree(tree, `data.${instanceGqlType}`, "defaultInitializationCode")}
|
|
126
|
+
}
|
|
127
|
+
, [data]);`;
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
return `const initialValues = {
|
|
131
|
+
${generateInitialValuesFromTree(tree, `data.${instanceGqlType}`, "defaultInitializationCode")}
|
|
132
|
+
};`;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
function generateDestructFormValueForInputFromTree(tree, restObject) {
|
|
136
|
+
let code = "";
|
|
137
|
+
for (const [key, value] of Object.entries(tree)) {
|
|
138
|
+
if (Object.keys(value.children).length > 0) {
|
|
139
|
+
const childCode = generateDestructFormValueForInputFromTree(value.children, `${restObject}${key.substring(0, 1).toUpperCase()}${key.substring(1)}`);
|
|
140
|
+
if (childCode.length) {
|
|
141
|
+
code += `${key}: { ${childCode} }, `;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
else if (value.config) {
|
|
145
|
+
if (value.config.destructFromFormValues) {
|
|
146
|
+
code += `${key}, `;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
if (code.length) {
|
|
151
|
+
code += `...${restObject}Rest`;
|
|
152
|
+
return code;
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
return "";
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
function generateDestructFormValueForInput({ formValuesConfig, gqlIntrospection, gqlType, }) {
|
|
159
|
+
const tree = formValuesConfigToTree({ formValuesConfig, gqlIntrospection, gqlType });
|
|
160
|
+
const code = generateDestructFormValueForInputFromTree(tree, "formValues");
|
|
161
|
+
return code.length ? `{ ${code} }` : "formValues";
|
|
162
|
+
}
|
|
163
|
+
function generateFormValuesToGqlInputFromTree(tree, dataObject, restObject) {
|
|
164
|
+
var _a, _b;
|
|
165
|
+
let code = "";
|
|
166
|
+
for (const [key, value] of Object.entries(tree)) {
|
|
167
|
+
if (Object.keys(value.children).length > 0) {
|
|
168
|
+
const childRestObject = `${restObject.replace(/Rest$/, "")}${key.substring(0, 1).toUpperCase()}${key.substring(1)}Rest`;
|
|
169
|
+
const hasChildDestruct = hasChildDestructTree(value.children);
|
|
170
|
+
let childCode = generateFormValuesToGqlInputFromTree(value.children, hasChildDestruct ? childRestObject : `${dataObject}.${key}`, childRestObject);
|
|
171
|
+
if (childCode.length || hasChildDestruct) {
|
|
172
|
+
childCode = `{ ...${hasChildDestruct ? childRestObject : `${dataObject}.${key}`}, ${childCode} }`;
|
|
173
|
+
if ((_a = value.config) === null || _a === void 0 ? void 0 : _a.wrapFormValueToGqlInputCode) {
|
|
174
|
+
childCode = value.config.wrapFormValueToGqlInputCode
|
|
175
|
+
.replaceAll("$fieldName", `${dataObject}.${key}`)
|
|
176
|
+
.replaceAll("$inner", childCode);
|
|
177
|
+
}
|
|
178
|
+
code += `${key}: ${childCode}, `;
|
|
179
|
+
}
|
|
180
|
+
if ((_b = value.config) === null || _b === void 0 ? void 0 : _b.formValueToGqlInputCode) {
|
|
181
|
+
throw new Error("Field has both subfields and direct formValueToGqlInputCode, which is not supported.");
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
else if (value.config) {
|
|
185
|
+
if (value.config.formValueToGqlInputCode) {
|
|
186
|
+
code += `${key}: ${value.config.formValueToGqlInputCode.replaceAll("$fieldName", `${dataObject}.${key}`)}, `;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return code;
|
|
191
|
+
}
|
|
192
|
+
function hasChildDestructTree(tree) {
|
|
193
|
+
return Object.values(tree).some((childValue) => {
|
|
194
|
+
var _a;
|
|
195
|
+
if ((_a = childValue.config) === null || _a === void 0 ? void 0 : _a.destructFromFormValues) {
|
|
196
|
+
return true;
|
|
197
|
+
}
|
|
198
|
+
if (Object.keys(childValue.children).length > 0) {
|
|
199
|
+
return hasChildDestructTree(childValue.children);
|
|
200
|
+
}
|
|
201
|
+
return false;
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
function generateFormValuesToGqlInput({ formValuesConfig, gqlIntrospection, gqlType, }) {
|
|
205
|
+
const tree = formValuesConfigToTree({ formValuesConfig, gqlIntrospection, gqlType });
|
|
206
|
+
const hasChildDestruct = hasChildDestructTree(tree);
|
|
207
|
+
const code = generateFormValuesToGqlInputFromTree(tree, hasChildDestruct ? "formValuesRest" : "formValues", hasChildDestruct ? "formValuesRest" : "formValues");
|
|
208
|
+
if (code.length) {
|
|
209
|
+
return `const output = { ...${hasChildDestruct ? "formValuesRest" : "formValues"}, ${code} };`;
|
|
210
|
+
}
|
|
211
|
+
else if (hasChildDestruct) {
|
|
212
|
+
return `const output = formValuesRest;`;
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
return `const output = formValues;`;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Helper function that generates a GraphQL fragment from form fragment fields (array of dot.separated.fields).
|
|
3
3
|
*
|
|
4
|
-
* - Fragments are supported as "foo
|
|
4
|
+
* - Fragments are supported as "foo...FragmentName"
|
|
5
5
|
* - for FinalFormFileUpload and FinalFormFileUploadDownloadable the needed variable is added automatically
|
|
6
6
|
*/
|
|
7
7
|
export declare function generateFragmentByFormFragmentFields({ formFragmentName, gqlType, formFragmentFields, }: {
|
|
@@ -1,50 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.generateFragmentByFormFragmentFields = generateFragmentByFormFragmentFields;
|
|
7
|
-
const
|
|
4
|
+
const generateGqlOperation_1 = require("../utils/generateGqlOperation");
|
|
8
5
|
/**
|
|
9
6
|
* Helper function that generates a GraphQL fragment from form fragment fields (array of dot.separated.fields).
|
|
10
7
|
*
|
|
11
|
-
* - Fragments are supported as "foo
|
|
8
|
+
* - Fragments are supported as "foo...FragmentName"
|
|
12
9
|
* - for FinalFormFileUpload and FinalFormFileUploadDownloadable the needed variable is added automatically
|
|
13
10
|
*/
|
|
14
11
|
function generateFragmentByFormFragmentFields({ formFragmentName, gqlType, formFragmentFields, }) {
|
|
15
|
-
// 1. create tree out of dot separated fields
|
|
16
|
-
const fieldsObject = formFragmentFields.reduce((acc, field) => {
|
|
17
|
-
const fragmentMatch = field.match(/(.*)({.*?})/); // keep { ... } parts as they are, contains eg. fragments
|
|
18
|
-
if (fragmentMatch) {
|
|
19
|
-
object_path_1.default.set(acc, fragmentMatch[1].trim(), fragmentMatch[2]);
|
|
20
|
-
}
|
|
21
|
-
else {
|
|
22
|
-
object_path_1.default.set(acc, field, true);
|
|
23
|
-
}
|
|
24
|
-
return acc;
|
|
25
|
-
}, {});
|
|
26
|
-
// 2. create fragment string out of tree
|
|
27
|
-
const recursiveStringify = (obj) => {
|
|
28
|
-
let ret = "";
|
|
29
|
-
let prefixField = "";
|
|
30
|
-
for (const key in obj) {
|
|
31
|
-
const value = obj[key];
|
|
32
|
-
if (typeof value === "boolean") {
|
|
33
|
-
ret += `${prefixField}${key}`;
|
|
34
|
-
}
|
|
35
|
-
else if (typeof value === "string") {
|
|
36
|
-
ret += `${prefixField}${key} ${value}`;
|
|
37
|
-
}
|
|
38
|
-
else {
|
|
39
|
-
ret += `${prefixField}${key} { ${recursiveStringify(value)} }`;
|
|
40
|
-
}
|
|
41
|
-
prefixField = " ";
|
|
42
|
-
}
|
|
43
|
-
return ret;
|
|
44
|
-
};
|
|
45
12
|
let fragmentCode = `
|
|
46
13
|
fragment ${formFragmentName} on ${gqlType} {
|
|
47
|
-
${
|
|
14
|
+
${(0, generateGqlOperation_1.generateGqlQueryTreeFromFields)(formFragmentFields)}
|
|
48
15
|
}
|
|
49
16
|
`;
|
|
50
17
|
// 3. add fragment instance variables when fragments are used
|
|
@@ -2,7 +2,7 @@ import { type IntrospectionField, type IntrospectionQuery } from "graphql";
|
|
|
2
2
|
import { type FormFieldConfig } from "../generate-command";
|
|
3
3
|
import { type Imports } from "../utils/generateImportsCode";
|
|
4
4
|
import { type Prop } from "./generateForm";
|
|
5
|
-
type GqlArg = {
|
|
5
|
+
export type GqlArg = {
|
|
6
6
|
type: string;
|
|
7
7
|
name: string;
|
|
8
8
|
isInputArgSubfield: boolean;
|
|
@@ -13,7 +13,6 @@ export declare function getForwardedGqlArgs({ fields, gqlOperation, gqlIntrospec
|
|
|
13
13
|
gqlIntrospection: IntrospectionQuery;
|
|
14
14
|
}): {
|
|
15
15
|
imports: Imports;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
};
|
|
19
|
-
export {};
|
|
16
|
+
prop: Prop;
|
|
17
|
+
gqlArg: GqlArg;
|
|
18
|
+
}[];
|
|
@@ -2,36 +2,37 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getForwardedGqlArgs = getForwardedGqlArgs;
|
|
4
4
|
function getForwardedGqlArgs({ fields, gqlOperation, gqlIntrospection, }) {
|
|
5
|
-
const
|
|
6
|
-
const props = [];
|
|
7
|
-
const gqlArgs = [];
|
|
8
|
-
const skipGqlInputArgFields = fields.map((field) => String(field.name));
|
|
5
|
+
const ret = [];
|
|
9
6
|
getArgsIncludingInputArgSubfields(gqlOperation, gqlIntrospection).forEach((arg) => {
|
|
10
|
-
if (arg.isInputArgSubfield
|
|
11
|
-
|
|
7
|
+
if (arg.isInputArgSubfield) {
|
|
8
|
+
if (fields.some((field) => {
|
|
9
|
+
return field.name === arg.name || field.name.startsWith(`${arg.name}.`);
|
|
10
|
+
})) {
|
|
11
|
+
// there is a field (or subfield) in this form, no need to forward this arg
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
let prop;
|
|
16
|
+
const imports = [];
|
|
12
17
|
if (arg.type === "ID" || arg.type === "String" || arg.type === "DateTime") {
|
|
13
|
-
|
|
18
|
+
prop = { name: arg.name, optional: false, type: "string" };
|
|
14
19
|
}
|
|
15
20
|
else if (arg.type === "Boolean") {
|
|
16
|
-
|
|
21
|
+
prop = { name: arg.name, optional: false, type: "boolean" };
|
|
17
22
|
}
|
|
18
23
|
else if (arg.type === "Int" || arg.type === "Float") {
|
|
19
|
-
|
|
24
|
+
prop = { name: arg.name, optional: false, type: "number" };
|
|
20
25
|
}
|
|
21
26
|
else if (arg.type === "JSONObject") {
|
|
22
|
-
|
|
27
|
+
prop = { name: arg.name, optional: false, type: "unknown" };
|
|
23
28
|
}
|
|
24
29
|
else {
|
|
25
|
-
|
|
30
|
+
prop = { name: arg.name, optional: false, type: `GQL${arg.type}` }; // generated types contain GQL prefix
|
|
26
31
|
imports.push({ name: `GQL${arg.type}`, importPath: "@src/graphql.generated" });
|
|
27
32
|
}
|
|
28
|
-
|
|
33
|
+
ret.push({ gqlArg: arg, prop, imports });
|
|
29
34
|
});
|
|
30
|
-
return
|
|
31
|
-
imports,
|
|
32
|
-
props,
|
|
33
|
-
gqlArgs,
|
|
34
|
-
};
|
|
35
|
+
return ret;
|
|
35
36
|
}
|
|
36
37
|
function getArgsIncludingInputArgSubfields(gqlOperation, gqlIntrospection) {
|
|
37
38
|
const nativeScalars = ["ID", "String", "Boolean", "Int", "Float", "DateTime", "JSONObject"];
|
|
@@ -18,6 +18,7 @@ const convertConfigImport_1 = require("../utils/convertConfigImport");
|
|
|
18
18
|
const findMutationType_1 = require("../utils/findMutationType");
|
|
19
19
|
const findQueryType_1 = require("../utils/findQueryType");
|
|
20
20
|
const findRootBlocks_1 = require("../utils/findRootBlocks");
|
|
21
|
+
const generateGqlOperation_1 = require("../utils/generateGqlOperation");
|
|
21
22
|
const generateImportsCode_1 = require("../utils/generateImportsCode");
|
|
22
23
|
const runtimeTypeGuards_1 = require("../utils/runtimeTypeGuards");
|
|
23
24
|
const findInputObjectType_1 = require("./findInputObjectType");
|
|
@@ -160,7 +161,6 @@ function generateGrid({ exportName, baseOutputFilename, targetDirectory, gqlIntr
|
|
|
160
161
|
{ name: "useDataGridRemote", importPath: "@comet/admin" },
|
|
161
162
|
{ name: "usePersistentColumnState", importPath: "@comet/admin" },
|
|
162
163
|
{ name: "BlockPreviewContent", importPath: "@comet/cms-admin" },
|
|
163
|
-
{ name: "useContentScope", importPath: "@comet/cms-admin" },
|
|
164
164
|
{ name: "Alert", importPath: "@mui/material" },
|
|
165
165
|
{ name: "Box", importPath: "@mui/material" },
|
|
166
166
|
{ name: "IconButton", importPath: "@mui/material" },
|
|
@@ -179,6 +179,7 @@ function generateGrid({ exportName, baseOutputFilename, targetDirectory, gqlIntr
|
|
|
179
179
|
{ name: "GridColumnHeaderTitle", importPath: "@mui/x-data-grid-pro" },
|
|
180
180
|
{ name: "GridToolbarQuickFilter", importPath: "@mui/x-data-grid-pro" },
|
|
181
181
|
{ name: "GridRowOrderChangeParams", importPath: "@mui/x-data-grid-pro" },
|
|
182
|
+
{ name: "useMemo", importPath: "react" },
|
|
182
183
|
];
|
|
183
184
|
const iconsToImport = ["Add", "Edit", "Info", "Excel"];
|
|
184
185
|
const props = [];
|
|
@@ -229,9 +230,24 @@ function generateGrid({ exportName, baseOutputFilename, targetDirectory, gqlIntr
|
|
|
229
230
|
const showCrudContextMenuInActionsColumn = allowDeleting;
|
|
230
231
|
const showEditInActionsColumn = allowEditing && !forwardRowAction;
|
|
231
232
|
const defaultActionsColumnWidth = getDefaultActionsColumnWidth(showCrudContextMenuInActionsColumn, showEditInActionsColumn);
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
233
|
+
let useScopeFromContext = false;
|
|
234
|
+
const gqlArgs = [];
|
|
235
|
+
{
|
|
236
|
+
const forwardedArgs = (0, getForwardedGqlArgs_1.getForwardedGqlArgs)([gridQueryType]);
|
|
237
|
+
for (const forwardedArg of forwardedArgs) {
|
|
238
|
+
imports.push(...forwardedArg.imports);
|
|
239
|
+
if (forwardedArg.gqlArg.name === "scope" && !config.scopeAsProp) {
|
|
240
|
+
useScopeFromContext = true;
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
props.push(forwardedArg.prop);
|
|
244
|
+
gqlArgs.push(forwardedArg.gqlArg);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
if (useScopeFromContext) {
|
|
249
|
+
imports.push({ name: "useContentScope", importPath: "@comet/cms-admin" });
|
|
250
|
+
}
|
|
235
251
|
const renderToolbar = (_f = config.toolbar) !== null && _f !== void 0 ? _f : true;
|
|
236
252
|
const filterArg = gridQueryType.args.find((arg) => arg.name === "filter");
|
|
237
253
|
const hasFilter = !!filterArg && renderToolbar && !allowRowReordering;
|
|
@@ -285,7 +301,6 @@ function generateGrid({ exportName, baseOutputFilename, targetDirectory, gqlIntr
|
|
|
285
301
|
}
|
|
286
302
|
}
|
|
287
303
|
const hasSearch = gridQueryType.args.some((arg) => arg.name === "search") && !allowRowReordering;
|
|
288
|
-
const hasScope = gridQueryType.args.some((arg) => arg.name === "scope");
|
|
289
304
|
const schemaEntity = gqlIntrospection.__schema.types.find((type) => type.kind === "OBJECT" && type.name === gqlType);
|
|
290
305
|
if (!schemaEntity)
|
|
291
306
|
throw new Error("didn't find entity in schema types");
|
|
@@ -489,7 +504,7 @@ function generateGrid({ exportName, baseOutputFilename, targetDirectory, gqlIntr
|
|
|
489
504
|
if (forwardRowAction) {
|
|
490
505
|
props.push({
|
|
491
506
|
name: "rowAction",
|
|
492
|
-
type: `(params: GridRenderCellParams<
|
|
507
|
+
type: `(params: GridRenderCellParams<GQL${fragmentName}Fragment>) => ReactNode`,
|
|
493
508
|
optional: true,
|
|
494
509
|
});
|
|
495
510
|
props.push({
|
|
@@ -555,31 +570,30 @@ function generateGrid({ exportName, baseOutputFilename, targetDirectory, gqlIntr
|
|
|
555
570
|
}
|
|
556
571
|
\`;
|
|
557
572
|
|
|
558
|
-
const ${instanceGqlTypePlural}Query = gql
|
|
559
|
-
query
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
\`;
|
|
573
|
+
const ${instanceGqlTypePlural}Query = gql\`${(0, generateGqlOperation_1.generateGqlOperation)({
|
|
574
|
+
type: "query",
|
|
575
|
+
operationName: `${gqlTypePlural}Grid`,
|
|
576
|
+
rootOperation: gridQuery,
|
|
577
|
+
fields: [`nodes...${fragmentName}`, "totalCount"],
|
|
578
|
+
fragmentVariables: [`\${${instanceGqlTypePlural}Fragment}`],
|
|
579
|
+
variables: [
|
|
580
|
+
...gqlArgs
|
|
581
|
+
.filter((gqlArg) => gqlArg.queryOrMutationName === gridQueryType.name)
|
|
582
|
+
.map((gqlArg) => ({ name: gqlArg.name, type: `${gqlArg.type}!` })),
|
|
583
|
+
{
|
|
584
|
+
name: "offset",
|
|
585
|
+
type: "Int!",
|
|
586
|
+
},
|
|
587
|
+
{
|
|
588
|
+
name: "limit",
|
|
589
|
+
type: "Int!",
|
|
590
|
+
},
|
|
591
|
+
...(hasSort ? [{ name: "sort", type: `[${gqlType}Sort!]` }] : []),
|
|
592
|
+
...(hasSearch ? [{ name: "search", type: "String" }] : []),
|
|
593
|
+
...(filterArg && (hasFilter || hasFilterProp) ? [{ name: "filter", type: `${gqlType}Filter` }] : []),
|
|
594
|
+
...(useScopeFromContext ? [{ name: "scope", type: `${gqlType}ContentScopeInput!` }] : []),
|
|
595
|
+
],
|
|
596
|
+
})}\`;
|
|
583
597
|
|
|
584
598
|
${allowRowReordering
|
|
585
599
|
? `const update${gqlType}PositionMutation = gql\`
|
|
@@ -627,12 +641,12 @@ function generateGrid({ exportName, baseOutputFilename, targetDirectory, gqlIntr
|
|
|
627
641
|
: config.selectionProps === "singleSelect"
|
|
628
642
|
? `, rowSelectionModel, onRowSelectionModelChange, checkboxSelection: false, keepNonExistentRowsSelected: false, disableRowSelectionOnClick: false`
|
|
629
643
|
: ``} };
|
|
630
|
-
${
|
|
644
|
+
${useScopeFromContext ? `const { scope } = useContentScope();` : ""}
|
|
631
645
|
${gridNeedsTheme ? `const theme = useTheme();` : ""}
|
|
632
646
|
|
|
633
647
|
${generateHandleRowOrderChange(allowRowReordering, gqlType, instanceGqlTypePlural)}
|
|
634
648
|
|
|
635
|
-
const columns: GridColDef<GQL${fragmentName}Fragment>[] = [
|
|
649
|
+
const columns: GridColDef<GQL${fragmentName}Fragment>[] = useMemo(()=>[
|
|
636
650
|
${gridColumnFields
|
|
637
651
|
.map((column) => {
|
|
638
652
|
const defaultMinWidth = 150;
|
|
@@ -727,7 +741,7 @@ function generateGrid({ exportName, baseOutputFilename, targetDirectory, gqlIntr
|
|
|
727
741
|
);
|
|
728
742
|
}` }))
|
|
729
743
|
: ""}
|
|
730
|
-
];
|
|
744
|
+
],[intl${gridNeedsTheme ? ", theme" : ""}${showCrudContextMenuInActionsColumn ? ", client" : ""}${forwardRowAction ? ", rowAction, actionsColumnWidth" : ""}]);
|
|
731
745
|
|
|
732
746
|
${hasFilter || hasSearch
|
|
733
747
|
? `const { ${hasFilter ? `filter: gqlFilter, ` : ""}${hasSearch ? `search: gqlSearch, ` : ""} } = muiGridFilterToGql(columns, dataGridProps.filterModel);`
|
|
@@ -737,7 +751,7 @@ function generateGrid({ exportName, baseOutputFilename, targetDirectory, gqlIntr
|
|
|
737
751
|
variables: {
|
|
738
752
|
${[
|
|
739
753
|
...gqlArgs.filter((gqlArg) => gqlArg.queryOrMutationName === gridQueryType.name).map((arg) => arg.name),
|
|
740
|
-
...(
|
|
754
|
+
...(useScopeFromContext ? ["scope"] : []),
|
|
741
755
|
...(filterArg
|
|
742
756
|
? hasFilter && hasFilterProp
|
|
743
757
|
? ["filter: filter ? { and: [gqlFilter, filter] } : gqlFilter"]
|
|
@@ -2,34 +2,30 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getForwardedGqlArgs = getForwardedGqlArgs;
|
|
4
4
|
function getForwardedGqlArgs(gqlFields) {
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const props = [];
|
|
8
|
-
const gqlArgs = [];
|
|
5
|
+
const ret = [];
|
|
6
|
+
const supportedGqlArgs = ["offset", "limit", "sort", "search", "filter", "input"]; // this arguments need to be handled differently or are already handled somewhere else
|
|
9
7
|
getArgs(gqlFields, supportedGqlArgs).forEach((arg) => {
|
|
8
|
+
let prop;
|
|
9
|
+
const imports = [];
|
|
10
10
|
if (arg.type === "ID" || arg.type === "String" || arg.type === "DateTime") {
|
|
11
|
-
|
|
11
|
+
prop = { name: arg.name, optional: false, type: "string" };
|
|
12
12
|
}
|
|
13
13
|
else if (arg.type === "Boolean") {
|
|
14
|
-
|
|
14
|
+
prop = { name: arg.name, optional: false, type: "boolean" };
|
|
15
15
|
}
|
|
16
16
|
else if (arg.type === "Int" || arg.type === "Float") {
|
|
17
|
-
|
|
17
|
+
prop = { name: arg.name, optional: false, type: "number" };
|
|
18
18
|
}
|
|
19
19
|
else if (arg.type === "JSONObject") {
|
|
20
|
-
|
|
20
|
+
prop = { name: arg.name, optional: false, type: "unknown" };
|
|
21
21
|
}
|
|
22
22
|
else {
|
|
23
|
-
|
|
24
|
-
imports.push({ name: arg.type
|
|
23
|
+
prop = { name: arg.name, optional: false, type: `GQL${arg.type}` }; // generated types contain GQL prefix
|
|
24
|
+
imports.push({ name: `GQL${arg.type}`, importPath: "@src/graphql.generated" });
|
|
25
25
|
}
|
|
26
|
-
|
|
26
|
+
ret.push({ gqlArg: { name: arg.name, type: arg.type, queryOrMutationName: arg.gqlField.name }, prop, imports });
|
|
27
27
|
});
|
|
28
|
-
return
|
|
29
|
-
imports,
|
|
30
|
-
props,
|
|
31
|
-
gqlArgs,
|
|
32
|
-
};
|
|
28
|
+
return ret;
|
|
33
29
|
}
|
|
34
30
|
function getArgs(gqlFields, skipGqlArgs) {
|
|
35
31
|
return gqlFields.reduce((acc, gqlField) => {
|
|
@@ -2,8 +2,13 @@ type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
|
|
2
2
|
type GqlLeaves<T, FollowArrays extends boolean = false, Depth extends number = 5> = [Depth] extends [never] ? never : T extends any ? T extends Array<infer ArrayType> ? FollowArrays extends true ? GqlLeaves<ArrayType, FollowArrays, Prev[Depth]> : never : "__typename" extends keyof T ? {
|
|
3
3
|
[K in keyof T as K extends "__typename" ? never : K]-?: GqlLeaves<T[K], FollowArrays, Prev[Depth]>;
|
|
4
4
|
} : never : never;
|
|
5
|
+
type IfExplicitAny<T, Y, N> = T extends never ? Y : N;
|
|
5
6
|
type FieldNames<T> = {
|
|
6
7
|
[K in keyof T]: `${Exclude<K, symbol>}${FieldNames<T[K]> extends never ? "" : `.${FieldNames<T[K]>}`}`;
|
|
7
8
|
}[keyof T];
|
|
8
|
-
export type UsableFields<T, FollowArrays extends boolean = false> = FieldNames<GqlLeaves<T, FollowArrays
|
|
9
|
+
export type UsableFields<T, FollowArrays extends boolean = false> = IfExplicitAny<T, any, FieldNames<GqlLeaves<T, FollowArrays>>>;
|
|
10
|
+
type FormFieldNames<T> = {
|
|
11
|
+
[K in keyof T]: `${Exclude<K, symbol>}` | (FormFieldNames<T[K]> extends never ? never : `${Exclude<K, symbol>}.${FormFieldNames<T[K]>}`);
|
|
12
|
+
}[keyof T];
|
|
13
|
+
export type UsableFormFields<T> = IfExplicitAny<T, any, FormFieldNames<GqlLeaves<T, false>>>;
|
|
9
14
|
export {};
|