prisma-nestjs-graphql 22.0.1 → 23.0.1
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/README.md +12 -6
- package/package.json +1 -1
- package/prisma-nestjs-graphql.d.ts +1 -0
- package/prisma-nestjs-graphql.mjs +64 -36
package/README.md
CHANGED
|
@@ -86,13 +86,13 @@ Default: `''` (empty string)
|
|
|
86
86
|
|
|
87
87
|
Combine nested/nullable scalar filters to single
|
|
88
88
|
Type: `boolean`
|
|
89
|
-
Default: `
|
|
89
|
+
Default: `true`
|
|
90
90
|
|
|
91
91
|
#### `noAtomicOperations`
|
|
92
92
|
|
|
93
93
|
Remove input types for atomic operations
|
|
94
94
|
Type: `boolean`
|
|
95
|
-
Default: `
|
|
95
|
+
Default: `true`
|
|
96
96
|
|
|
97
97
|
#### `reExport`
|
|
98
98
|
|
|
@@ -152,6 +152,13 @@ Disable usage of graphql `ID` type and use `Int/Float` for fields marked as `@id
|
|
|
152
152
|
Type: `boolean`
|
|
153
153
|
Default: `false`
|
|
154
154
|
|
|
155
|
+
#### `typeListNullable`
|
|
156
|
+
|
|
157
|
+
Adds `nullable: true` for relation list properties out output models,
|
|
158
|
+
it makes graphql field looks like `[Type!]`, default `[Type!]!`
|
|
159
|
+
Type: `boolean`
|
|
160
|
+
Default: `false`
|
|
161
|
+
|
|
155
162
|
#### `requireSingleFieldsInWhereUniqueInput`
|
|
156
163
|
|
|
157
164
|
When a model `*WhereUniqueInput` class has only a single field, mark that field as **required** (TypeScript) and **not nullable** (GraphQL).
|
|
@@ -788,12 +795,11 @@ import { generate } from 'prisma-nestjs-graphql';
|
|
|
788
795
|
|
|
789
796
|
## TODO
|
|
790
797
|
|
|
791
|
-
-
|
|
792
|
-
-
|
|
793
|
-
-
|
|
798
|
+
- noAtomicOperations = 1, IntFieldUpdateOperationsInput exists
|
|
799
|
+
- CommentUncheckedUpdateManyWithoutAuthorNestedInput and CommentUpdateManyWithoutAuthorNestedInput are same
|
|
800
|
+
- Add logic to detect view models and skip generation of mutation inputs/args for them https://github.com/unlight/prisma-nestjs-graphql/issues/248
|
|
794
801
|
- dummy-createfriends.input.ts -> `create-friends`
|
|
795
802
|
- check 'TODO FIXME'
|
|
796
|
-
- 22.12 node require esm (update all deps to latest)
|
|
797
803
|
|
|
798
804
|
## License
|
|
799
805
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prisma-nestjs-graphql",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "23.0.1",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Generate object types, inputs, args, etc. from prisma schema file for usage with @nestjs/graphql module",
|
|
7
7
|
"bin": "bin.mjs",
|
|
@@ -47,6 +47,7 @@ declare function createConfig(data: Record<string, unknown>): {
|
|
|
47
47
|
reExport: ReExportType;
|
|
48
48
|
requireSingleFieldsInWhereUniqueInput: boolean;
|
|
49
49
|
tsConfigFilePath: string | undefined;
|
|
50
|
+
typeListNullable: boolean;
|
|
50
51
|
unsafeCompatibleWhereUniqueInput: boolean;
|
|
51
52
|
useInputType: ConfigInputItem[];
|
|
52
53
|
};
|
|
@@ -138,7 +138,7 @@ function beforeInputType$2(args) {
|
|
|
138
138
|
inputType.name = replaceBogus(inputType.name);
|
|
139
139
|
}
|
|
140
140
|
}
|
|
141
|
-
function beforeGenerateField(field) {
|
|
141
|
+
function beforeGenerateField(field, args) {
|
|
142
142
|
for (const fieldInput of field.inputTypes) {
|
|
143
143
|
if (fieldInput.location !== 'inputObjectTypes') {
|
|
144
144
|
continue;
|
|
@@ -175,13 +175,7 @@ function postBegin(args) {
|
|
|
175
175
|
} = args;
|
|
176
176
|
const inputTypes = schema.inputObjectTypes.prisma ?? [];
|
|
177
177
|
const enumTypes = schema.enumTypes.model || [];
|
|
178
|
-
const types = ['Bool', 'Int', 'String', 'DateTime', 'Decimal', 'Float', 'Json', 'Bytes', 'BigInt'];
|
|
179
|
-
for (const enumType of enumTypes) {
|
|
180
|
-
const {
|
|
181
|
-
name
|
|
182
|
-
} = enumType;
|
|
183
|
-
types.push(`Enum${name}`);
|
|
184
|
-
}
|
|
178
|
+
const types = ['Bool', 'Int', 'String', 'DateTime', 'Decimal', 'Float', 'Json', 'Bytes', 'BigInt', ...enumTypes.map(x => `Enum${x.name}`)];
|
|
185
179
|
const inputTypeByName = keyBy(inputTypes, inputType => inputType.name);
|
|
186
180
|
const replaceBogusFilters = (filterName, filterNameCandidates) => {
|
|
187
181
|
for (const filterNameCandidate of filterNameCandidates) {
|
|
@@ -199,9 +193,9 @@ function postBegin(args) {
|
|
|
199
193
|
};
|
|
200
194
|
for (const type of types) {
|
|
201
195
|
// Scalar filters
|
|
202
|
-
replaceBogusFilters(`${type}Filter`, [`${type}NullableFilter`, `Nested${type}NullableFilter`]);
|
|
203
|
-
replaceBogusFilters(`${type}WithAggregatesFilter`, [`${type}NullableWithAggregatesFilter`, `Nested${type}NullableWithAggregatesFilter`]);
|
|
204
|
-
replaceBogusFilters(`${type}ListFilter`, [`${type}NullableListFilter`, `Nested${type}NullableListFilter`]);
|
|
196
|
+
replaceBogusFilters(`${type}Filter`, [`${type}NullableFilter`, `Nested${type}NullableFilter`, `Nested${type}Filter`]);
|
|
197
|
+
replaceBogusFilters(`${type}WithAggregatesFilter`, [`${type}NullableWithAggregatesFilter`, `Nested${type}NullableWithAggregatesFilter`, `Nested${type}WithAggregatesFilter`]);
|
|
198
|
+
replaceBogusFilters(`${type}ListFilter`, [`${type}NullableListFilter`, `Nested${type}NullableListFilter`, `Nested${type}ListFilter`]);
|
|
205
199
|
}
|
|
206
200
|
for (const modelName of modelNames) {
|
|
207
201
|
replaceBogusFilters(`${modelName}RelationFilter`, [`${modelName}NullableRelationFilter`]);
|
|
@@ -471,7 +465,7 @@ function combineToSingle(args) {
|
|
|
471
465
|
});
|
|
472
466
|
}
|
|
473
467
|
|
|
474
|
-
const extensions = new Set(['.js', '.mjs', '.ts', '.mts']);
|
|
468
|
+
const extensions = new Set(['.js', '.mjs', '.ts', '.mts', '.cts', '.cjs']);
|
|
475
469
|
function adjustModuleSpecifier(moduleSpecifier, importExtension) {
|
|
476
470
|
if (moduleSpecifier.startsWith('.')) {
|
|
477
471
|
let specifierWithoutExtension = moduleSpecifier;
|
|
@@ -840,11 +834,6 @@ function inputType(args) {
|
|
|
840
834
|
});
|
|
841
835
|
const useInputType = config.useInputType.find(x => inputType.name.includes(x.typeName));
|
|
842
836
|
const isWhereUnique = isWhereUniqueInputType(inputType.name);
|
|
843
|
-
|
|
844
|
-
// if (inputType.name.includes('DecimalNullableFilter')) {
|
|
845
|
-
// console.log({ importDeclarations, location, property, propertyType });
|
|
846
|
-
// }
|
|
847
|
-
|
|
848
837
|
for (const field of inputType.fields) {
|
|
849
838
|
field.inputTypes = field.inputTypes.filter(t => !removeTypes.has(String(t.type)));
|
|
850
839
|
eventEmitter.emitSync(BeforeGenerateField, field, args);
|
|
@@ -1467,16 +1456,13 @@ function modelOutputType(outputType, args) {
|
|
|
1467
1456
|
name: 'HideField'
|
|
1468
1457
|
});
|
|
1469
1458
|
} else {
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
})],
|
|
1478
|
-
name: 'Field'
|
|
1479
|
-
});
|
|
1459
|
+
property.decorators.push(generateFieldDecorator({
|
|
1460
|
+
config,
|
|
1461
|
+
field,
|
|
1462
|
+
graphqlType,
|
|
1463
|
+
modelField,
|
|
1464
|
+
settings
|
|
1465
|
+
}));
|
|
1480
1466
|
for (const setting of settings || []) {
|
|
1481
1467
|
if (shouldBeDecorated(setting) && (setting.match?.(field.name) ?? true)) {
|
|
1482
1468
|
property.decorators.push({
|
|
@@ -1487,15 +1473,15 @@ function modelOutputType(outputType, args) {
|
|
|
1487
1473
|
importDeclarations.createFrom(setting);
|
|
1488
1474
|
}
|
|
1489
1475
|
}
|
|
1490
|
-
for (const
|
|
1491
|
-
if (
|
|
1476
|
+
for (const d of config.decorate) {
|
|
1477
|
+
if (d.isMatchField(field.name) && d.isMatchType(outputTypeName)) {
|
|
1492
1478
|
property.decorators.push({
|
|
1493
|
-
arguments:
|
|
1479
|
+
arguments: d.arguments?.map(x => pupa(x, {
|
|
1494
1480
|
propertyType
|
|
1495
1481
|
})),
|
|
1496
|
-
name:
|
|
1482
|
+
name: d.name
|
|
1497
1483
|
});
|
|
1498
|
-
importDeclarations.createFrom(
|
|
1484
|
+
importDeclarations.createFrom(d);
|
|
1499
1485
|
}
|
|
1500
1486
|
}
|
|
1501
1487
|
}
|
|
@@ -1530,6 +1516,47 @@ function modelOutputType(outputType, args) {
|
|
|
1530
1516
|
});
|
|
1531
1517
|
}
|
|
1532
1518
|
}
|
|
1519
|
+
|
|
1520
|
+
/**
|
|
1521
|
+
* Get structure for `@Field()` decorator
|
|
1522
|
+
*/
|
|
1523
|
+
function generateFieldDecorator(args) {
|
|
1524
|
+
const {
|
|
1525
|
+
config,
|
|
1526
|
+
field,
|
|
1527
|
+
graphqlType,
|
|
1528
|
+
modelField,
|
|
1529
|
+
settings
|
|
1530
|
+
} = args;
|
|
1531
|
+
const {
|
|
1532
|
+
isList,
|
|
1533
|
+
namespace
|
|
1534
|
+
} = field.outputType;
|
|
1535
|
+
const {
|
|
1536
|
+
typeListNullable
|
|
1537
|
+
} = config;
|
|
1538
|
+
const {
|
|
1539
|
+
isNullable
|
|
1540
|
+
} = field;
|
|
1541
|
+
const firstArgumentType = isList ? `() => [${graphqlType}]` : `() => ${graphqlType}`;
|
|
1542
|
+
const getNullable = () => {
|
|
1543
|
+
if (!typeListNullable && namespace === 'model' && isList && isNullable) {
|
|
1544
|
+
return false;
|
|
1545
|
+
}
|
|
1546
|
+
return Boolean(isNullable);
|
|
1547
|
+
};
|
|
1548
|
+
const defaultValue = ['number', 'string', 'boolean'].includes(typeof modelField?.default) ? modelField?.default : undefined;
|
|
1549
|
+
const secondArgumentOptions = JSON5.stringify({
|
|
1550
|
+
...settings?.fieldArguments(),
|
|
1551
|
+
defaultValue,
|
|
1552
|
+
description: modelField?.documentation,
|
|
1553
|
+
nullable: getNullable()
|
|
1554
|
+
});
|
|
1555
|
+
return {
|
|
1556
|
+
arguments: [firstArgumentType, secondArgumentOptions],
|
|
1557
|
+
name: 'Field'
|
|
1558
|
+
};
|
|
1559
|
+
}
|
|
1533
1560
|
function shouldBeDecorated(setting) {
|
|
1534
1561
|
return setting.kind === 'Decorator' && (setting.output || setting.model) && !(setting.output && setting.model);
|
|
1535
1562
|
}
|
|
@@ -1969,7 +1996,7 @@ function createConfig(data) {
|
|
|
1969
1996
|
delimiter: '_'
|
|
1970
1997
|
}));
|
|
1971
1998
|
const $warnings = [];
|
|
1972
|
-
const configOutputFilePattern =
|
|
1999
|
+
const configOutputFilePattern = typeof config.outputFilePattern === 'string' && config.outputFilePattern || `{model}/{name}.{type}.ts`;
|
|
1973
2000
|
const outputFilePattern = configOutputFilePattern.replaceAll('\\', '/').split('/').map(path => filenamify(path, {
|
|
1974
2001
|
replacement: ''
|
|
1975
2002
|
})).filter(Boolean).join('/');
|
|
@@ -2025,7 +2052,7 @@ function createConfig(data) {
|
|
|
2025
2052
|
}
|
|
2026
2053
|
return {
|
|
2027
2054
|
$warnings,
|
|
2028
|
-
combineScalarFilters: toBoolean(config.combineScalarFilters),
|
|
2055
|
+
combineScalarFilters: toBoolean(config.combineScalarFilters ?? 'true'),
|
|
2029
2056
|
customImport,
|
|
2030
2057
|
decorate,
|
|
2031
2058
|
emitBlocks: createEmitBlocks(config.emitBlocks),
|
|
@@ -2033,8 +2060,8 @@ function createConfig(data) {
|
|
|
2033
2060
|
emitSingle: toBoolean(config.emitSingle),
|
|
2034
2061
|
fields,
|
|
2035
2062
|
graphqlScalars: config.graphqlScalars || {},
|
|
2036
|
-
importExtension:
|
|
2037
|
-
noAtomicOperations: toBoolean(config.noAtomicOperations),
|
|
2063
|
+
importExtension: typeof config.importExtension === 'string' && config.importExtension || '',
|
|
2064
|
+
noAtomicOperations: toBoolean(config.noAtomicOperations ?? 'true'),
|
|
2038
2065
|
noTypeId: toBoolean(config.noTypeId),
|
|
2039
2066
|
omitModelsCount: toBoolean(config.omitModelsCount),
|
|
2040
2067
|
outputFilePattern,
|
|
@@ -2043,6 +2070,7 @@ function createConfig(data) {
|
|
|
2043
2070
|
reExport: ReExport[String(config.reExport)] || ReExport.None,
|
|
2044
2071
|
requireSingleFieldsInWhereUniqueInput: toBoolean(config.requireSingleFieldsInWhereUniqueInput),
|
|
2045
2072
|
tsConfigFilePath: createTsConfigFilePathValue(config.tsConfigFilePath),
|
|
2073
|
+
typeListNullable: toBoolean(config.typeListNullable ?? 'false'),
|
|
2046
2074
|
unsafeCompatibleWhereUniqueInput: toBoolean(config.unsafeCompatibleWhereUniqueInput),
|
|
2047
2075
|
useInputType: createUseInputType(config.useInputType)
|
|
2048
2076
|
};
|