Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeScript: 4. Finalize GraphQL resolvers [MEGA PR] #229

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
603a3bb
IN PROGRESS
alukach Jun 14, 2024
72231fa
Merge branch 'main' into feature/typescript/models-utils
alukach Jun 14, 2024
f9797eb
Convert Project model
alukach Jun 14, 2024
929b31e
Attempt to fix query warning
alukach Jun 17, 2024
b802430
Simplify types
alukach Jun 17, 2024
6d6c2a9
Merge branch 'main' into feature/typescript/models-project
alukach Jun 17, 2024
bb8c9c8
Further simplify types
alukach Jun 17, 2024
cf4e5ab
Use HydratedSingleSubdocument
alukach Jun 17, 2024
40cc2fd
Convert tasks model
alukach Jun 18, 2024
fb85ae8
Start of conversion
alukach Jun 18, 2024
f7f1c3a
Handle error string
alukach Jun 18, 2024
dade099
Mark all values in arrays as required
alukach Jun 14, 2024
999c02f
Complete first pass
alukach Jun 18, 2024
91c56d0
Continue buildout
alukach Jun 20, 2024
7307e5b
Fix type error
alukach Jun 20, 2024
43a9440
Merge branch 'main' into feature/typescript/models-utils
alukach Jun 20, 2024
915ec33
Finalize
alukach Jun 20, 2024
f364fec
Merge branch 'feature/typescript/models-utils' into feature/typescrip…
alukach Jun 20, 2024
c743243
Adapt to utils.ts - IN PROGRESS
alukach Jun 20, 2024
22e3a5a
IN PROGRESS
alukach Jun 24, 2024
8069446
Type outputs
alukach Jun 24, 2024
a0c5fd8
Bulk edit queries on queryById methods
alukach Jun 24, 2024
ee844af
Merge branch 'main' into feature/typescript/models-task
alukach Jun 24, 2024
23ee3e4
Merge branch 'main' into feature/typescript/models-image
alukach Jun 24, 2024
51ea59e
Fix import
alukach Jun 24, 2024
76df33d
Finalize
alukach Jun 24, 2024
72ab57e
Merge branch 'main' into feature/typescript/models-utils
alukach Jun 24, 2024
1febba6
Simplify
alukach Jun 24, 2024
775b758
Fix import
alukach Jun 24, 2024
779d916
Mark curr_project as required
alukach Jun 25, 2024
1306fa4
Merge branch 'main' into feature/typescript/graphql-resolvers-fix-que…
alukach Jun 25, 2024
69fed9e
Merge branch 'feature/typescript/graphql-resolvers-fix-query-mlmodels…
alukach Jun 25, 2024
e870e32
Merge branch 'feature/typescript/models-project' into feature/typescr…
alukach Jun 25, 2024
4f19e3d
Merge branch 'feature/typescript/models-image' into feature/typescrip…
alukach Jun 25, 2024
017c6e4
Merge branch 'feature/typescript/models-utils' into feature/typescrip…
alukach Jun 25, 2024
49f4e3e
Merge branch 'feature/typescript/models-task' into feature/typescript…
alukach Jun 25, 2024
28c5161
FIX: correct utils import
alukach Jun 25, 2024
d803dce
FIX: Cleanup methods
alukach Jun 25, 2024
8c64e0f
FIX: Add missing props to aggregation output
alukach Jun 26, 2024
88a73ad
FIX: Include count with query resolver imageErrors response
alukach Jun 26, 2024
aacb9de
FIX: Adapt to undefined query args
alukach Jun 26, 2024
bc5de8e
FIX: Pass in input.filters to ImageError.countImageErrors()
alukach Jun 26, 2024
544b401
FIX: Comply with GQL types
alukach Jun 26, 2024
9c51626
GraphQL: Mark all array values as non-null
alukach Jun 26, 2024
b79e082
Merge branch 'fix/graphql/bulk-change-array-bytes' into feature/types…
alukach Jun 26, 2024
3ef23c7
FIX: Correct user type
alukach Jun 26, 2024
8e2afe6
FIX: Explicitly describe _id for subdocument
alukach Jun 26, 2024
3c0fdfb
FIX: Mark userId as optional as per DB schema
alukach Jun 26, 2024
2a0c760
FIX: Add type as per models response
alukach Jun 26, 2024
11b2018
FIX: Manually define type for AutomationRuleSchema to avoid TS issues
alukach Jun 27, 2024
e1131c6
FIX: Align CreateImageErrorInput with method
alukach Jun 27, 2024
da15599
FIX: Update view graphql type to match DB schema
alukach Jun 27, 2024
4f84be3
Simplify
alukach Jun 27, 2024
2e1d7c8
FIX: Work around error property on response objects
alukach Jun 27, 2024
b0ec544
FIX: Make sortDeps work with DocumentArray
alukach Jun 27, 2024
21c42c6
Amend sortDeps
alukach Jun 27, 2024
eb3bbe4
FIX: Forcibly coerce to automationRules
alukach Jun 27, 2024
93ce02c
FIX: Add _id property on subdocuments
alukach Jun 27, 2024
9a5cf75
Loosen Config requirements
alukach Jun 27, 2024
15bdc1d
FIX: Loosen ID type
alukach Jun 27, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 44 additions & 42 deletions src/@types/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ export type Scalars = {

export type AutomationAction = {
__typename?: 'AutomationAction';
alertRecipients?: Maybe<Array<Maybe<Scalars['String']['output']>>>;
alertRecipients?: Maybe<Array<Scalars['String']['output']>>;
categoryConfig?: Maybe<Scalars['JSONObject']['output']>;
confThreshold?: Maybe<Scalars['Float']['output']>;
mlModel?: Maybe<Scalars['String']['output']>;
type: Scalars['String']['output'];
};

export type AutomationActionInput = {
alertRecipients?: InputMaybe<Array<InputMaybe<Scalars['String']['input']>>>;
alertRecipients?: InputMaybe<Array<Scalars['String']['input']>>;
categoryConfig?: InputMaybe<Scalars['JSONObject']['input']>;
confThreshold?: InputMaybe<Scalars['Float']['input']>;
mlModel?: InputMaybe<Scalars['String']['input']>;
Expand Down Expand Up @@ -66,7 +66,7 @@ export type Batch = {
_id: Scalars['String']['output'];
created?: Maybe<Scalars['Date']['output']>;
dead?: Maybe<Scalars['Int']['output']>;
errors?: Maybe<Array<Maybe<BatchError>>>;
errors?: Maybe<Array<BatchError>>;
imageErrors?: Maybe<Scalars['Int']['output']>;
ingestionComplete?: Maybe<Scalars['Date']['output']>;
originalFile?: Maybe<Scalars['String']['output']>;
Expand Down Expand Up @@ -148,9 +148,9 @@ export type CreateImageCommentInput = {
};

export type CreateImageErrorInput = {
batch?: InputMaybe<Scalars['String']['input']>;
batch: Scalars['String']['input'];
error: Scalars['String']['input'];
image?: InputMaybe<Scalars['String']['input']>;
image: Scalars['String']['input'];
};

export type CreateImageInput = {
Expand All @@ -165,7 +165,7 @@ export type CreateImagePayload = {
export type CreateInternalLabelInput = {
bbox: Array<Scalars['Float']['input']>;
conf?: InputMaybe<Scalars['Float']['input']>;
imageId?: InputMaybe<Scalars['ID']['input']>;
imageId: Scalars['ID']['input'];
labelId: Scalars['String']['input'];
mlModel: Scalars['String']['input'];
mlModelVersion: Scalars['String']['input'];
Expand All @@ -179,9 +179,10 @@ export type CreateLabelInput = {
_id?: InputMaybe<Scalars['ID']['input']>;
bbox: Array<Scalars['Float']['input']>;
conf?: InputMaybe<Scalars['Float']['input']>;
imageId?: InputMaybe<Scalars['ID']['input']>;
imageId: Scalars['ID']['input'];
labelId: Scalars['String']['input'];
labeledDate?: InputMaybe<Scalars['Date']['input']>;
mlModel?: InputMaybe<Scalars['String']['input']>;
objectId?: InputMaybe<Scalars['ID']['input']>;
userId?: InputMaybe<Scalars['ID']['input']>;
validation?: InputMaybe<ValidationInput>;
Expand Down Expand Up @@ -223,7 +224,7 @@ export type CreateUploadPayload = {
batch: Scalars['String']['output'];
multipartUploadId?: Maybe<Scalars['String']['output']>;
url?: Maybe<Scalars['String']['output']>;
urls?: Maybe<Array<Maybe<Scalars['String']['output']>>>;
urls?: Maybe<Array<Scalars['String']['output']>>;
user: Scalars['String']['output'];
};

Expand Down Expand Up @@ -346,7 +347,7 @@ export type ExportStatusInput = {
export type ExportStatusPayload = {
__typename?: 'ExportStatusPayload';
count?: Maybe<Scalars['Int']['output']>;
error?: Maybe<Array<Maybe<ExportError>>>;
error?: Maybe<Array<ExportError>>;
meta?: Maybe<Scalars['JSONObject']['output']>;
status: Scalars['String']['output'];
url?: Maybe<Scalars['String']['output']>;
Expand All @@ -356,12 +357,12 @@ export type Filters = {
__typename?: 'Filters';
addedEnd?: Maybe<Scalars['Date']['output']>;
addedStart?: Maybe<Scalars['Date']['output']>;
cameras?: Maybe<Array<Maybe<Scalars['String']['output']>>>;
cameras?: Maybe<Array<Scalars['String']['output']>>;
createdEnd?: Maybe<Scalars['Date']['output']>;
createdStart?: Maybe<Scalars['Date']['output']>;
custom?: Maybe<Scalars['String']['output']>;
deployments?: Maybe<Array<Maybe<Scalars['String']['output']>>>;
labels?: Maybe<Array<Maybe<Scalars['String']['output']>>>;
deployments?: Maybe<Array<Scalars['String']['output']>>;
labels?: Maybe<Array<Scalars['String']['output']>>;
notReviewed?: Maybe<Scalars['Boolean']['output']>;
reviewed?: Maybe<Scalars['Boolean']['output']>;
};
Expand All @@ -374,7 +375,7 @@ export type FiltersInput = {
createdStart?: InputMaybe<Scalars['Date']['input']>;
custom?: InputMaybe<Scalars['String']['input']>;
deployments?: InputMaybe<Array<Scalars['String']['input']>>;
labels?: InputMaybe<Array<InputMaybe<Scalars['String']['input']>>>;
labels?: InputMaybe<Array<Scalars['String']['input']>>;
reviewed?: InputMaybe<Scalars['Boolean']['input']>;
};

Expand All @@ -396,11 +397,11 @@ export type Image = {
batchId?: Maybe<Scalars['String']['output']>;
bucket: Scalars['String']['output'];
cameraId: Scalars['String']['output'];
comments?: Maybe<Array<Maybe<ImageComment>>>;
comments?: Maybe<Array<ImageComment>>;
dateAdded: Scalars['Date']['output'];
dateTimeOriginal: Scalars['Date']['output'];
deploymentId: Scalars['ID']['output'];
errors?: Maybe<Array<Maybe<ImageError>>>;
errors?: Maybe<Array<ImageError>>;
fileTypeExtension: Scalars['String']['output'];
imageBytes?: Maybe<Scalars['Int']['output']>;
imageHeight?: Maybe<Scalars['Int']['output']>;
Expand All @@ -409,7 +410,7 @@ export type Image = {
make: Scalars['String']['output'];
mimeType?: Maybe<Scalars['String']['output']>;
model?: Maybe<Scalars['String']['output']>;
objects?: Maybe<Array<Maybe<Object>>>;
objects?: Maybe<Array<Object>>;
originalFileName?: Maybe<Scalars['String']['output']>;
path?: Maybe<Scalars['String']['output']>;
projectId: Scalars['String']['output'];
Expand All @@ -423,7 +424,7 @@ export type ImageAttempt = {
_id: Scalars['ID']['output'];
batch?: Maybe<Scalars['String']['output']>;
created: Scalars['Date']['output'];
errors?: Maybe<Array<Maybe<ImageError>>>;
errors?: Maybe<Array<ImageError>>;
metadata?: Maybe<ImageMetadata>;
projectId: Scalars['String']['output'];
};
Expand All @@ -438,7 +439,7 @@ export type ImageComment = {

export type ImageCommentsPayload = {
__typename?: 'ImageCommentsPayload';
comments?: Maybe<Array<Maybe<ImageComment>>>;
comments?: Maybe<Array<ImageComment>>;
};

export type ImageError = {
Expand All @@ -454,7 +455,7 @@ export type ImageError = {
export type ImageErrorsConnection = {
__typename?: 'ImageErrorsConnection';
errors: Array<ImageError>;
pageInfo?: Maybe<PageInfo>;
pageInfo: PageInfoWithCount;
};

export type ImageErrorsFilterInput = {
Expand Down Expand Up @@ -513,7 +514,7 @@ export type LabelDiffsInput = {

export type LabelList = {
__typename?: 'LabelList';
categories?: Maybe<Array<Maybe<Scalars['String']['output']>>>;
categories?: Maybe<Array<Scalars['String']['output']>>;
};

export type LabelUpdate = {
Expand Down Expand Up @@ -777,7 +778,7 @@ export type Object = {
__typename?: 'Object';
_id: Scalars['ID']['output'];
bbox?: Maybe<Array<Scalars['Float']['output']>>;
labels?: Maybe<Array<Maybe<Label>>>;
labels?: Maybe<Array<Label>>;
locked: Scalars['Boolean']['output'];
};

Expand All @@ -789,7 +790,7 @@ export type ObjectDiffsInput = {
export type ObjectInput = {
_id: Scalars['ID']['input'];
bbox?: InputMaybe<Array<Scalars['Float']['input']>>;
labels?: InputMaybe<Array<InputMaybe<CreateLabelInput>>>;
labels?: InputMaybe<Array<CreateLabelInput>>;
locked: Scalars['Boolean']['input'];
};

Expand Down Expand Up @@ -830,11 +831,11 @@ export type PointInput = {
export type Project = {
__typename?: 'Project';
_id: Scalars['String']['output'];
automationRules?: Maybe<Array<Maybe<AutomationRule>>>;
availableMLModels?: Maybe<Array<Maybe<Scalars['String']['output']>>>;
cameraConfigs?: Maybe<Array<Maybe<CameraConfig>>>;
automationRules?: Maybe<Array<AutomationRule>>;
availableMLModels?: Maybe<Array<Scalars['String']['output']>>;
cameraConfigs?: Maybe<Array<CameraConfig>>;
description?: Maybe<Scalars['String']['output']>;
labels?: Maybe<Array<Maybe<ProjectLabel>>>;
labels?: Maybe<Array<ProjectLabel>>;
name: Scalars['String']['output'];
timezone: Scalars['String']['output'];
views: Array<View>;
Expand Down Expand Up @@ -875,13 +876,13 @@ export type Query = {
images?: Maybe<ImagesConnection>;
imagesCount?: Maybe<ImagesCount>;
labels?: Maybe<LabelList>;
mlModels?: Maybe<Array<Maybe<MlModel>>>;
projects?: Maybe<Array<Maybe<Project>>>;
mlModels?: Maybe<Array<MlModel>>;
projects?: Maybe<Array<Project>>;
stats?: Maybe<Task>;
task?: Maybe<Task>;
tasks?: Maybe<TasksPayload>;
users?: Maybe<UsersPayload>;
wirelessCameras?: Maybe<Array<Maybe<WirelessCamera>>>;
wirelessCameras?: Maybe<Array<WirelessCamera>>;
};


Expand Down Expand Up @@ -1033,12 +1034,12 @@ export type RegisterCameraInput = {
export type RegisterCameraPayload = {
__typename?: 'RegisterCameraPayload';
project?: Maybe<Project>;
wirelessCameras?: Maybe<Array<Maybe<WirelessCamera>>>;
wirelessCameras?: Maybe<Array<WirelessCamera>>;
};

export type StandardErrorPayload = {
__typename?: 'StandardErrorPayload';
errors?: Maybe<Array<Maybe<Scalars['String']['output']>>>;
errors?: Maybe<Array<Scalars['String']['output']>>;
isOk?: Maybe<Scalars['Boolean']['output']>;
};

Expand All @@ -1065,6 +1066,7 @@ export type Task = {

export type TasksPayload = {
__typename?: 'TasksPayload';
pageInfo: PageInfo;
tasks: Array<Task>;
};

Expand All @@ -1075,16 +1077,16 @@ export type UnregisterCameraInput = {
export type UnregisterCameraPayload = {
__typename?: 'UnregisterCameraPayload';
project?: Maybe<Project>;
wirelessCameras?: Maybe<Array<Maybe<WirelessCamera>>>;
wirelessCameras?: Maybe<Array<WirelessCamera>>;
};

export type UpdateAutomationRulesInput = {
automationRules?: InputMaybe<Array<InputMaybe<AutomationRuleInput>>>;
automationRules: Array<AutomationRuleInput>;
};

export type UpdateAutomationRulesPayload = {
__typename?: 'UpdateAutomationRulesPayload';
automationRules?: Maybe<Array<Maybe<AutomationRule>>>;
automationRules?: Maybe<Array<AutomationRule>>;
};

export type UpdateBatchInput = {
Expand Down Expand Up @@ -1148,12 +1150,12 @@ export type UpdateViewPayload = {

export type User = {
__typename?: 'User';
created: Scalars['String']['output'];
email: Scalars['String']['output'];
enabled: Scalars['Boolean']['output'];
created?: Maybe<Scalars['Date']['output']>;
email?: Maybe<Scalars['String']['output']>;
enabled?: Maybe<Scalars['Boolean']['output']>;
roles: Array<UserRole>;
status: Scalars['String']['output'];
updated: Scalars['String']['output'];
status?: Maybe<Scalars['String']['output']>;
updated?: Maybe<Scalars['Date']['output']>;
username: Scalars['String']['output'];
};

Expand All @@ -1170,7 +1172,7 @@ export type UsersPayload = {

export type Validation = {
__typename?: 'Validation';
userId: Scalars['ID']['output'];
userId?: Maybe<Scalars['ID']['output']>;
validated: Scalars['Boolean']['output'];
validationDate: Scalars['Date']['output'];
};
Expand All @@ -1183,9 +1185,9 @@ export type ValidationInput = {

export type View = {
__typename?: 'View';
_id: Scalars['String']['output'];
_id: Scalars['ID']['output'];
description?: Maybe<Scalars['String']['output']>;
editable: Scalars['Boolean']['output'];
editable?: Maybe<Scalars['Boolean']['output']>;
filters: Filters;
name: Scalars['String']['output'];
};
Expand Down
11 changes: 6 additions & 5 deletions src/@types/mongo-cursor-pagination.d.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
declare module 'mongo-cursor-pagination' {
import { Model } from 'mongoose';
import { Model, PipelineStage } from 'mongoose';

type Maybe<T> = T | null;

export type AggregationInput = {
aggregation: Array<{
$match: Record<string, any>;
$set?: Record<string, any>;
}>;
aggregation: PipelineStage[];
paginatedField?: Maybe<string>;
sortAscending?: Maybe<boolean>;
limit?: Maybe<number>;
Expand All @@ -20,6 +17,10 @@ declare module 'mongo-cursor-pagination' {
page: number;
}>;
results: T[];
previous: Maybe<string>;
hasPrevious: boolean;
next: Maybe<string>;
hasNext: boolean;
}

const defaultExport: {
Expand Down
3 changes: 3 additions & 0 deletions src/@types/mongodb-query-parser.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
declare module 'mongodb-query-parser' {
export const isFilterValid = (filter: string) => boolean;
}
2 changes: 1 addition & 1 deletion src/api/auth/authorization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export interface User {
aud: string;
'cognito:username': string;
is_superuser: boolean;
curr_project: string | null;
curr_project: string;
projects: Record<string, { roles: string[] }>;
curr_project_roles: string[];
}
Expand Down
8 changes: 4 additions & 4 deletions src/api/db/models/Batch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ import Batch, { BatchSchema } from '../schemas/Batch.js';
import mongoose from 'mongoose';
import BatchError, { BatchErrorSchema } from '../schemas/BatchError.js';
import retry from 'async-retry';
import { BaseAuthedModel, GenericResponse, MethodParams, roleCheck } from './utils-model.js';
import { BaseAuthedModel, GenericResponse, MethodParams, roleCheck } from './utils.js';
import { ImageErrorModel } from './ImageError.js';
import { Context } from '../../handler.js';

export class BatchModel {
static async queryByFilter(
input: gql.QueryBatchesInput,
context: Context,
context: Pick<Context, 'user'>,
): Promise<AggregationOutput<BatchSchemaWithErrors>> {
try {
const pipeline: Record<'$match', Record<string, any>>[] = [
Expand Down Expand Up @@ -56,7 +56,7 @@ export class BatchModel {
}

static async queryById(_id: string): Promise<mongoose.HydratedDocument<BatchSchemaWithErrors>> {
const query = { _id };
const query = { _id: { $eq: _id } };
try {
const batch = await Batch.findOne<mongoose.HydratedDocument<BatchSchemaWithErrors>>(query);
if (!batch) throw new NotFoundError('Batch not found');
Expand Down Expand Up @@ -232,7 +232,7 @@ export class BatchModel {

static async createUpload(
input: gql.CreateUploadInput,
context: Context,
context: Pick<Context, 'user'>,
): Promise<gql.CreateUploadPayload> {
try {
const id = `batch-${randomUUID()}`;
Expand Down
2 changes: 1 addition & 1 deletion src/api/db/models/BatchError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import GraphQLError, { InternalServerError } from '../../errors.js';
import { WRITE_IMAGES_ROLES } from '../../auth/roles.js';
import BatchError, { BatchErrorSchema } from '../schemas/BatchError.js';
import retry from 'async-retry';
import { BaseAuthedModel, GenericResponse, MethodParams, roleCheck } from './utils-model.js';
import { BaseAuthedModel, GenericResponse, MethodParams, roleCheck } from './utils.js';

/**
* BatchErrors are errors that are generated when an uploaded Zip fails
Expand Down
Loading
Loading