@comet/api-generator 8.0.0-beta.3 → 8.0.0-beta.4
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.
|
@@ -11,9 +11,6 @@ export declare function buildOptions(metadata: EntityMetadata<any>, generatorOpt
|
|
|
11
11
|
hasSlugProp: boolean;
|
|
12
12
|
hasPositionProp: boolean;
|
|
13
13
|
positionGroupProps: import("@mikro-orm/postgresql").EntityProperty<any, any>[];
|
|
14
|
-
statusProp: import("@mikro-orm/postgresql").EntityProperty<any, any> | undefined;
|
|
15
|
-
statusActiveItems: (string | number)[] | undefined;
|
|
16
|
-
hasStatusFilter: boolean | undefined;
|
|
17
14
|
scopeProp: import("@mikro-orm/postgresql").EntityProperty<any, any> | undefined;
|
|
18
15
|
skipScopeCheck: boolean;
|
|
19
16
|
argsClassName: string;
|
|
@@ -56,7 +56,7 @@ const generate_imports_code_1 = require("../utils/generate-imports-code");
|
|
|
56
56
|
const ts_morph_helper_1 = require("../utils/ts-morph-helper");
|
|
57
57
|
// TODO move into own file
|
|
58
58
|
function buildOptions(metadata, generatorOptions) {
|
|
59
|
-
var _a, _b
|
|
59
|
+
var _a, _b;
|
|
60
60
|
const { classNameSingular, classNamePlural, fileNameSingular, fileNamePlural } = (0, build_name_variants_1.buildNameVariants)(metadata);
|
|
61
61
|
const dedicatedResolverArgProps = metadata.props.filter((prop) => {
|
|
62
62
|
if ((0, cms_api_1.hasCrudFieldFeature)(metadata.class, prop.name, "dedicatedResolverArg")) {
|
|
@@ -72,34 +72,6 @@ function buildOptions(metadata, generatorOptions) {
|
|
|
72
72
|
});
|
|
73
73
|
const crudSearchPropNames = (0, cms_api_1.getCrudSearchFieldsFromMetadata)(metadata);
|
|
74
74
|
const hasSearchArg = crudSearchPropNames.length > 0;
|
|
75
|
-
let statusProp = metadata.props.find((prop) => prop.name == "status");
|
|
76
|
-
if (statusProp) {
|
|
77
|
-
if (!statusProp.enum) {
|
|
78
|
-
console.warn(`${metadata.className} status prop must be an enum to be supported by crud generator`);
|
|
79
|
-
statusProp = undefined;
|
|
80
|
-
}
|
|
81
|
-
else if (statusProp.nullable) {
|
|
82
|
-
console.warn(`${metadata.className} status prop must not be nullable to be supported by crud generator`);
|
|
83
|
-
statusProp = undefined;
|
|
84
|
-
}
|
|
85
|
-
else if (((_a = (0, ts_morph_helper_1.morphTsProperty)(statusProp.name, metadata).getInitializer()) === null || _a === void 0 ? void 0 : _a.getText()) == "") {
|
|
86
|
-
console.warn(`${metadata.className} status prop must have a default value to be supported by crud generator`);
|
|
87
|
-
statusProp = undefined;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
let statusActiveItems = undefined;
|
|
91
|
-
if (statusProp) {
|
|
92
|
-
if (!statusProp.items)
|
|
93
|
-
throw new Error("Status enum prop has not items");
|
|
94
|
-
statusActiveItems = statusProp.items.filter((item) => {
|
|
95
|
-
if (typeof item == "number") {
|
|
96
|
-
console.warn(`${metadata.className} status prop must not have numeric items to be supported by crud generator`);
|
|
97
|
-
return false;
|
|
98
|
-
}
|
|
99
|
-
return ["Active", "Visible", "Invisible", "Published", "Unpublished"].includes(item);
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
const hasStatusFilter = statusProp && statusActiveItems && statusActiveItems.length != ((_b = statusProp.items) === null || _b === void 0 ? void 0 : _b.length); //if all items are active ones, no need for status filter
|
|
103
75
|
const crudFilterProps = metadata.props.filter((prop) => (0, cms_api_1.hasCrudFieldFeature)(metadata.class, prop.name, "filter") &&
|
|
104
76
|
!prop.name.startsWith("scope_") &&
|
|
105
77
|
prop.name != "position" &&
|
|
@@ -117,7 +89,8 @@ function buildOptions(metadata, generatorOptions) {
|
|
|
117
89
|
prop.kind === "m:1" ||
|
|
118
90
|
prop.kind === "1:m" ||
|
|
119
91
|
prop.kind === "m:n" ||
|
|
120
|
-
prop.type === "EnumArrayType"
|
|
92
|
+
prop.type === "EnumArrayType" ||
|
|
93
|
+
prop.type === "uuid") &&
|
|
121
94
|
!dedicatedResolverArgProps.some((dedicatedResolverArgProp) => dedicatedResolverArgProp.name == prop.name));
|
|
122
95
|
const hasFilterArg = crudFilterProps.length > 0;
|
|
123
96
|
const crudSortProps = metadata.props.filter((prop) => (0, cms_api_1.hasCrudFieldFeature)(metadata.class, prop.name, "sort") &&
|
|
@@ -141,7 +114,7 @@ function buildOptions(metadata, generatorOptions) {
|
|
|
141
114
|
throw new Error("Scope prop has no targetMeta");
|
|
142
115
|
const hasPositionProp = metadata.props.some((prop) => prop.name == "position");
|
|
143
116
|
const positionGroupPropNames = hasPositionProp
|
|
144
|
-
? ((
|
|
117
|
+
? ((_b = (_a = generatorOptions.position) === null || _a === void 0 ? void 0 : _a.groupByFields) !== null && _b !== void 0 ? _b : [
|
|
145
118
|
...(scopeProp ? [scopeProp.name] : []), // if there is a scope prop it's effecting position-group, if not groupByFields should be used
|
|
146
119
|
])
|
|
147
120
|
: [];
|
|
@@ -163,9 +136,6 @@ function buildOptions(metadata, generatorOptions) {
|
|
|
163
136
|
hasSlugProp,
|
|
164
137
|
hasPositionProp,
|
|
165
138
|
positionGroupProps,
|
|
166
|
-
statusProp,
|
|
167
|
-
statusActiveItems,
|
|
168
|
-
hasStatusFilter,
|
|
169
139
|
scopeProp,
|
|
170
140
|
skipScopeCheck,
|
|
171
141
|
argsClassName,
|
|
@@ -205,7 +175,7 @@ function generateFilterDto({ generatorOptions, metadata }) {
|
|
|
205
175
|
}
|
|
206
176
|
}
|
|
207
177
|
});
|
|
208
|
-
const filterOut = `import { StringFilter, NumberFilter, BooleanFilter, DateFilter, DateTimeFilter, ManyToOneFilter, OneToManyFilter, ManyToManyFilter, createEnumFilter, createEnumsFilter } from "@comet/cms-api";
|
|
178
|
+
const filterOut = `import { StringFilter, NumberFilter, BooleanFilter, DateFilter, DateTimeFilter, ManyToOneFilter, OneToManyFilter, ManyToManyFilter, IdFilter, createEnumFilter, createEnumsFilter } from "@comet/cms-api";
|
|
209
179
|
import { Field, InputType } from "@nestjs/graphql";
|
|
210
180
|
import { Type } from "class-transformer";
|
|
211
181
|
import { IsNumber, IsOptional, IsString, ValidateNested } from "class-validator";
|
|
@@ -301,6 +271,14 @@ function generateFilterDto({ generatorOptions, metadata }) {
|
|
|
301
271
|
${prop.name}?: ManyToManyFilter;
|
|
302
272
|
`;
|
|
303
273
|
}
|
|
274
|
+
else if (prop.type == "uuid") {
|
|
275
|
+
return `@Field(() => IdFilter, { nullable: true })
|
|
276
|
+
@ValidateNested()
|
|
277
|
+
@IsOptional()
|
|
278
|
+
@Type(() => IdFilter)
|
|
279
|
+
${prop.name}?: IdFilter;
|
|
280
|
+
`;
|
|
281
|
+
}
|
|
304
282
|
else {
|
|
305
283
|
//unsupported type TODO support more
|
|
306
284
|
}
|
|
@@ -368,29 +346,12 @@ function generatePaginatedDto({ generatorOptions, metadata }) {
|
|
|
368
346
|
return paginatedOut;
|
|
369
347
|
}
|
|
370
348
|
function generateArgsDto({ generatorOptions, metadata }) {
|
|
371
|
-
var _a;
|
|
372
349
|
const { classNameSingular, fileNameSingular } = (0, build_name_variants_1.buildNameVariants)(metadata);
|
|
373
|
-
const { scopeProp, argsClassName, hasSearchArg, hasSortArg, hasFilterArg,
|
|
350
|
+
const { scopeProp, argsClassName, hasSearchArg, hasSortArg, hasFilterArg, dedicatedResolverArgProps } = buildOptions(metadata, generatorOptions);
|
|
374
351
|
const imports = [];
|
|
375
352
|
if (scopeProp && scopeProp.targetMeta) {
|
|
376
353
|
imports.push(generateEntityImport(scopeProp.targetMeta, `${generatorOptions.targetDirectory}/dto`));
|
|
377
354
|
}
|
|
378
|
-
let statusFilterClassName = undefined;
|
|
379
|
-
let statusFilterDefaultValue;
|
|
380
|
-
if (hasStatusFilter && statusProp) {
|
|
381
|
-
statusFilterClassName = (0, ts_morph_helper_1.findEnumName)(statusProp.name, metadata);
|
|
382
|
-
const importPath = (0, ts_morph_helper_1.findEnumImportPath)(statusFilterClassName, `${generatorOptions.targetDirectory}/dto`, metadata);
|
|
383
|
-
imports.push({
|
|
384
|
-
name: statusFilterClassName,
|
|
385
|
-
importPath,
|
|
386
|
-
});
|
|
387
|
-
if (statusActiveItems && statusActiveItems.length > 1) {
|
|
388
|
-
statusFilterDefaultValue = `[${statusActiveItems.map((i) => `${statusFilterClassName}.${i}`).join(", ")}]`;
|
|
389
|
-
}
|
|
390
|
-
else {
|
|
391
|
-
statusFilterDefaultValue = `[${(_a = (0, ts_morph_helper_1.morphTsProperty)(statusProp.name, metadata).getInitializer()) === null || _a === void 0 ? void 0 : _a.getText()}]`;
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
355
|
const argsOut = `import { ArgsType, Field, IntersectionType, registerEnumType, ID } from "@nestjs/graphql";
|
|
395
356
|
import { Type } from "class-transformer";
|
|
396
357
|
import { IsOptional, IsString, ValidateNested, IsEnum, IsUUID } from "class-validator";
|
|
@@ -427,14 +388,6 @@ function generateArgsDto({ generatorOptions, metadata }) {
|
|
|
427
388
|
})
|
|
428
389
|
.join("")}
|
|
429
390
|
|
|
430
|
-
${hasStatusFilter
|
|
431
|
-
? `
|
|
432
|
-
@Field(() => [${statusFilterClassName}], { defaultValue: ${statusFilterDefaultValue} })
|
|
433
|
-
@IsEnum(${statusFilterClassName}, { each: true })
|
|
434
|
-
status: ${statusFilterClassName}[];
|
|
435
|
-
`
|
|
436
|
-
: ""}
|
|
437
|
-
|
|
438
391
|
${hasSearchArg
|
|
439
392
|
? `
|
|
440
393
|
@Field({ nullable: true })
|
|
@@ -837,7 +790,7 @@ function generateRelationsFieldResolver({ generatorOptions, metadata }) {
|
|
|
837
790
|
}
|
|
838
791
|
function generateResolver({ generatorOptions, metadata }) {
|
|
839
792
|
const { classNameSingular, fileNameSingular, instanceNameSingular, classNamePlural, fileNamePlural, instanceNamePlural } = (0, build_name_variants_1.buildNameVariants)(metadata);
|
|
840
|
-
const { scopeProp, skipScopeCheck, argsClassName, argsFileName, hasSlugProp, hasSearchArg, hasSortArg, hasFilterArg, hasPositionProp, positionGroupProps,
|
|
793
|
+
const { scopeProp, skipScopeCheck, argsClassName, argsFileName, hasSlugProp, hasSearchArg, hasSortArg, hasFilterArg, hasPositionProp, positionGroupProps, dedicatedResolverArgProps, } = buildOptions(metadata, generatorOptions);
|
|
841
794
|
const relationManyToOneProps = metadata.props.filter((prop) => prop.kind === "m:1");
|
|
842
795
|
const relationOneToManyProps = metadata.props.filter((prop) => prop.kind === "1:m");
|
|
843
796
|
const relationManyToManyProps = metadata.props.filter((prop) => prop.kind === "m:n");
|
|
@@ -867,14 +820,6 @@ function generateResolver({ generatorOptions, metadata }) {
|
|
|
867
820
|
imports.push(generateEntityImport(scopeProp.targetMeta, generatorOptions.targetDirectory));
|
|
868
821
|
}
|
|
869
822
|
imports.push(...injectRepositories.map((meta) => generateEntityImport(meta, generatorOptions.targetDirectory)));
|
|
870
|
-
if (statusProp) {
|
|
871
|
-
const enumName = (0, ts_morph_helper_1.findEnumName)(statusProp.name, metadata);
|
|
872
|
-
const importPath = (0, ts_morph_helper_1.findEnumImportPath)(enumName, generatorOptions.targetDirectory, metadata);
|
|
873
|
-
imports.push({
|
|
874
|
-
name: enumName,
|
|
875
|
-
importPath,
|
|
876
|
-
});
|
|
877
|
-
}
|
|
878
823
|
function generateIdArg(name, metadata) {
|
|
879
824
|
if (constants_1.integerTypes.includes(metadata.properties[name].type)) {
|
|
880
825
|
return `@Args("${name}", { type: () => ID }, { transform: (value) => parseInt(value) }) ${name}: number`;
|
|
@@ -948,7 +893,7 @@ function generateResolver({ generatorOptions, metadata }) {
|
|
|
948
893
|
@Args() {${Object.entries(Object.assign(Object.assign({ scope: !!scopeProp }, dedicatedResolverArgProps.reduce((acc, dedicatedResolverArgProp) => {
|
|
949
894
|
acc[dedicatedResolverArgProp.name] = true;
|
|
950
895
|
return acc;
|
|
951
|
-
}, {})), {
|
|
896
|
+
}, {})), { search: !!hasSearchArg, filter: !!hasFilterArg, sort: !!hasSortArg, offset: true, limit: true }))
|
|
952
897
|
.filter(([key, use]) => use)
|
|
953
898
|
.map(([key]) => key)
|
|
954
899
|
.join(", ")}}: ${argsClassName}
|
|
@@ -957,7 +902,6 @@ function generateResolver({ generatorOptions, metadata }) {
|
|
|
957
902
|
const where${hasSearchArg || hasFilterArg
|
|
958
903
|
? ` = gqlArgsToMikroOrmQuery({ ${hasSearchArg ? `search, ` : ""}${hasFilterArg ? `filter, ` : ""} }, this.repository);`
|
|
959
904
|
: `: ObjectQuery<${metadata.className}> = {}`}
|
|
960
|
-
${hasStatusFilter ? `where.status = { $in: status };` : ""}
|
|
961
905
|
${scopeProp ? `where.scope = scope;` : ""}
|
|
962
906
|
${dedicatedResolverArgProps
|
|
963
907
|
.map((dedicatedResolverArgProp) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@comet/api-generator",
|
|
3
|
-
"version": "8.0.0-beta.
|
|
3
|
+
"version": "8.0.0-beta.4",
|
|
4
4
|
"repository": {
|
|
5
5
|
"directory": "packages/api/api-generator",
|
|
6
6
|
"type": "git",
|
|
@@ -21,15 +21,15 @@
|
|
|
21
21
|
"pluralize": "^8.0.0",
|
|
22
22
|
"ts-morph": "^25.0.1",
|
|
23
23
|
"ts-node": "^10.9.2",
|
|
24
|
-
"@comet/cms-api": "8.0.0-beta.
|
|
24
|
+
"@comet/cms-api": "8.0.0-beta.4"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@mikro-orm/cli": "^6.4.10",
|
|
28
28
|
"@mikro-orm/core": "^6.4.10",
|
|
29
29
|
"@mikro-orm/postgresql": "^6.4.10",
|
|
30
|
-
"@nestjs/graphql": "^13.0
|
|
30
|
+
"@nestjs/graphql": "^13.1.0",
|
|
31
31
|
"@types/jest": "^29.5.14",
|
|
32
|
-
"@types/node": "^22.
|
|
32
|
+
"@types/node": "^22.14.0",
|
|
33
33
|
"@types/pluralize": "^0.0.33",
|
|
34
34
|
"class-validator": "^0.14.1",
|
|
35
35
|
"eslint": "^9.22.0",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"ts-jest": "^29.2.6",
|
|
42
42
|
"typescript": "^5.7.3",
|
|
43
43
|
"uuid": "^11.1.0",
|
|
44
|
-
"@comet/eslint-config": "8.0.0-beta.
|
|
44
|
+
"@comet/eslint-config": "8.0.0-beta.4"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
47
|
"@mikro-orm/cli": "^6.0.0",
|
|
@@ -64,6 +64,6 @@
|
|
|
64
64
|
"lint:prettier": "npx prettier --check './**/*.{js,json,md,yml,yaml}'",
|
|
65
65
|
"lint:tsc": "tsc",
|
|
66
66
|
"test": "NODE_OPTIONS=--experimental-vm-modules npx jest",
|
|
67
|
-
"test:watch": "jest --watch"
|
|
67
|
+
"test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch"
|
|
68
68
|
}
|
|
69
69
|
}
|