From ece7a984fe852d0e8bc4dcb82881ce11b4e84bce Mon Sep 17 00:00:00 2001 From: Lars Johansson Date: Wed, 1 Mar 2023 09:51:52 +0100 Subject: [PATCH 1/8] feat: Added response types for different actions --- source/project_schema.ts | 6 +-- source/session.ts | 95 +++++++++++++++++++++++++++++++--------- 2 files changed, 78 insertions(+), 23 deletions(-) diff --git a/source/project_schema.ts b/source/project_schema.ts index 44484bbd..0c722717 100644 --- a/source/project_schema.ts +++ b/source/project_schema.ts @@ -1,8 +1,8 @@ // :copyright: Copyright (c) 2016 ftrack import * as operation from "./operation"; -import { Session } from "./session"; - +import { QueryResponse, Session } from "./session"; +import { Data } from "./types"; /** * Project schema namespace * @namespace project_schema @@ -71,7 +71,7 @@ export function getStatuses( ) ); - response = session.call(operations); + response = session.call>(operations); response = response.then((results) => { // Since the operations where performed in one batched call, // the result will be merged into a single entity. diff --git a/source/session.ts b/source/session.ts index 4e2eb6a5..3e05643d 100644 --- a/source/session.ts +++ b/source/session.ts @@ -77,18 +77,65 @@ export interface SearchOptions { objectTypeIds?: string[]; } -export interface Response { +interface ActionResponseMap { + query: { + data: Data[]; + }; + create: { + data: Data; + }; + update: { + data: Data; + }; + delete: { + data: boolean; + }; + search: { + data: Data[]; + }; +} + +interface BaseResponse { url?: any; headers?: any; - action: string; + action: keyof ActionResponseMap; metadata: { next: { offset: number | null; }; }; + data: T | T[] | boolean; +} + +export interface QueryResponse extends BaseResponse { data: T[]; + action: "query"; } +export interface CreateResponse extends BaseResponse { + data: T; + action: "create"; +} +export interface UpdateResponse extends BaseResponse { + data: T; + action: "update"; +} +export interface DeleteResponse extends BaseResponse { + data: boolean; + action: "delete"; +} +export interface SearchResponse extends BaseResponse { + data: T[]; + action: "search"; +} +export type Response = + | QueryResponse + | CreateResponse + | UpdateResponse + | DeleteResponse + | SearchResponse + | BaseResponse; + export interface ResponseError { exception: string; content: string; @@ -267,7 +314,7 @@ export class Session { this.initializing = this.call(operations).then((responses) => { this.serverInformation = responses[0]; this.schemas = responses[1]; - this.serverVersion = this.serverInformation.version; + this.serverVersion = this.serverInformation?.version; this.initialized = true; return Promise.resolve(this); @@ -567,7 +614,7 @@ export class Session { * @param {string} options.decodeDatesAsIso - Return dates as ISO strings instead of moment objects * */ - call( + call>( operations: operation.Operation[], { abortController, @@ -576,7 +623,7 @@ export class Session { additionalHeaders = {}, decodeDatesAsIso = false, }: CallOptions = {} - ): Promise[]> { + ): Promise { const url = `${this.serverUrl}${this.apiEndpoint}`; // Delay call until session is initialized if initialization is in @@ -794,7 +841,10 @@ export class Session { query(expression: string, options: QueryOptions = {}) { logger.debug("Query", expression); const queryOperation = operation.query(expression); - let request = this.call([queryOperation], options).then((responses) => { + let request = this.call>( + [queryOperation], + options + ).then((responses) => { const response = responses[0]; return response; }); @@ -844,7 +894,10 @@ export class Session { contextId, objectTypeIds, }); - let request = this.call([searchOperation], options).then((responses) => { + let request = this.call>( + [searchOperation], + options + ).then((responses) => { const response = responses[0]; return response; }); @@ -866,12 +919,13 @@ export class Session { create(entityType: string, data: Data, options: MutationOptions = {}) { logger.debug("Create", entityType, data, options); - let request = this.call([operation.create(entityType, data)], options).then( - (responses) => { - const response = responses[0]; - return response; - } - ); + let request = this.call>( + [operation.create(entityType, data)], + options + ).then((responses) => { + const response = responses[0]; + return response; + }); return request; } @@ -896,7 +950,7 @@ export class Session { ) { logger.debug("Update", type, keys, data, options); - const request = this.call( + const request = this.call>( [operation.update(type, keys, data)], options ).then((responses) => { @@ -921,12 +975,13 @@ export class Session { delete(type: string, keys: string[], options: MutationOptions = {}) { logger.debug("Delete", type, keys, options); - let request = this.call([operation.delete(type, keys)], options).then( - (responses) => { - const response = responses[0]; - return response; - } - ); + let request = this.call( + [operation.delete(type, keys)], + options + ).then((responses) => { + const response = responses[0]; + return response; + }); return request; } From e233177ec3e4cc402597bec5043373c94eecf38a Mon Sep 17 00:00:00 2001 From: Lars Johansson Date: Wed, 1 Mar 2023 15:40:27 +0100 Subject: [PATCH 2/8] Added types for all action responses and general type improvements --- source/project_schema.ts | 4 +- source/session.ts | 162 +++++++----------------------- source/types.ts | 211 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 247 insertions(+), 130 deletions(-) diff --git a/source/project_schema.ts b/source/project_schema.ts index 0c722717..77dc8bad 100644 --- a/source/project_schema.ts +++ b/source/project_schema.ts @@ -1,8 +1,8 @@ // :copyright: Copyright (c) 2016 ftrack import * as operation from "./operation"; -import { QueryResponse, Session } from "./session"; -import { Data } from "./types"; +import { Session } from "./session"; +import { Data, QueryResponse } from "./types"; /** * Project schema namespace * @namespace project_schema diff --git a/source/session.ts b/source/session.ts index 3e05643d..1b5a5cd5 100644 --- a/source/session.ts +++ b/source/session.ts @@ -15,7 +15,25 @@ import { import { SERVER_LOCATION_ID } from "./constant"; import normalizeString from "./util/normalize_string"; -import { Data } from "./types"; +import type { + ActionResponse, + CallOptions, + CreateComponentOptions, + CreateResponse, + Data, + DeleteResponse, + GetUploadMetadataResponse, + IsTuple, + MutationOptions, + QueryOptions, + QueryResponse, + QueryServerInformationResponse, + ResponseError, + SearchOptions, + SearchResponse, + SessionOptions, + UpdateResponse, +} from "./types"; import { convertToIsoString } from "./util/convert_to_iso_string"; const logger = loglevel.getLogger("ftrack_api"); @@ -42,122 +60,6 @@ function splitFileExtension(fileName: string) { return [basename, extension]; } -export interface EventHubOptions { - applicationId?: string; -} - -export interface SessionOptions { - autoConnectEventHub?: boolean; - serverInformationValues?: string[]; - eventHubOptions?: EventHubOptions; - clientToken?: string; - apiEndpoint?: string; - additionalHeaders?: Data; - strictApi?: boolean; -} - -export interface CreateComponentOptions { - name?: string; - data?: Data; - onProgress?: (progress: number) => unknown; - xhr?: XMLHttpRequest; - onAborted?: () => unknown; -} - -export interface Entity { - id: string; - __entity_type__: string; -} - -export interface SearchOptions { - expression: string; - entityType: string; - terms?: string[]; - contextId?: string; - objectTypeIds?: string[]; -} - -interface ActionResponseMap { - query: { - data: Data[]; - }; - create: { - data: Data; - }; - update: { - data: Data; - }; - delete: { - data: boolean; - }; - search: { - data: Data[]; - }; -} - -interface BaseResponse { - url?: any; - headers?: any; - action: keyof ActionResponseMap; - metadata: { - next: { - offset: number | null; - }; - }; - data: T | T[] | boolean; -} - -export interface QueryResponse extends BaseResponse { - data: T[]; - action: "query"; -} - -export interface CreateResponse extends BaseResponse { - data: T; - action: "create"; -} -export interface UpdateResponse extends BaseResponse { - data: T; - action: "update"; -} -export interface DeleteResponse extends BaseResponse { - data: boolean; - action: "delete"; -} -export interface SearchResponse extends BaseResponse { - data: T[]; - action: "search"; -} -export type Response = - | QueryResponse - | CreateResponse - | UpdateResponse - | DeleteResponse - | SearchResponse - | BaseResponse; - -export interface ResponseError { - exception: string; - content: string; - error_code?: string; - error?: Data; -} - -export interface MutationOptions { - pushToken?: string; - additionalHeaders?: Data; - decodeDatesAsIso?: boolean; -} - -export interface QueryOptions { - abortController?: AbortController; - signal?: AbortSignal; - additionalHeaders?: Data; - decodeDatesAsIso?: boolean; -} - -export interface CallOptions extends MutationOptions, QueryOptions {} - /** * ftrack API session * @class Session @@ -311,10 +213,12 @@ export class Session { * @instance * @type {Promise} */ - this.initializing = this.call(operations).then((responses) => { + this.initializing = this.call< + [QueryServerInformationResponse, QueryResponse] + >(operations).then((responses) => { this.serverInformation = responses[0]; this.schemas = responses[1]; - this.serverVersion = this.serverInformation?.version; + this.serverVersion = this.serverInformation.version; this.initialized = true; return Promise.resolve(this); @@ -614,7 +518,7 @@ export class Session { * @param {string} options.decodeDatesAsIso - Return dates as ISO strings instead of moment objects * */ - call>( + call( operations: operation.Operation[], { abortController, @@ -623,7 +527,7 @@ export class Session { additionalHeaders = {}, decodeDatesAsIso = false, }: CallOptions = {} - ): Promise { + ): Promise extends true ? T : T[]> { const url = `${this.serverUrl}${this.apiEndpoint}`; // Delay call until session is initialized if initialization is in @@ -841,7 +745,7 @@ export class Session { query(expression: string, options: QueryOptions = {}) { logger.debug("Query", expression); const queryOperation = operation.query(expression); - let request = this.call>( + let request = this.call<[QueryResponse]>( [queryOperation], options ).then((responses) => { @@ -894,7 +798,7 @@ export class Session { contextId, objectTypeIds, }); - let request = this.call>( + let request = this.call<[SearchResponse]>( [searchOperation], options ).then((responses) => { @@ -919,7 +823,7 @@ export class Session { create(entityType: string, data: Data, options: MutationOptions = {}) { logger.debug("Create", entityType, data, options); - let request = this.call>( + let request = this.call<[CreateResponse]>( [operation.create(entityType, data)], options ).then((responses) => { @@ -950,7 +854,7 @@ export class Session { ) { logger.debug("Update", type, keys, data, options); - const request = this.call>( + const request = this.call<[UpdateResponse]>( [operation.update(type, keys, data)], options ).then((responses) => { @@ -975,7 +879,7 @@ export class Session { delete(type: string, keys: string[], options: MutationOptions = {}) { logger.debug("Delete", type, keys, options); - let request = this.call( + let request = this.call<[DeleteResponse]>( [operation.delete(type, keys)], options ).then((responses) => { @@ -1052,7 +956,7 @@ export class Session { createComponent( file: Blob, options: CreateComponentOptions = {} - ): Promise[]> { + ): Promise { const componentName = options.name ?? (file as File).name; let normalizedFileName; @@ -1107,7 +1011,9 @@ export class Session { location_id: SERVER_LOCATION_ID, }; - const componentAndLocationPromise = this.call([ + const componentAndLocationPromise = this.call< + [CreateResponse, CreateResponse, GetUploadMetadataResponse] + >([ operation.create("FileComponent", component), operation.create("ComponentLocation", componentLocation), { diff --git a/source/types.ts b/source/types.ts index 65b1e4e4..d5152975 100644 --- a/source/types.ts +++ b/source/types.ts @@ -1 +1,212 @@ export type Data = { [key: string]: any }; +export type IsTuple = T extends [any, ...any] ? true : false; +export interface EventHubOptions { + applicationId?: string; +} + +export interface SessionOptions { + autoConnectEventHub?: boolean; + serverInformationValues?: string[]; + eventHubOptions?: EventHubOptions; + clientToken?: string; + apiEndpoint?: string; + additionalHeaders?: Data; + strictApi?: boolean; +} + +export interface CreateComponentOptions { + name?: string; + data?: Data; + onProgress?: (progress: number) => unknown; + xhr?: XMLHttpRequest; + onAborted?: () => unknown; +} + +export interface Entity { + id: string; + __entity_type__: string; +} +interface ResponseMetadata { + metadata: { + next: { + offset: number | null; + }; + }; +} +export interface SearchOptions { + expression: string; + entityType: string; + terms?: string[]; + contextId?: string; + objectTypeIds?: string[]; +} + +export interface QueryResponse { + data: T[]; + action: "query"; + metadata: ResponseMetadata; +} + +export interface CreateResponse { + data: T; + action: "create"; +} +export interface UpdateResponse { + data: T; + action: "update"; +} +export interface DeleteResponse { + data: true; + action: "delete"; +} +export interface SearchResponse { + data: T[]; + action: "search"; + metadata: ResponseMetadata; +} +export interface ResetRemoteResponse { + action: "reset_remote"; + data: Data; +} +export type QuerySchemasResponse = Data[]; +export interface QueryServerInformationResponse { + is_prevent_media_download_enabled?: boolean; + is_two_factor_authentication_enabled?: boolean; + is_two_factor_authentication_enforced?: boolean; + custom_widget?: Data; + spark_sentry_dsn?: string; + default_colors?: string[]; + is_nested_subqueries_enabled?: boolean; + license?: string[]; + require_billing_info_before?: string; + subscription_management?: Data; + preferred_language?: string; + week_startday?: number; + workday_length?: number; + display_week_numbers?: boolean; + storage_limit?: number; + i18n_message_url_ftrack_spark_overview?: string; + display_task_dates_as_time?: boolean; + company_information?: { + logo_url?: string; + name?: string; + }; + user_information?: { + access_key_id?: string | null; + id?: string; + is_global_access_key?: boolean; + restricted_user?: boolean; + username?: string; + }; + review_sync?: { + enabled?: boolean; + load_balancer?: string; + hosts?: string[]; + limited?: boolean; + }; + review_pro?: { + enabled?: boolean; + display_upsell_cta?: boolean; + }; + review_watermarking_text?: string; + product?: Data; + version?: string; + schema_hash?: string; + storage_scenario?: Data; + [key: string]: any; +} + +export interface GetWidgetUrlResponse { + widget_url: string; +} +export interface DelayedJobResponse { + action: "delayed_job"; + data?: any; +} +export interface EncodeMediaResponse { + job_id: string; +} +export interface GetUploadMetadataResponse { + url: string; + component_id?: string; + headers: Data; +} +export interface SetLicenseResponse { + license: any[]; +} + +export interface ValidateLicenseResponse { + success: boolean; + message?: string; +} +export interface UpdateLicenseResponse { + action: "update_license"; + success: boolean; + license?: any[]; +} +export interface AdjustSubscriptionResponse { + action: "adjust_subscription"; + success?: [boolean, string]; +} + +export interface SendReviewSessionInviteResponse { + sent: true; +} +export interface SendUserInviteResponse { + sent: true; +} +export interface ComputeRollupsResponse { + data: any[]; +} +export interface GenerateSignedUrlResponse { + signed_url: string; +} +export interface PermissionsResponse { + action: "permissions"; + data: Data; +} + +export type ActionResponse = + | QueryResponse + | CreateResponse + | UpdateResponse + | DeleteResponse + | SearchResponse + | ResetRemoteResponse + | QuerySchemasResponse + | QueryServerInformationResponse + | GetWidgetUrlResponse + | DelayedJobResponse + | EncodeMediaResponse + | GetUploadMetadataResponse + | SetLicenseResponse + | ValidateLicenseResponse + | UpdateLicenseResponse + | AdjustSubscriptionResponse + | SendReviewSessionInviteResponse + | SendUserInviteResponse + | ComputeRollupsResponse + | GenerateSignedUrlResponse + | PermissionsResponse; + +export interface ResponseError { + exception: string; + content: string; + error_code?: string; + error?: Data; +} + +export interface MutationOptions { + pushToken?: string; + additionalHeaders?: Data; + decodeDatesAsIso?: boolean; +} + +export interface QueryOptions { + abortController?: AbortController; + signal?: AbortSignal; + additionalHeaders?: Data; + decodeDatesAsIso?: boolean; +} + +export interface CallOptions extends MutationOptions, QueryOptions {} From e273fdd3b780eb9df4bcb16d25aad6ccbdcda886 Mon Sep 17 00:00:00 2001 From: Lars Johansson Date: Wed, 1 Mar 2023 16:11:17 +0100 Subject: [PATCH 3/8] Cleanup --- source/types.ts | 39 --------------------------------------- 1 file changed, 39 deletions(-) diff --git a/source/types.ts b/source/types.ts index d5152975..ebc2c24e 100644 --- a/source/types.ts +++ b/source/types.ts @@ -70,22 +70,15 @@ export interface ResetRemoteResponse { } export type QuerySchemasResponse = Data[]; export interface QueryServerInformationResponse { - is_prevent_media_download_enabled?: boolean; - is_two_factor_authentication_enabled?: boolean; - is_two_factor_authentication_enforced?: boolean; custom_widget?: Data; - spark_sentry_dsn?: string; default_colors?: string[]; is_nested_subqueries_enabled?: boolean; license?: string[]; - require_billing_info_before?: string; - subscription_management?: Data; preferred_language?: string; week_startday?: number; workday_length?: number; display_week_numbers?: boolean; storage_limit?: number; - i18n_message_url_ftrack_spark_overview?: string; display_task_dates_as_time?: boolean; company_information?: { logo_url?: string; @@ -98,17 +91,6 @@ export interface QueryServerInformationResponse { restricted_user?: boolean; username?: string; }; - review_sync?: { - enabled?: boolean; - load_balancer?: string; - hosts?: string[]; - limited?: boolean; - }; - review_pro?: { - enabled?: boolean; - display_upsell_cta?: boolean; - }; - review_watermarking_text?: string; product?: Data; version?: string; schema_hash?: string; @@ -131,23 +113,6 @@ export interface GetUploadMetadataResponse { component_id?: string; headers: Data; } -export interface SetLicenseResponse { - license: any[]; -} - -export interface ValidateLicenseResponse { - success: boolean; - message?: string; -} -export interface UpdateLicenseResponse { - action: "update_license"; - success: boolean; - license?: any[]; -} -export interface AdjustSubscriptionResponse { - action: "adjust_subscription"; - success?: [boolean, string]; -} export interface SendReviewSessionInviteResponse { sent: true; @@ -179,10 +144,6 @@ export type ActionResponse = | DelayedJobResponse | EncodeMediaResponse | GetUploadMetadataResponse - | SetLicenseResponse - | ValidateLicenseResponse - | UpdateLicenseResponse - | AdjustSubscriptionResponse | SendReviewSessionInviteResponse | SendUserInviteResponse | ComputeRollupsResponse From ccdeb27738a896af86001af1b118219704803567 Mon Sep 17 00:00:00 2001 From: Lars Johansson Date: Wed, 1 Mar 2023 16:18:26 +0100 Subject: [PATCH 4/8] fix: typeParam comment added to Call() --- source/session.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/source/session.ts b/source/session.ts index 1b5a5cd5..ee73b50e 100644 --- a/source/session.ts +++ b/source/session.ts @@ -509,6 +509,7 @@ export class Session { * ServerError * Generic server errors or network issues * + * @typeParam T - either an array of responseTypes to get return type Tuple or a single response to get return type T[]. Default is ActionResponse * @param {Array} operations - API operations. * @param {Object} options * @param {AbortController} options.abortController - Abort controller, deprecated in favor of options.signal From dd16f3f855a9f1420b86d7561d60371dfe06e63d Mon Sep 17 00:00:00 2001 From: Lars Johansson Date: Wed, 1 Mar 2023 16:18:39 +0100 Subject: [PATCH 5/8] More precise return type for createComponent --- source/session.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/session.ts b/source/session.ts index ee73b50e..32e386bf 100644 --- a/source/session.ts +++ b/source/session.ts @@ -957,7 +957,9 @@ export class Session { createComponent( file: Blob, options: CreateComponentOptions = {} - ): Promise { + ): Promise< + [CreateResponse, CreateResponse, GetUploadMetadataResponse] + > { const componentName = options.name ?? (file as File).name; let normalizedFileName; From e8d2bcfae3e1cf84eb81af0a6b2171c46344748c Mon Sep 17 00:00:00 2001 From: Lars Johansson Date: Wed, 1 Mar 2023 16:23:24 +0100 Subject: [PATCH 6/8] Update source/session.ts Co-authored-by: Jimmy Callin --- source/session.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/session.ts b/source/session.ts index 32e386bf..cfd025ad 100644 --- a/source/session.ts +++ b/source/session.ts @@ -509,7 +509,7 @@ export class Session { * ServerError * Generic server errors or network issues * - * @typeParam T - either an array of responseTypes to get return type Tuple or a single response to get return type T[]. Default is ActionResponse + * @typeParam T - Either an array of response types to get return type `Tuple`, or a single response type to get return type T[]. Default is ActionResponse. * @param {Array} operations - API operations. * @param {Object} options * @param {AbortController} options.abortController - Abort controller, deprecated in favor of options.signal From f8db0c4c195a7f40f8ccb3f44714daccbc77ee36 Mon Sep 17 00:00:00 2001 From: Lars Johansson Date: Wed, 1 Mar 2023 18:02:14 +0100 Subject: [PATCH 7/8] Added generic types to ensure, query, search, create, update and createComponent --- source/session.ts | 62 +++++++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/source/session.ts b/source/session.ts index cfd025ad..73f783c2 100644 --- a/source/session.ts +++ b/source/session.ts @@ -629,12 +629,13 @@ export class Session { * * Return update or create promise. */ - ensure( + + ensure( entityType: string, - data: Data, - identifyingKeys: string[] = [] - ): Promise { - let keys = identifyingKeys; + data: T, + identifyingKeys: Array = [] + ): Promise { + let keys = identifyingKeys as string[]; logger.info( "Ensuring entity with data using identifying keys: ", @@ -673,9 +674,9 @@ export class Session { expression = `${expression} ${criteria.join(" and ")}`; - return this.query(expression).then((response) => { + return this.query(expression).then((response) => { if (response.data.length === 0) { - return this.create(entityType, data).then(({ data: responseData }) => + return this.create(entityType, data).then(({ data: responseData }) => Promise.resolve(responseData) ); } @@ -692,7 +693,7 @@ export class Session { // Update entity if required. let updated = false; - Object.keys(data).forEach((key) => { + Object.keys(data).forEach((key: keyof T) => { if (data[key] !== updateEntity[key]) { updateEntity[key] = data[key]; updated = true; @@ -700,15 +701,15 @@ export class Session { }); if (updated) { - return this.update( + return this.update( entityType, primaryKeys.map((key: string) => updateEntity[key]), - Object.keys(data).reduce((accumulator, key) => { + Object.keys(data).reduce((accumulator, key: keyof T) => { if (primaryKeys.indexOf(key) === -1) { accumulator[key] = data[key]; } return accumulator; - }, {}) + }, {} as T) ).then(({ data: responseData }) => Promise.resolve(responseData)); } @@ -743,16 +744,15 @@ export class Session { * @return {Promise} Promise which will be resolved with an object * containing action, data and metadata */ - query(expression: string, options: QueryOptions = {}) { + query(expression: string, options: QueryOptions = {}) { logger.debug("Query", expression); const queryOperation = operation.query(expression); - let request = this.call<[QueryResponse]>( - [queryOperation], - options - ).then((responses) => { - const response = responses[0]; - return response; - }); + let request = this.call<[QueryResponse]>([queryOperation], options).then( + (responses) => { + const response = responses[0]; + return response; + } + ); return request; } @@ -774,7 +774,7 @@ export class Session { * @return {Promise} Promise which will be resolved with an object * containing data and metadata */ - search( + search( { expression, entityType, @@ -799,7 +799,7 @@ export class Session { contextId, objectTypeIds, }); - let request = this.call<[SearchResponse]>( + let request = this.call<[SearchResponse]>( [searchOperation], options ).then((responses) => { @@ -821,10 +821,14 @@ export class Session { * @param {object} options.decodeDatesAsIso - Decode dates as ISO strings instead of moment objects * @return {Promise} Promise which will be resolved with the response. */ - create(entityType: string, data: Data, options: MutationOptions = {}) { + create( + entityType: string, + data: T, + options: MutationOptions = {} + ) { logger.debug("Create", entityType, data, options); - let request = this.call<[CreateResponse]>( + let request = this.call<[CreateResponse]>( [operation.create(entityType, data)], options ).then((responses) => { @@ -847,15 +851,15 @@ export class Session { * @param {object} options.decodeDatesAsIso - Decode dates as ISO strings instead of moment objects * @return {Promise} Promise resolved with the response. */ - update( + update( type: string, keys: string[], - data: Data, + data: T, options: MutationOptions = {} ) { logger.debug("Update", type, keys, data, options); - const request = this.call<[UpdateResponse]>( + const request = this.call<[UpdateResponse]>( [operation.update(type, keys, data)], options ).then((responses) => { @@ -954,11 +958,11 @@ export class Session { * @return {Promise} Promise resolved with the response when creating * Component and ComponentLocation. */ - createComponent( + createComponent( file: Blob, options: CreateComponentOptions = {} ): Promise< - [CreateResponse, CreateResponse, GetUploadMetadataResponse] + [CreateResponse, CreateResponse, GetUploadMetadataResponse] > { const componentName = options.name ?? (file as File).name; @@ -1015,7 +1019,7 @@ export class Session { }; const componentAndLocationPromise = this.call< - [CreateResponse, CreateResponse, GetUploadMetadataResponse] + [CreateResponse, CreateResponse, GetUploadMetadataResponse] >([ operation.create("FileComponent", component), operation.create("ComponentLocation", componentLocation), From 4168afc58e0ad19e1910ed72d7306a69b541deba Mon Sep 17 00:00:00 2001 From: Lars Johansson Date: Thu, 2 Mar 2023 09:23:45 +0100 Subject: [PATCH 8/8] Removed an incorrect extra object level --- source/types.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/source/types.ts b/source/types.ts index ebc2c24e..125beebf 100644 --- a/source/types.ts +++ b/source/types.ts @@ -27,10 +27,8 @@ export interface Entity { __entity_type__: string; } interface ResponseMetadata { - metadata: { - next: { - offset: number | null; - }; + next: { + offset: number | null; }; } export interface SearchOptions {