@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
|
@@ -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
|
-
|
|
202
|
-
|
|
203
|
-
const
|
|
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
|
-
|
|
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:
|
|
64
|
+
name: UsableFormFields<T>;
|
|
64
65
|
multiline?: boolean;
|
|
65
66
|
} & InputBaseFieldConfig) | ({
|
|
66
67
|
type: "number";
|
|
67
|
-
name:
|
|
68
|
+
name: UsableFormFields<T>;
|
|
68
69
|
decimals?: number;
|
|
69
70
|
} & InputBaseFieldConfig) | ({
|
|
70
71
|
type: "numberRange";
|
|
71
|
-
name:
|
|
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:
|
|
78
|
+
name: UsableFormFields<T>;
|
|
78
79
|
} | ({
|
|
79
80
|
type: "date";
|
|
80
|
-
name:
|
|
81
|
+
name: UsableFormFields<T>;
|
|
81
82
|
} & InputBaseFieldConfig) | ({
|
|
82
83
|
type: "dateTime";
|
|
83
|
-
name:
|
|
84
|
+
name: UsableFormFields<T>;
|
|
84
85
|
} & InputBaseFieldConfig) | ({
|
|
85
86
|
type: "staticSelect";
|
|
86
|
-
name:
|
|
87
|
+
name: UsableFormFields<T>;
|
|
87
88
|
values?: StaticSelectValue[];
|
|
88
89
|
inputType?: "select" | "radio";
|
|
89
90
|
} & Omit<InputBaseFieldConfig, "endAdornment">) | ({
|
|
90
91
|
type: "asyncSelect";
|
|
91
|
-
name:
|
|
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:
|
|
121
|
+
name: UsableFormFields<T>;
|
|
111
122
|
block: BlockInterface;
|
|
112
123
|
} | ({
|
|
113
124
|
type: "fileUpload";
|
|
114
125
|
multiple?: false;
|
|
115
|
-
name:
|
|
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:
|
|
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:
|
|
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
|
|
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
|
-
|
|
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 = `$
|
|
281
|
+
formValueConfig.formValueToGqlInputCode = `$fieldName ? $fieldName.id : null`;
|
|
271
282
|
}
|
|
272
283
|
else {
|
|
273
|
-
formValueToGqlInputCode = `$
|
|
284
|
+
formValueConfig.formValueToGqlInputCode = `$fieldName?.id`;
|
|
274
285
|
}
|
|
275
286
|
}
|
|
276
287
|
else {
|
|
277
|
-
formValueToGqlInputCode = `$
|
|
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 =
|
|
292
|
-
formValueConfig.initializationCode =
|
|
308
|
+
formValueConfig.typeCode = { nullable: true, type: `{ id: string; ${labelField}: string }` };
|
|
309
|
+
formValueConfig.initializationCode = `data.${instanceGqlType}.${config.loadValueQueryField.replace(/\./g, "?.")}`;
|
|
293
310
|
}
|
|
294
|
-
code =
|
|
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
|
|
306
|
-
|
|
307
|
-
:
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
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,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,
|
|
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,
|
|
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
|
|
80
|
+
return { name, formattedMessageRootId, fieldLabel, startAdornment, endAdornment, imports };
|
|
90
81
|
}
|
|
@@ -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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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,
|