Skip to content

Commit 7960cb8

Browse files
committed
Change types to correctly convey a necessary condition
1 parent 6201bfc commit 7960cb8

File tree

12 files changed

+41
-35
lines changed

12 files changed

+41
-35
lines changed

src/common/date-filter.input.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Field, InputType } from '@nestjs/graphql';
2-
import { DateTime } from 'luxon';
2+
import { type DateTime } from 'luxon';
33
import { DateField, DateTimeField } from './luxon.graphql';
4-
import { CalendarDate } from './temporal';
4+
import { type CalendarDate } from './temporal';
55

66
@InputType({
77
description: 'A filter range designed for date fields',
@@ -11,25 +11,25 @@ export abstract class DateFilter {
1111
description: 'After this day',
1212
nullable: true,
1313
})
14-
after?: CalendarDate;
14+
after?: CalendarDate | null;
1515

1616
@DateField({
1717
description: 'After or equal to this day',
1818
nullable: true,
1919
})
20-
afterInclusive?: CalendarDate;
20+
afterInclusive?: CalendarDate | null;
2121

2222
@DateField({
2323
description: 'Before this day',
2424
nullable: true,
2525
})
26-
before?: CalendarDate;
26+
before?: CalendarDate | null;
2727

2828
@DateField({
2929
description: 'Before or equal to this day',
3030
nullable: true,
3131
})
32-
beforeInclusive?: CalendarDate;
32+
beforeInclusive?: CalendarDate | null;
3333

3434
@Field({ description: 'Whether the field is null or not', nullable: true })
3535
isNull?: boolean;
@@ -43,25 +43,25 @@ export abstract class DateTimeFilter {
4343
description: 'After this time',
4444
nullable: true,
4545
})
46-
after?: DateTime;
46+
after?: DateTime | null;
4747

4848
@DateTimeField({
4949
description: 'After or equal to this time',
5050
nullable: true,
5151
})
52-
afterInclusive?: DateTime;
52+
afterInclusive?: DateTime | null;
5353

5454
@DateTimeField({
5555
description: 'Before this time',
5656
nullable: true,
5757
})
58-
before?: DateTime;
58+
before?: DateTime | null;
5959

6060
@DateTimeField({
6161
description: 'Before or equal to this time',
6262
nullable: true,
6363
})
64-
beforeInclusive?: DateTime;
64+
beforeInclusive?: DateTime | null;
6565

6666
@Field({ description: 'Whether the field is null or not', nullable: true })
6767
isNull?: boolean;

src/common/exceptions/service-unavailable.exception.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export class TransientException extends ServerException {}
55

66
export class ServiceUnavailableException extends TransientException {
77
readonly status = HttpStatus.SERVICE_UNAVAILABLE;
8-
constructor(message: string, previous?: Error) {
8+
constructor(message?: string, previous?: Error) {
99
super(message ?? 'Service Unavailable', previous);
1010
}
1111
}

src/common/name-field.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,13 @@ export const NameField = (options: NameFieldParams = {}) =>
5151
*/
5252
const InferredTypeOrStringField =
5353
(options: FieldOptions): PropertyDecorator | MethodDecorator =>
54-
(prototype, property, descriptor) => {
54+
(prototype, property, descriptorRaw) => {
5555
const propertyKey = property as string;
5656
const applyMetadataFn = () => {
57+
// fix linter false positive thinking it always exists, property decorators don't have it
58+
const descriptor = descriptorRaw as
59+
| TypedPropertyDescriptor<unknown>
60+
| undefined;
5761
const isResolver = !!descriptor;
5862
const isResolverMethod = !!descriptor?.value;
5963
const resolveType = (typeFn?: ReturnTypeFunc) =>

src/common/variant.dto.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ export const VariantInputField = <
9090
? resource.Variants.find((v) => v.key === value)
9191
: value;
9292
const defaultVariant = many
93-
? (defaultValue as any[])?.map(resolveVariant)
93+
? (defaultValue as any[] | undefined)?.map(resolveVariant)
9494
: resolveVariant(defaultValue as VariantOf<Res>);
9595

9696
return applyDecorators(

src/components/authorization/policy/executor/condition-optimizer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export class ConditionOptimizer implements OnModuleInit {
3434
// Optimize leaves first, walking up to root.
3535
// This means smaller expressions are optimized before tackling larger ones.
3636
if (condition instanceof AggregateConditions) {
37-
let changed = false;
37+
let changed = Boolean(false);
3838
const newSubs = condition.conditions.map((sub) => {
3939
const next = this.doOptimize(sub);
4040
if (next !== sub) {

src/components/authorization/policy/executor/policy-executor.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ export class PolicyExecutor {
222222
return c;
223223
}
224224

225-
let changed = false;
225+
let changed = Boolean(false);
226226
const children = c.conditions.map((sub) => {
227227
const next = walkAndReform(sub);
228228
if (next !== sub) {

src/components/notifications/dto/mark-notification-read.args.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ export abstract class MarkNotificationReadArgs {
77
readonly id: ID<'Notification'>;
88

99
@Field(() => Boolean, { nullable: true })
10-
readonly unread = false;
10+
readonly unread: boolean = false;
1111
}

src/components/product/product.resolver.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,9 @@ export class ProductResolver {
149149
}
150150
const produces = product.produces.value;
151151
// All of our producibles have a name field, so instead of enumerating
152-
// through them just fake the type and grab it directly.
152+
// through them, just fake the type and grab it directly.
153153
// This also assumes the user can read the name, which is completely unvalidated.
154-
return (produces as unknown as { name: string }).name ?? null;
154+
return (produces as unknown as { name?: string }).name ?? null;
155155
}
156156

157157
@ResolveField(() => String, {

src/components/product/product.service.ts

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -128,10 +128,9 @@ export class ProductService {
128128
);
129129
}
130130

131-
const type =
132-
'title' in input && input.title !== undefined
133-
? ProducibleType.OtherProduct
134-
: producibleType ?? ProducibleType.DirectScriptureProduct;
131+
const type = otherInput
132+
? ProducibleType.OtherProduct
133+
: producibleType ?? ProducibleType.DirectScriptureProduct;
135134
const availableSteps = getAvailableSteps({
136135
type,
137136
methodology: input.methodology,
@@ -144,16 +143,15 @@ export class ProductService {
144143
Number: input.progressTarget ?? 1,
145144
});
146145

147-
const id =
148-
'title' in input && input.title !== undefined
149-
? await this.repo.createOther({ ...input, progressTarget, steps })
150-
: await this.repo.create({
151-
...input,
152-
progressTarget,
153-
steps,
154-
totalVerses,
155-
totalVerseEquivalents,
156-
});
146+
const id = otherInput
147+
? await this.repo.createOther({ ...otherInput, progressTarget, steps })
148+
: await this.repo.create({
149+
...input,
150+
progressTarget,
151+
steps,
152+
totalVerses,
153+
totalVerseEquivalents,
154+
});
157155

158156
this.logger.debug(`product created`, { id });
159157
const created = await this.readOne(id).catch((e) => {

src/core/authentication/authentication.repository.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ export class AuthenticationRepository {
209209
.return<{
210210
userId: ID | null;
211211
roles: readonly Role[];
212-
impersonateeRoles: readonly Role[] | null;
212+
impersonateeRoles?: readonly Role[] | null;
213213
}>([
214214
'user.id as userId',
215215
'roles',

0 commit comments

Comments
 (0)