diff --git a/libraries/grpc-sdk/src/modules/database/index.ts b/libraries/grpc-sdk/src/modules/database/index.ts index af37deaf2..e94335a74 100644 --- a/libraries/grpc-sdk/src/modules/database/index.ts +++ b/libraries/grpc-sdk/src/modules/database/index.ts @@ -11,6 +11,13 @@ import { UntypedArray, } from '../../interfaces/index.js'; import { Query } from '../../types/db.js'; +import { FindOneOptions, FindManyOptions } from './types.js'; +import { AuthzOptions, PopulateAuthzOptions } from '../../types/options.js'; +import { isNil } from 'lodash'; +import { + normalizeAuthzOptions, + normalizePopulateAuthzOptions, +} from '../../utilities/normalizeOptions.js'; export class DatabaseProvider extends ConduitModule { constructor( @@ -116,21 +123,36 @@ export class DatabaseProvider extends ConduitModule; + + findOne(schemaName: string, query: Query, options?: FindOneOptions): Promise; + + findOne( + schemaName: string, + query: Query, + selectOrOptions?: string | FindOneOptions, + populate?: string | string[], + userId?: string, + scope?: string, ): Promise { - let populateArray = populate; - if (populate && !Array.isArray(populate)) { - populateArray = [populate]; + let options: FindOneOptions; + if (typeof selectOrOptions === 'string' || isNil(selectOrOptions)) { + options = { select: selectOrOptions, populate, userId, scope }; + } else { + options = selectOrOptions; } + let populateArray = options.populate; + if (options.populate && !Array.isArray(options.populate)) { + populateArray = [options.populate]; + } + return this.client!.findOne({ schemaName, query: this.processQuery(query), - select: select === null ? undefined : select, + ...options, + select: options.select === null ? undefined : options.select, populate: (populateArray as string[]) ?? [], - userId, - scope, - }).then(res => { - return JSON.parse(res.result); - }); + }).then(res => JSON.parse(res.result)); } findMany( @@ -143,23 +165,55 @@ export class DatabaseProvider extends ConduitModule; + + findMany( + schemaName: string, + query: Query, + options?: FindManyOptions, + ): Promise; + + findMany( + schemaName: string, + query: Query, + selectOrOptions?: string | FindManyOptions, + skip?: number, + limit?: number, + sort?: { [field: string]: -1 | 1 } | string[] | string, + populate?: string | string[], + userId?: string, + scope?: string, ): Promise { - if (typeof sort === 'string') sort = [sort]; - const sortObj = Array.isArray(sort) ? this.constructSortObj(sort) : sort; - let populateArray = populate; - if (populate && !Array.isArray(populate)) { - populateArray = [populate]; + let options: FindManyOptions; + if (typeof selectOrOptions === 'string' || isNil(selectOrOptions)) { + options = { + select: selectOrOptions, + skip, + limit, + sort, + populate, + userId, + scope, + }; + } else { + options = selectOrOptions; } + if (typeof options.sort === 'string') options.sort = [options.sort]; + const sortObj = Array.isArray(options.sort) + ? this.constructSortObj(options.sort) + : options.sort; + let populateArray = options.populate; + if (options.populate && !Array.isArray(options.populate)) { + populateArray = [options.populate]; + } + return this.client!.findMany({ schemaName, query: this.processQuery(query), - select: select === null ? undefined : select, - skip, - limit, + ...options, + select: options.select === null ? undefined : options.select, sort: sortObj, populate: (populateArray as string[]) ?? [], - userId, - scope, }).then(res => { return JSON.parse(res.result); }); @@ -170,12 +224,21 @@ export class DatabaseProvider extends ConduitModule, userId?: string, scope?: string, + ): Promise; + + create(schemaName: string, query: Query, options?: AuthzOptions): Promise; + + create( + schemaName: string, + query: Query, + userIdOrOptions?: string | AuthzOptions, + scope?: string, ): Promise { + const options = normalizeAuthzOptions(userIdOrOptions, scope); return this.client!.create({ schemaName, query: this.processQuery(query), - userId, - scope, + ...options, }).then(res => { return JSON.parse(res.result); }); @@ -186,12 +249,25 @@ export class DatabaseProvider extends ConduitModule[], userId?: string, scope?: string, + ): Promise; + + createMany( + schemaName: string, + query: Query[], + options?: AuthzOptions, + ): Promise; + + createMany( + schemaName: string, + query: Query, + userIdOrOptions?: string | AuthzOptions, + scope?: string, ): Promise { + const options = normalizeAuthzOptions(userIdOrOptions, scope); return this.client!.createMany({ schemaName, query: this.processQuery(query), - userId, - scope, + ...options, }).then(res => { return JSON.parse(res.result); }); @@ -204,18 +280,34 @@ export class DatabaseProvider extends ConduitModule; + + findByIdAndUpdate( + schemaName: string, + id: string, + document: Query, + options?: PopulateAuthzOptions, + ): Promise; + + findByIdAndUpdate( + schemaName: string, + id: string, + document: Query, + populateOrOptions?: string | string[] | PopulateAuthzOptions, + userId?: string, + scope?: string, ): Promise { - let populateArray = populate; - if (populate && !Array.isArray(populate)) { - populateArray = [populate]; + const options = normalizePopulateAuthzOptions(populateOrOptions, userId, scope); + let populateArray = options.populate; + if (options.populate && !Array.isArray(options.populate)) { + populateArray = [options.populate]; } return this.client!.findByIdAndUpdate({ schemaName, id, query: this.processQuery(document), + ...options, populate: (populateArray as string[]) ?? [], - userId, - scope, }).then(res => { return JSON.parse(res.result); }); @@ -228,18 +320,34 @@ export class DatabaseProvider extends ConduitModule; + + findByIdAndReplace( + schemaName: string, + id: string, + document: Query, + options?: PopulateAuthzOptions, + ): Promise; + + findByIdAndReplace( + schemaName: string, + id: string, + document: Query, + populateOrOptions?: string | string[] | PopulateAuthzOptions, + userId?: string, + scope?: string, ): Promise { - let populateArray = populate; - if (populate && !Array.isArray(populate)) { - populateArray = [populate]; + const options = normalizePopulateAuthzOptions(populateOrOptions, userId, scope); + let populateArray = options.populate; + if (options.populate && !Array.isArray(options.populate)) { + populateArray = [options.populate]; } return this.client!.findByIdAndReplace({ schemaName, id, query: this.processQuery(document), + ...options, populate: (populateArray as string[]) ?? [], - userId, - scope, }).then(res => { return JSON.parse(res.result); }); @@ -252,18 +360,34 @@ export class DatabaseProvider extends ConduitModule; + + updateMany( + schemaName: string, + filterQuery: Query, + query: Query, + options?: PopulateAuthzOptions, + ): Promise; + + updateMany( + schemaName: string, + filterQuery: Query, + query: Query, + populateOrOptions?: string | string[] | PopulateAuthzOptions, + userId?: string, + scope?: string, ) { - let populateArray = populate; - if (populate && !Array.isArray(populate)) { - populateArray = [populate]; + const options = normalizePopulateAuthzOptions(populateOrOptions, userId, scope); + let populateArray = options.populate; + if (options.populate && !Array.isArray(options.populate)) { + populateArray = [options.populate]; } return this.client!.updateMany({ schemaName, filterQuery: this.processQuery(filterQuery), query: this.processQuery(query), + ...options, populate: (populateArray as string[]) ?? [], - userId, - scope, }).then(res => { return JSON.parse(res.result); }); @@ -276,18 +400,34 @@ export class DatabaseProvider extends ConduitModule; + + updateOne( + schemaName: string, + filterQuery: Query, + query: Query, + options?: PopulateAuthzOptions, + ): Promise; + + updateOne( + schemaName: string, + filterQuery: Query, + query: Query, + populateOrOptions?: string | string[] | PopulateAuthzOptions, + userId?: string, + scope?: string, ) { - let populateArray = populate; - if (populate && !Array.isArray(populate)) { - populateArray = [populate]; + const options = normalizePopulateAuthzOptions(populateOrOptions, userId, scope); + let populateArray = options.populate; + if (options.populate && !Array.isArray(options.populate)) { + populateArray = [options.populate]; } return this.client!.updateOne({ schemaName, filterQuery: this.processQuery(filterQuery), query: this.processQuery(query), + ...options, populate: (populateArray as string[]) ?? [], - userId, - scope, }).then(res => { return JSON.parse(res.result); }); @@ -300,40 +440,88 @@ export class DatabaseProvider extends ConduitModule; + + replaceOne( + schemaName: string, + filterQuery: Query, + query: Query, + options?: PopulateAuthzOptions, + ): Promise; + + replaceOne( + schemaName: string, + filterQuery: Query, + query: Query, + populateOrOptions?: string | string[] | PopulateAuthzOptions, + userId?: string, + scope?: string, ) { - let populateArray = populate; - if (populate && !Array.isArray(populate)) { - populateArray = [populate]; + const options = normalizePopulateAuthzOptions(populateOrOptions, userId, scope); + let populateArray = options.populate; + if (options.populate && !Array.isArray(options.populate)) { + populateArray = [options.populate]; } return this.client!.replaceOne({ schemaName, filterQuery: this.processQuery(filterQuery), query: this.processQuery(query), + ...options, populate: (populateArray as string[]) ?? [], - userId, - scope, }).then(res => { return JSON.parse(res.result); }); } - deleteOne(schemaName: string, query: Query, userId?: string, scope?: string) { + deleteOne( + schemaName: string, + query: Query, + userId?: string, + scope?: string, + ): Promise; + + deleteOne(schemaName: string, query: Query, options?: AuthzOptions): Promise; + + deleteOne( + schemaName: string, + query: Query, + userIdOrOptions?: string | AuthzOptions, + scope?: string, + ) { + const options = normalizeAuthzOptions(userIdOrOptions, scope); return this.client!.deleteOne({ schemaName, query: this.processQuery(query), - userId, - scope, + ...options, }).then(res => { return JSON.parse(res.result); }); } - deleteMany(schemaName: string, query: Query, userId?: string, scope?: string) { + deleteMany( + schemaName: string, + query: Query, + userId?: string, + scope?: string, + ): Promise; + + deleteMany( + schemaName: string, + query: Query, + options?: AuthzOptions, + ): Promise; + + deleteMany( + schemaName: string, + query: Query, + userIdOrOptions?: string | AuthzOptions, + scope?: string, + ) { + const options = normalizeAuthzOptions(userIdOrOptions, scope); return this.client!.deleteMany({ schemaName, query: this.processQuery(query), - userId, - scope, + ...options, }).then(res => { return JSON.parse(res.result); }); @@ -344,12 +532,25 @@ export class DatabaseProvider extends ConduitModule, userId?: string, scope?: string, + ): Promise; + + countDocuments( + schemaName: string, + query: Query, + options?: AuthzOptions, + ): Promise; + + countDocuments( + schemaName: string, + query: Query, + userIdOrOptions?: string | AuthzOptions, + scope?: string, ): Promise { + const options = normalizeAuthzOptions(userIdOrOptions, scope); return this.client!.countDocuments({ schemaName, query: this.processQuery(query), - userId, - scope, + ...options, }).then(res => { return JSON.parse(res.result); }); diff --git a/libraries/grpc-sdk/src/modules/database/types.ts b/libraries/grpc-sdk/src/modules/database/types.ts new file mode 100644 index 000000000..9d7fe3030 --- /dev/null +++ b/libraries/grpc-sdk/src/modules/database/types.ts @@ -0,0 +1,16 @@ +export type FindOneOptions = { + select?: string; + populate?: string | string[]; + userId?: string; + scope?: string; +}; + +export type FindManyOptions = { + select?: string; + skip?: number; + limit?: number; + sort?: { [field: string]: -1 | 1 } | string[] | string; + populate?: string | string[]; + userId?: string; + scope?: string; +}; diff --git a/libraries/grpc-sdk/src/modules/pushNotifications/index.ts b/libraries/grpc-sdk/src/modules/pushNotifications/index.ts index fa1fab41c..72f5bd769 100644 --- a/libraries/grpc-sdk/src/modules/pushNotifications/index.ts +++ b/libraries/grpc-sdk/src/modules/pushNotifications/index.ts @@ -1,5 +1,10 @@ import { ConduitModule } from '../../classes/index.js'; -import { PushNotificationsDefinition } from '../../protoUtils/index.js'; +import { + PushNotificationsDefinition, + SendNotificationResponse, +} from '../../protoUtils/index.js'; +import { SendNotificationOptions } from './types'; +import { isNil } from 'lodash'; export class PushNotifications extends ConduitModule { constructor( @@ -37,13 +42,31 @@ export class PushNotifications extends ConduitModule; + + sendNotification( + sendTo: string, + title: string, + options?: SendNotificationOptions, + ): Promise; + + sendNotification( + sendTo: string, + title: string, + bodyOrOptions?: string | SendNotificationOptions, + data?: string, + platform?: string, ) { + let options: SendNotificationOptions; + if (typeof bodyOrOptions === 'string' || isNil(bodyOrOptions)) { + options = { body: bodyOrOptions, data, platform }; + } else { + options = bodyOrOptions; + } return this.client!.sendNotification({ sendTo, title, - body, - data, - platform, + ...options, }); } @@ -63,13 +86,31 @@ export class PushNotifications extends ConduitModule; + + sendNotificationToManyDevices( + sendTo: string[], + title: string, + options?: SendNotificationOptions, + ): Promise; + + sendNotificationToManyDevices( + sendTo: string[], + title: string, + bodyOrOptions?: string | SendNotificationOptions, + data?: string, + platform?: string, ) { + let options: SendNotificationOptions; + if (typeof bodyOrOptions === 'string' || isNil(bodyOrOptions)) { + options = { body: bodyOrOptions, data, platform }; + } else { + options = bodyOrOptions; + } return this.client!.sendNotificationToManyDevices({ sendTo, title, - body, - data, - platform, + ...options, }); } } diff --git a/libraries/grpc-sdk/src/modules/pushNotifications/types.ts b/libraries/grpc-sdk/src/modules/pushNotifications/types.ts new file mode 100644 index 000000000..7737b6d6f --- /dev/null +++ b/libraries/grpc-sdk/src/modules/pushNotifications/types.ts @@ -0,0 +1,5 @@ +export type SendNotificationOptions = { + body?: string; + data?: string; + platform?: string; +}; diff --git a/libraries/grpc-sdk/src/modules/storage/index.ts b/libraries/grpc-sdk/src/modules/storage/index.ts index 405ba3f8e..339aede00 100644 --- a/libraries/grpc-sdk/src/modules/storage/index.ts +++ b/libraries/grpc-sdk/src/modules/storage/index.ts @@ -1,11 +1,21 @@ import { ConduitModule } from '../../classes/index.js'; import { DeleteFileResponse, + FileByUrlResponse, FileResponse, GetFileDataResponse, GetFileUrlResponse, StorageDefinition, } from '../../protoUtils/storage.js'; +import { AuthzOptions } from '../../types'; +import { normalizeAuthzOptions } from '../../utilities/normalizeOptions'; +import { + CreateFileByURLOptions, + CreateFileOptions, + UpdateFileByURLOptions, + UpdateFileOptions, +} from './types'; +import { isNil } from 'lodash'; export class Storage extends ConduitModule { constructor( @@ -17,16 +27,43 @@ export class Storage extends ConduitModule { this.initializeClient(StorageDefinition); } - getFile(id: string, userId?: string, scope?: string): Promise { - return this.client!.getFile({ id, userId, scope }); + getFile(id: string, userId?: string, scope?: string): Promise; + + getFile(id: string, options?: AuthzOptions): Promise; + + getFile( + id: string, + userIdOrOptions?: string | AuthzOptions, + scope?: string, + ): Promise { + const options = normalizeAuthzOptions(userIdOrOptions, scope); + return this.client!.getFile({ id, ...options }); } - getFileUrl(id: string, userId?: string, scope?: string): Promise { - return this.client!.getFileUrl({ id, userId, scope }); + getFileUrl(id: string, userId?: string, scope?: string): Promise; + + getFileUrl(id: string, options?: AuthzOptions): Promise; + + getFileUrl( + id: string, + userIdOrOptions?: string | AuthzOptions, + scope?: string, + ): Promise { + const options = normalizeAuthzOptions(userIdOrOptions, scope); + return this.client!.getFileUrl({ id, ...options }); } - getFileData(id: string, userId?: string, scope?: string): Promise { - return this.client!.getFileData({ id, userId, scope }); + getFileData(id: string, userId?: string, scope?: string): Promise; + + getFileData(id: string, options?: AuthzOptions): Promise; + + getFileData( + id: string, + userIdOrOptions?: string | AuthzOptions, + scope?: string, + ): Promise { + const options = normalizeAuthzOptions(userIdOrOptions, scope); + return this.client!.getFileData({ id, ...options }); } createFile( @@ -35,21 +72,48 @@ export class Storage extends ConduitModule { folder?: string, container?: string, mimeType?: string, - isPublic: boolean = false, + isPublic?: boolean, + userId?: string, + scope?: string, + alias?: string, + ): Promise; + + createFile( + name: string | undefined, + data: string, + options?: CreateFileOptions, + ): Promise; + + createFile( + name: string | undefined, + data: string, + folderOrOptions?: string | CreateFileOptions, + container?: string, + mimeType?: string, + isPublic?: boolean, userId?: string, scope?: string, alias?: string, ): Promise { + let options: CreateFileOptions; + if (typeof folderOrOptions === 'string' || isNil(folderOrOptions)) { + options = { + folder: folderOrOptions, + container, + mimeType, + isPublic, + userId, + scope, + alias, + }; + } else { + options = folderOrOptions; + } return this.client!.createFile({ name, - mimeType, data, - folder, - isPublic, - container, - userId, - scope, - alias, + ...options, + isPublic: options.isPublic ?? false, }); } @@ -63,22 +127,57 @@ export class Storage extends ConduitModule { userId?: string, scope?: string, alias?: string, + ): Promise; + + updateFile( + id: string, + data: string, + options?: UpdateFileOptions, + ): Promise; + + updateFile( + id: string, + data: string, + nameOrOptions?: string | UpdateFileOptions, + folder?: string, + container?: string, + mimeType?: string, + userId?: string, + scope?: string, + alias?: string, ): Promise { + let options: UpdateFileOptions; + if (typeof nameOrOptions === 'string' || isNil(nameOrOptions)) { + options = { + name: nameOrOptions, + folder, + container, + mimeType, + userId, + scope, + alias, + }; + } else { + options = nameOrOptions; + } return this.client!.updateFile({ - name, - mimeType, - data, - folder, id, - container, - userId, - scope, - alias, + data, + ...options, }); } - deleteFile(id: string, userId?: string, scope?: string): Promise { - return this.client!.deleteFile({ id, userId, scope }); + deleteFile(id: string, userId?: string, scope?: string): Promise; + + deleteFile(id: string, options?: AuthzOptions): Promise; + + deleteFile( + id: string, + userIdOrOptions?: string | AuthzOptions, + scope?: string, + ): Promise { + const options = normalizeAuthzOptions(userIdOrOptions, scope); + return this.client!.deleteFile({ id, ...options }); } createFileByUrl( @@ -87,21 +186,47 @@ export class Storage extends ConduitModule { container?: string, mimeType?: string, size?: number, - isPublic: boolean = false, + isPublic?: boolean, userId?: string, scope?: string, alias?: string, - ) { + ): Promise; + + createFileByUrl( + name: string | undefined, + options?: CreateFileByURLOptions, + ): Promise; + + createFileByUrl( + name: string | undefined, + folderOrOptions?: string | CreateFileByURLOptions, + container?: string, + mimeType?: string, + size?: number, + isPublic?: boolean, + userId?: string, + scope?: string, + alias?: string, + ): Promise { + let options: CreateFileByURLOptions; + if (typeof folderOrOptions === 'string' || isNil(folderOrOptions)) { + options = { + folder: folderOrOptions, + container, + mimeType, + size, + isPublic, + userId, + scope, + alias, + }; + } else { + options = folderOrOptions; + } return this.client!.createFileByUrl({ name, - mimeType, - folder, - container, - size, - isPublic, - userId, - scope, - alias, + ...options, + isPublic: options.isPublic ?? false, }); } @@ -115,17 +240,39 @@ export class Storage extends ConduitModule { userId?: string, scope?: string, alias?: string, - ) { - return this.client!.updateFileByUrl({ - id, - name, - folder, - container, - mimeType, - size, - userId, - scope, - alias, - }); + ): Promise; + + updateFileByUrl( + id: string, + options?: UpdateFileByURLOptions, + ): Promise; + + updateFileByUrl( + id: string, + nameOrOptions?: string | UpdateFileByURLOptions, + folder?: string, + container?: string, + mimeType?: string, + size?: number, + userId?: string, + scope?: string, + alias?: string, + ): Promise { + let options: UpdateFileByURLOptions; + if (typeof nameOrOptions === 'string' || isNil(nameOrOptions)) { + options = { + name: nameOrOptions, + folder, + container, + mimeType, + size, + userId, + scope, + alias, + }; + } else { + options = nameOrOptions; + } + return this.client!.updateFileByUrl({ id, ...options }); } } diff --git a/libraries/grpc-sdk/src/modules/storage/types.ts b/libraries/grpc-sdk/src/modules/storage/types.ts new file mode 100644 index 000000000..63dce214e --- /dev/null +++ b/libraries/grpc-sdk/src/modules/storage/types.ts @@ -0,0 +1,23 @@ +export type CreateFileOptions = { + folder?: string; + container?: string; + mimeType?: string; + isPublic?: boolean; + userId?: string; + scope?: string; + alias?: string; +}; + +export type UpdateFileOptions = { + name?: string; + folder?: string; + container?: string; + mimeType?: string; + userId?: string; + scope?: string; + alias?: string; +}; + +export type CreateFileByURLOptions = { size?: number } & CreateFileOptions; + +export type UpdateFileByURLOptions = { size?: number } & UpdateFileOptions; diff --git a/libraries/grpc-sdk/src/types/index.ts b/libraries/grpc-sdk/src/types/index.ts index a08436c1d..562031b3b 100644 --- a/libraries/grpc-sdk/src/types/index.ts +++ b/libraries/grpc-sdk/src/types/index.ts @@ -1,6 +1,8 @@ import { Metadata, status } from '@grpc/grpc-js'; export * from './db.js'; +export * from './options.js'; + export type GrpcRequest = { request: T; metadata?: Metadata }; export type GrpcResponse = ( err: { diff --git a/libraries/grpc-sdk/src/types/options.ts b/libraries/grpc-sdk/src/types/options.ts new file mode 100644 index 000000000..122083286 --- /dev/null +++ b/libraries/grpc-sdk/src/types/options.ts @@ -0,0 +1,8 @@ +export type AuthzOptions = { + userId?: string; + scope?: string; +}; + +export type PopulateAuthzOptions = { + populate?: string | string[]; +} & AuthzOptions; diff --git a/libraries/grpc-sdk/src/utilities/normalizeOptions.ts b/libraries/grpc-sdk/src/utilities/normalizeOptions.ts new file mode 100644 index 000000000..1b5407bb4 --- /dev/null +++ b/libraries/grpc-sdk/src/utilities/normalizeOptions.ts @@ -0,0 +1,27 @@ +import { AuthzOptions, PopulateAuthzOptions } from '../types'; +import { isNil } from 'lodash'; + +export function normalizeAuthzOptions( + userIdOrOptions?: string | AuthzOptions, + scope?: string, +): AuthzOptions { + if (typeof userIdOrOptions === 'string' || isNil(userIdOrOptions)) { + return { userId: userIdOrOptions, scope }; + } + return userIdOrOptions; +} + +export function normalizePopulateAuthzOptions( + populateOrOptions?: string | string[] | PopulateAuthzOptions, + userId?: string, + scope?: string, +) { + if ( + typeof populateOrOptions === 'string' || + Array.isArray(populateOrOptions) || + isNil(populateOrOptions) + ) { + return { populate: populateOrOptions, userId, scope }; + } + return populateOrOptions; +}