@eddye68/studio-client
Version:
The AWS service Studio client
1 lines • 88.6 kB
Source Map (JSON)
{"version":3,"sources":["../src/common/argument-error.ts","../src/model/wfl/basic-metadata.ts","../src/model/wfl/category.ts","../src/model/wfl/metadata.ts","../src/model/wfl/publication.ts","../src/model/wfl/state.ts","../src/model/wfl/wflobject.ts","../src/model/wfl/workflow-metadata.ts","../src/client/helpers/wfl-helpers.ts","../src/client/client-error.ts","../src/client/client.ts","../src/http-client/http-error.ts","../src/http-client/http-response-error.ts","../src/http-client/http-client.ts","../src/model/wfl/relation.ts","../src/client/client-option-error.ts","../src/client/client-options.ts","../src/model/wfl/attachment.ts","../src/model/wfl/content-metadata.ts","../src/model/wfl/edition-renditions-info.ts","../src/model/wfl/edition.ts","../src/model/wfl/element.ts","../src/model/wfl/extra-metadata.ts","../src/model/wfl/indesign-article.ts","../src/model/wfl/issue.ts","../src/model/wfl/message-list.ts","../src/model/wfl/message.ts","../src/model/wfl/metadata-value.ts","../src/model/wfl/object-info.ts","../src/model/wfl/object-label.ts","../src/model/wfl/object-operations.ts","../src/model/wfl/page.ts","../src/model/wfl/param.ts","../src/model/wfl/placement.ts","../src/model/wfl/property-value.ts","../src/model/wfl/pub-channel.ts","../src/model/wfl/rendition-type-info.ts","../src/model/wfl/rights-metadata.ts","../src/model/wfl/source-metadata.ts","../src/model/wfl/sticky-info.ts","../src/model/wfl/target.ts"],"sourcesContent":["export class ArgumentError extends Error {\n constructor(message: string, public paramName: string, error?: Error) {\n super(ArgumentError.buildMessage(message, paramName, error));\n this.name = 'ArgumentError';\n }\n\n private static buildMessage(message: string, paramName: string, error?: Error) {\n return `${message} (Parameter '${paramName}')`;\n }\n}","import { Category } from \"./category\";\nimport { Publication } from \"./publication\";\n\nexport class BasicMetaData {\n public __classname__: string = 'BasicMetaData';\n\n public ID : string | null = null;\n\n public DocumentID : string | null = null;\n\n public Name : string | null = null;\n\n public Type : string | null = null;\n\n public Publication : Publication | null = null;\n\n public Category : Category | null = null;\n\n public ContentSource : string | null = null;\n\n public MasterId : string | null = null;\n\n public StoryId : string | null = null;\n\n constructor(\n params : BasicMetaDataNamedParameters\n ) {\n this.ID = params.ID ?? null;\n this.DocumentID = params.DocumentID ?? null;\n this.Name = params.Name ?? null;\n this.Type = params.Type ?? null;\n this.Publication = params.Publication ?? null;\n this.Category = params.Category ?? null;\n this.ContentSource = params.ContentSource ?? null;\n this.MasterId = params.MasterId ?? null;\n this.StoryId = params.StoryId ?? null;\n }\n}\n\nexport interface BasicMetaDataNamedParameters {\n ID? : string \n DocumentID? : string\n Name? : string \n Type? : string \n Publication? : Publication \n Category? : Category \n ContentSource? : string \n MasterId? : string \n StoryId? : string \n}","export class Category {\n public __classname__: string = 'Category';\n\n public Id : string | null = null;\n\n public Name : string | null = null; \n \n constructor(params : CategoryNamedParameters ) {\n this.Id = params.Id ?? null;\n this.Name = params.Name ?? null;\n }\n}\n\nexport interface CategoryNamedParameters {\n Id? : string \n Name? : string\n}","import { BasicMetaData } from \"./basic-metadata\";\nimport { ContentMetaData } from \"./content-metadata\";\nimport { ExtraMetaData } from \"./extra-metadata\";\nimport { RightsMetaData } from \"./rights-metadata\";\nimport { SourceMetaData } from \"./source-metadata\";\nimport { WorkflowMetaData } from \"./workflow-metadata\";\n\nexport class MetaData {\n public __classname__: string = 'MetaData';\n\n\n public BasicMetaData: BasicMetaData | null = null;\n\n public RightsMetaData: RightsMetaData | null = null;\n\n public SourceMetaData: SourceMetaData | null = null;\n\n public ContentMetaData: ContentMetaData | null = null;\n\n public WorkflowMetaData: WorkflowMetaData | null = null;\n\n public ExtraMetaData: ExtraMetaData | null = null;\n\n constructor(\n params : MetaDataNamedParameters\n ) {\n this.BasicMetaData = params.BasicMetaData ?? null;\n this.RightsMetaData = params.RightsMetaData ?? null;\n this.SourceMetaData = params.SourceMetaData ?? null;\n this.ContentMetaData = params.ContentMetaData ?? null;\n this.WorkflowMetaData = params.WorkflowMetaData ?? null;\n this.ExtraMetaData = params.ExtraMetaData ?? null;\n }\n\n}\n\nexport interface MetaDataNamedParameters {\n BasicMetaData?: BasicMetaData,\n RightsMetaData?: RightsMetaData,\n SourceMetaData?: SourceMetaData,\n ContentMetaData?: ContentMetaData,\n WorkflowMetaData?: WorkflowMetaData,\n ExtraMetaData?: ExtraMetaData\n}","export class Publication {\n public __classname__: string = 'Publication';\n\n public Id : string | null = null;\n\n public Name : string | null = null; \n \n constructor(params : PublicationNamedParameters) {\n this.Id = params.Id ?? null;\n this.Name = params.Name ?? null;\n }\n}\n\nexport interface PublicationNamedParameters {\n Id? : string \n Name? : string\n}","export class State {\n public __classname__: string = 'State';\n\n public Id: string | null = null;\n public Name: string | null = null;\n public Type: string | null = null;\n public Produce: boolean | null = null;\n public Color: string | null = null;\n public DefaultRouteTo: string | null = null;\n\n constructor(\n Id: string | null = null,\n Name: string | null = null,\n Type: string | null = null,\n Produce: boolean | null = null,\n Color: string | null = null,\n DefaultRouteTo: string | null = null\n ) {\n this.Id = Id;\n this.Name = Name;\n this.Type = Type;\n this.Produce = Produce;\n this.Color = Color;\n this.DefaultRouteTo = DefaultRouteTo;\n }\n}","import { Attachment } from \"./attachment\";\nimport { EditionRenditionsInfo } from \"./edition-renditions-info\";\nimport { Element } from \"./element\";\nimport { InDesignArticle } from \"./indesign-article\";\nimport { Message } from \"./message\";\nimport { MessageList } from \"./message-list\";\nimport { MetaData } from \"./metadata\";\nimport { ObjectLabel } from \"./object-label\";\nimport { ObjectOperation } from \"./object-operations\";\nimport { Page } from \"./page\";\nimport { Placement } from \"./placement\";\nimport { Relation } from \"./relation\";\nimport { Target } from \"./target\";\n\nexport class WflObject {\n public __classname__: string = 'Object';\n\n public MetaData: MetaData | null = null;\n\n public Relations: Relation[] | null = null;\n\n public Pages: Page[] | null = null;\n\n public Files: Attachment[] | null = null;\n\n public Messages: Message[] | null = null;\n\n public Elements: Element[] | null = null;\n\n public Targets: Target[] | null = null;\n\n public Renditions: EditionRenditionsInfo[] | null = null;\n\n public MessageList: MessageList | null = null;\n\n public ObjectLabels: ObjectLabel[] | null = null;\n\n public InDesignArticles: InDesignArticle[] | null = null;\n\n public Placements: Placement[] | null = null;\n\n public Operations: ObjectOperation[] | null = null;\n\n constructor(\n params : WflObjectNamedParameters\n ) {\n this.MetaData = params.Metadata ?? null;\n this.Relations = params.Relations ?? null;;\n this.Pages = params.Pages ?? null;;\n this.Files = params.Files ?? null;;\n this.Messages = params.Messages ?? null;;\n this.Elements = params.Elements ?? null;;\n this.Targets = params.Targets ?? null;;\n this.Renditions = params.Renditions ?? null;;\n this.MessageList = params.MessageList ?? null;;\n this.ObjectLabels = params.ObjectLabels ?? null;;\n this.InDesignArticles = params.InDesignArticles ?? null;;\n this.Placements = params.Placements ?? null;;\n this.Operations = params.Operations ?? null;;\n }\n\n}\n\nexport interface WflObjectNamedParameters {\n Metadata?: MetaData\n Relations?: Relation[]\n Pages?: Page[]\n Files?: Attachment[]\n Messages?: Message[]\n Elements?: Element[]\n Targets?: Target[]\n Renditions?: EditionRenditionsInfo[]\n MessageList?: MessageList\n ObjectLabels?: ObjectLabel[]\n InDesignArticles?: InDesignArticle[]\n Placements?: Placement[]\n Operations?: ObjectOperation[]\n}","import { State } from \"./state\";\n\nexport class WorkflowMetaData {\n public __classname__: string = 'WorkflowMetaData';\n\n public Deadline : string | null = null;\n\tpublic Urgency : string | null = null;\n\tpublic Modifier : string | null = null;\n\tpublic Modified : string | null = null;\n\tpublic Creator : string | null = null;\n\tpublic Created : string | null = null;\n\tpublic Comment : string | null = null;\n\tpublic State : State | null = null;\n\tpublic RouteTo : string | null = null;\n\tpublic LockedBy : string | null = null;\n\tpublic Version : string | null = null;\n\tpublic DeadlineSoft : string | null = null;\n\tpublic Rating : number | null = null;\n\tpublic Deletor : string | null = null;\n\tpublic Deleted : string | null = null;\n\n constructor(\n params : WorkflowMetaDataNamedParameters\n ) {\n this.Deadline = params.Deadline ?? null;\n this.Urgency = params.Urgency ?? null;\n this.Modifier = params.Modifier ?? null;\n this.Modified = params.Modified ?? null;\n this.Creator = params.Creator ?? null;\n this.Created = params.Created ?? null;\n this.Comment = params.Comment ?? null;\n this.State = params.State ?? null;\n this.RouteTo = params.RouteTo ?? null;\n this.LockedBy = params.LockedBy ?? null;\n this.Version = params.Version ?? null;\n this.DeadlineSoft = params.DeadlineSoft ?? null;\n this.Rating = params.Rating ?? null;\n this.Deletor = params.Deletor ?? null;\n this.Deleted = params.Deleted ?? null;\n }\n}\n\nexport interface WorkflowMetaDataNamedParameters {\n Deadline? : string \n Urgency? : string \n Modifier? : string \n Modified? : string \n Creator? : string \n Created? : string \n Comment? : string \n State? : State \n RouteTo? : string \n LockedBy? : string \n Version? : string \n DeadlineSoft? : string \n Rating? : number \n Deletor? : string \n Deleted? : string\n}","import { BasicMetaData } from \"../../model/wfl/basic-metadata\";\nimport { Category } from \"../../model/wfl/category\";\nimport { ContentMetaData } from \"../../model/wfl/content-metadata\";\nimport { MetaData } from \"../../model/wfl/metadata\";\nimport { Publication } from \"../../model/wfl/publication\";\nimport { SourceMetaData } from \"../../model/wfl/source-metadata\";\nimport { State } from \"../../model/wfl/state\";\nimport { WflObject } from \"../../model/wfl/wflobject\";\nimport { WorkflowMetaData } from \"../../model/wfl/workflow-metadata\";\n\nexport class WflHelpers { \n /**\n *\n * @param name\n * @param type The object type like 'Article'\n * @param categoryId\n * @param publicationId\n * @param stateId\n *\n * @returns The Workflow object\n */\n static createWflObject(name: string, type : string | undefined, categoryId: string, publicationId: string, stateId: string) : WflObject {\n\n return new WflObject({\n Metadata: new MetaData({\n BasicMetaData: new BasicMetaData({\n Name: name,\n Type: type,\n Publication: new Publication({\n Id : publicationId\n }),\n Category: new Category({ \n Id: categoryId\n })\n }),\n WorkflowMetaData: new WorkflowMetaData({\n State: new State(stateId)\n }),\n }),\n Files: [],\n Relations: []\n });\n }\n}","export class ClientError extends Error {\n constructor(msg: string) {\n super(msg);\n this.name = 'ClientError';\n }\n}\n","import { v4 as uuidv4 } from 'uuid';\nimport { IClient } from './client-interface';\nimport { ClientOptions } from './client-options';\n\nimport { LoggerInterface, } from '@aws-lambda-powertools/logger/types';\nimport { HttpClient } from '../http-client/http-client';\nimport { IHttpClient } from '../http-client/http-client-interface';\nimport { ClientError } from './client-error';\nimport { WflObject } from '../model/wfl/wflobject';\nimport { Relation, RelationType } from '../model/wfl/relation';\nimport { MetaDataValue } from '../model/wfl/metadata-value';\nimport { PropertyValue } from '../model/wfl/property-value';\nimport { Target } from '../model/wfl/target';\n\nimport { BodyInit } from \"undici-types/fetch\";\n\ninterface RegisterRequest {\n Appname: string,\n Url: string,\n Username: string,\n Password: string,\n RequestId: string,\n /**\n * Optional\n */\n ConfigurationId?: string\n}\n\ninterface Responsebase {\n ConfigurationId: string,\n RequestId: string,\n EventSource: string,\n EventDetail: string,\n Status: string,\n StatusMessage?: string,\n Result: any\n}\n\n\n\nexport class Client implements IClient{\n\n private _options: ClientOptions;\n private _logger : LoggerInterface;\n private _httpClient : IHttpClient;\n\n private _studioBaseUrl : string = \"\";\n\n private _publicationsCache : Record<string,any> = {};\n\n get options() {\n return this._options;\n }\n\n /**\n * The configurationId\n */\n private _configurationId: string | null = null;\n\n /**\n * @returns The configurationid\n * @throws QqAwsServiceStudioClientClientError when not logged on\n */\n get configurationId(): string {\n if (this._configurationId === null) {\n throw new ClientError(\"Not logged on\")\n };\n\n return this._configurationId;\n }\n\n /**\n * \n * @param logger The logger instance\n * @param options The Client options\n * @param httpClient The Http client. When not defined an instance will be created automatically.\n */\n constructor(logger : LoggerInterface, options: ClientOptions, httpClient? : IHttpClient) {\n\n console.log(\"Client::constructor\", options);\n \n if (httpClient === undefined) {\n httpClient = new HttpClient(logger);\n }\n\n this._logger = logger;\n this._options = options;\n this._httpClient = httpClient;\n\n this._httpClient.setCommonHeaders( {\n 'User-Agent': 'StudioClient Client',\n 'x-api-key' : this.options.apiKey\n });\n\n this._httpClient.setBaseUrl(options.baseUrl);\n }\n\n private validateOptions(options: ClientOptions) {\n if (options.baseUrl == \"\") {\n throw new ClientError(\"baseUrl is required\");\n }\n }\n\n /**\n * \n * @returns true when logged in\n */\n isLoggedOn(): boolean {\n return this._configurationId !== null;\n }\n\n setStudioBaseUrl(url : string) {\n this._studioBaseUrl = this._sanitizeUrl(url);\n }\n\n /**\n * \n * @param configurationId \n * @returns true when logged in\n */\n async logon(configurationId: string) : Promise<boolean> {\n console.log(`QqAwsServiceStudioClientClient::logon: configurationId=[${configurationId}]`);\n //TODO: Maybe some additional validation here \n\n this._configurationId = configurationId;\n\n return this.isLoggedOn();\n }\n\n\n /**\n * \n * @returns The Woodwing Studio base URL\n */\n getBaseUrl(): string {\n return <string>this._options.baseUrl;\n }\n\n /**\n * @param studioUrl The \n * @param appname The application name\n * @param username The WoodWing Studio username\n * @param password The WoodWing Studio password\n * @param requestId Optional: The requestID \n * @param configurationId Optional: The configurationID\n * @returns The new or given ConfigurationId\n * @throws QqAwsServiceStudioClientClientError when the registration fails.\n */\n async register(studioUrl: string, appname: string, username: string, password: string, requestId: string|undefined, configurationId: string|undefined): Promise<string> {\n if (requestId === undefined) {\n requestId = this._generateRequestId();\n }\n console.log(`QqAwsServiceStudioClientClient::register: studioUrl=[${studioUrl}], appname=[${appname}], username=[${username}], requestId=[${requestId}]`);\n\n const request: RegisterRequest = {\n \"Appname\": appname,\n \"Url\": this._sanitizeUrl(studioUrl),\n \"Username\": username,\n \"Password\": password,\n \"RequestId\": requestId,\n };\n\n if (configurationId !== undefined) {\n if (this._configurationId !== null) {\n request.ConfigurationId = this._configurationId\n }\n request.ConfigurationId = configurationId\n }\n\n const result = await this._httpClient.request('POST', 'studioapplication', undefined, request);\n if ('ConfigurationId' in result) {\n this._configurationId = result.ConfigurationId;\n return result.ConfigurationId;\n }\n\n throw new ClientError(\"No 'ConfigurationId' in response\");\n }\n\n async unRegister(configurationId?: string) : Promise<void> {\n if (configurationId === undefined) {\n configurationId = this.configurationId;\n }\n }\n\n /**\n * \n * @param ids The publication ids to resolve\n * @param requestInfo What elements to retrieve. \"PubChannels\",\"States\", \"Categories\"\n * @param forceNew When true, ignore local cache.\n * @returns All resolved publications \n */\n public async getPublications(ids : string[], requestInfo? : string[], forceNew? : boolean, requestId?: string, configurationId?: string) : Promise<Record<string, any>[]> {\n if(forceNew === undefined) {\n forceNew = false;\n }\n \n console.log(`SqCreatePdf2Client::getPublications: ids=[${ids.join(', ')}], forceNew=[${forceNew}]`);\n let idsToRequest : string[] = [];\n for (const id of ids) {\n if (forceNew === true || !(id in this._publicationsCache)) {\n idsToRequest.push(id);\n } else {\n // Brand already cached\n this._logger.debug(`Brand ${id} already loaded. Check the request info`);\n if (requestInfo !== undefined) {\n for (const requestInfoElement of requestInfo) {\n if (!(requestInfoElement in this._publicationsCache[id])) {\n // The request info element is not cached for this brand\n this._logger.debug(`Brand ${id} already loaded. But ${requestInfoElement} was not requested before.`);\n idsToRequest.push(id);\n break;\n }\n }\n }\n\n }\n }\n\n if(idsToRequest.length > 0) {\n const publications = await this.getPublicationsInt(\n idsToRequest, requestInfo);\n\n for (const publication of publications) {\n const brandId = <string> publication.Id;\n this._publicationsCache[brandId] = publication;\n }\n }\n\n let result : Record<string, any>[] = [];\n for (const id of ids) {\n if (id in this._publicationsCache) {\n result.push(this._publicationsCache[id]);\n }\n }\n\n return result;\n }\n\n /**\n *\n * @param {string} publicationId\n * @returns {Promise<null|object>}\n */\n async getPublication(publicationId : string, requestInfo? : string[] ) {\n\n const publications = await this.getPublications([publicationId], requestInfo);\n \n\n for (let pubIdx in publications) {\n\n const publication = publications[pubIdx];\n\n console.log(\"processing publication: \", publication);\n\n if (publication.Id === publicationId.toString()) {\n return publication;\n }\n }\n\n return null;\n }\n\n /**\n * \n * @param forceNew When true create a new ticket instead of the cached ticket\n * @param requestId \n * @param configurationId \n * @returns \n */\n async getTicket(forceNew? : boolean, requestId?: string, configurationId?: string): Promise<string> {\n if (forceNew === undefined) {\n forceNew = false;\n }\n \n if (requestId === undefined) {\n requestId = this._generateRequestId();\n }\n\n if (configurationId === undefined) {\n configurationId = this.configurationId;\n }\n console.log(`QqAwsServiceStudioClientClient::getTicket: forceNew=[${forceNew}], requestId=[${requestId}], configurationId=[${configurationId}]`);\n\n const path = 'ticket';\n\n const query = new URLSearchParams({\n ConfigurationId: configurationId,\n RequestId: requestId,\n Forcenew: forceNew ? 'true' : 'false'\n })\n\n const result = await this._httpClient.request('GET', path, query);\n\n return result;\n }\n\n /**\n * @inheritdoc\n */\n async getStateByName(publicationId : string, type : string, name : string ) : Promise<null|any> {\n\n const publication = await this.getPublication(publicationId, ['States']);\n\n if (publication === null) {\n return null;\n }\n\n for (const state of publication.States) {\n //const state = publication.States[stateIdx];\n\n if (state.Type.toLowerCase() === type.toLowerCase() && state.Name.toLowerCase() === name.toLowerCase()) {\n return state;\n }\n }\n \n return null;\n }\n\n\n\n\n /**\n *\n * @param wflObject\n * @param childId\n * @param type\n * @param parentType\n * @returns \n */\n async getWflRelations(wflObject : any, childId : string, type : string = 'Contained', parentType : string = 'Dossier') : Promise<object[]> {\n\n let result = [];\n\n for (let relIdx in wflObject.Relations) {\n const relation = wflObject.Relations[relIdx];\n\n if (\n relation.Child === childId &&\n relation.Type.toLowerCase() === type.toLowerCase() &&\n relation.ParentInfo.Type.toLowerCase() === parentType.toLowerCase()\n ) {\n result.push(relation)\n }\n\n }\n\n return result;\n }\n\n // /**\n // *\n // * @param {string} bucket\n // * @param {string} key\n // *\n // * @returns {Promise<object>}\n // */\n // async getDigitalArticle = async(bucket : string, key : string) : Promise<object> => {\n // const s3client = new S3Client({});\n // const response = await s3client.send(new GetObjectCommand(\n // {\n // Bucket: bucket,\n // Key: key\n // }\n // ));\n\n // if (!response.ETag) {\n // throw new Error('Error getting digital article from bucket.');\n // }\n\n // return response;\n // }\n \n /**\n *\n * @param url\n * @returns \n */\n async downloadFile(url : string, query? : URLSearchParams ) : Promise<ArrayBuffer>{\n if (query === undefined) {\n query = new URLSearchParams();\n }\n\n query.append('ticket', await this.getTicket());\n\n const buffer = await this._httpClient.downloadFile(url, query);\n \n return buffer;\n }\n \n \n /**\n * @inheritdoc\n */\n async uploadFile(body : BodyInit, contentType : string, size : number){\n\n if(this._studioBaseUrl === '') {\n throw new ClientError(\"No studio base url set\");\n }\n\n const url = await this._httpClient.uploadFile(body, size, contentType, await this.getTicket(), this._studioBaseUrl )\n\n return url;\n }\n\n /**\n *\n * @param objectIds\n * @param rendition\n * @param requestInfo\n * @param lock\n * @param areas\n * @returns \n */\n async getObjects(\n objectIds : string[], \n rendition : string = 'native', \n requestInfo : string[] = ['MetaData'],\n lock : boolean = false, \n areas : string[] = ['Workflow']\n ) : Promise<WflObject[]> {\n\n const query = this._getCommonQueryParameters();\n query.append('ObjectIds', objectIds.join(','));\n query.append('RequestInfo', requestInfo.join(','));\n query.append('Rendition', rendition);\n\n const response = await this._httpClient.request('get', 'objects', query);\n //TODO: How to convert te result in a WflObject instance.\n return response;\n\n }\n\n async createObjects(wflObjects : WflObject[], lock : boolean = false) : Promise<WflObject[]> {\n\n const body = {\n WflObjects: wflObjects,\n RequestId: this._generateRequestId(),\n ConfigurationId: this.configurationId,\n Lock: lock\n }\n\n const response = await this._httpClient.request('post', 'objects', undefined, body);\n\n return response;\n }\n\n /**\n *\n * @param parentIdOrInstance\n * @param childIdsOrInstances\n * @param type\n * @returns \n */\n async createObjectRelations(\n parentIdOrInstance : string | WflObject, \n childIdsOrInstances : string[]|WflObject[], \n type : RelationType = RelationType.Contained \n ) : Promise<Relation[]> {\n const parentId = this._getObjectId(parentIdOrInstance);\n const childIds : string[] = [];\n\n for(const childIdOrInstance of childIdsOrInstances) {\n const childId = this._getObjectId(childIdOrInstance);\n childIds.push(childId);\n }\n\n let relations = [];\n\n for (const childId of childIds) {\n relations.push(new Relation({\n Parent: parentId,\n Child: childId,\n Type: type\n }));\n }\n\n const body = {\n RequestId : this._generateRequestId(),\n Relations : relations,\n ConfigurationId: this.configurationId\n }\n\n const response = await this._httpClient.request('post','objectrelations', undefined, body);\n return response;\n }\n\n /**\n * \n * @param childIdsOrInstances \n * @param permanent \n * @param areas \n * @returns \n */\n async deleteObjects(childIdsOrInstances : string[] | WflObject[], permanent : boolean = false, areas : string = 'Workflow') : Promise<object> {\n const ids : string[] = [];\n for(const childIdOrInstance of childIdsOrInstances) {\n const childId = this._getObjectId(childIdOrInstance);\n ids.push(childId);\n }\n\n const query = this._getCommonQueryParameters();\n query.append('ObjectIds', ids.join(','));\n query.append('Permanent', '');\n query.append('Areas', areas);\n query.append('RequestId', this._generateRequestId());\n query.append('ConfigurationId', this.configurationId);\n\n const response = await this._httpClient.request('delete', 'objects', query);\n\n return response;\n }\n\n /**\n * \n * @param action Workflow Action type.\n * @param context v10.40 Can be used to provide relevant information based on the dialog circumstances.\n * @param metaData v8.0: MetaData value allows client app to round trip the data.\n * @param targets v8.0: Object's targets. Data contained in Targets allow client app to round trip the data.\n * @param defaultDossier v7.0: Dossier ID: Request to populate the Dossier property. \n * The given Publication and Issue are used to get dossiers (to choose from). If no Issue specified, \n * first one is taken. The dossier ID will be used to set the default value at Dossier property. \n * If DefaultDossier is nil (or left out) no dossier property nor dossiers will be returned.\n * @param parent v7.0: Parent ID: When creating objects that are placed (such as creating articles form layout) the client \n * knows that the object will be placed, but the server does not know yet. For placed objects, \n * the dialog has some fields disabled (greyed) like Publication/Brand, Issue and Category. Nil (or left out) \n * means object is not placed.\n * @param template v7.0: Template ID : When creating objects, some properties should be taken from a template. \n * Those should be pre-filled in for the new object at the Create workflow dialog. Provide the object ID of \n * the template (that was picked by user) to let server pre-fill properties. Nil (or left out) means object \n * is not created from template.\n * @param areas v8.0: Area to search for the object. Nil means 'workflow' area only (for backwards compatibility reasons).\n * @param multipleObjects v9.2: Indicate if the dialog is for multiple objects or single object. \n * Nil means 'false' (for backwards compatibility reasons).\n * @returns \n */\n async getDialog2(\n action : string, \n context? : string, \n metaData? : MetaDataValue[], \n targets? : Target[], \n defaultDossier? : string,\n parent? : string,\n template? : string,\n areas? : string[],\n multipleObjects? : boolean\n ) {\n const body : Record<string, any> = {\n RequestId : this._generateRequestId(),\n ConfigurationId: this.configurationId,\n Action : action\n }\n\n if(context) {\n body['Context'] = context;\n }\n\n if(metaData) {\n //TODO: Must be 'MetaData' (bug in Service)\n body['Metadata'] = metaData;\n }\n\n if(targets) {\n body['Targets'] = targets;\n }\n\n if(defaultDossier) {\n body['DefaultDossier'] = defaultDossier;\n }\n\n if(parent) {\n body['Parent'] = parent;\n }\n\n if(template) {\n body['Template'] = template;\n }\n\n if(areas) {\n body['Areas'] = areas;\n }\n\n if(multipleObjects) {\n body['MultipleObjects'] = multipleObjects;\n }\n\n const response = await this._httpClient.request('post', 'dialog', undefined, body);\n return response;\n }\n\n /**\n * \n * @param ids The brand id(s)\n * @param requestInfo What elements to retrieve. \"PubChannels\",\"States\", \"Categories\"\n * @param requestId \n * @param configurationId \n * @returns \n */\n private async getPublicationsInt(ids: string[], requestInfo? : string[], requestId?: string, configurationId?: string): Promise<Record<string, any>[]> {\n if(requestInfo === undefined) {\n requestInfo = [];\n }\n \n if (requestId === undefined) {\n requestId = this._generateRequestId();\n }\n console.log(`QqAwsServiceStudioClientClient::getPublications: ids=[${ids.join(',')}], requestInfo=[${requestInfo.join(', ')}], requestId=[${requestId}]`);\n\n if (configurationId === undefined) {\n configurationId = this.configurationId;\n }\n \n const query = this._getCommonQueryParameters(configurationId);\n query.append('Ids', ids.join(','));\n query.append('RequestInfo', requestInfo.join(', '));\n\n const result = await this._httpClient.request('GET', 'publications', query);\n return result;\n }\n\n /**\n * Add the ConfigurationId and RequestId to the query\n * \n * \n * @param configurationId Overrule the configurationId when required.\n * @returns \n */\n private _getCommonQueryParameters(configurationId? : string) : URLSearchParams {\n if (configurationId === undefined) {\n configurationId = this.configurationId;\n }\n const query = new URLSearchParams({\n ConfigurationId: configurationId,\n RequestId: this._generateRequestId()\n });\n\n return query;\n }\n\n /**\n * Get the parentId from the iddOrInstance\n *\n * @param iddOrInstance\n * @returns The object id\n * @throws ClientError when the id cannot be determined\n */\n private _getObjectId(idOrInstance : string | WflObject, ) : string {\n if(idOrInstance instanceof WflObject || (\n typeof idOrInstance === 'object' &&\n '__classname__' in idOrInstance &&\n idOrInstance['__classname__'] === 'Object')) {\n const id = idOrInstance.MetaData?.BasicMetaData?.ID;\n if(id === undefined || id === null) {\n throw new ClientError(`childId is undefined`);\n }\n return id;\n } else {\n return idOrInstance;\n }\n }\n\n _sanitizeUrl(url: string): string {\n return url.replace(/\\/$/, \"\");\n }\n\n _generateRequestId() {\n return uuidv4();\n }\n\n\n}","export class HttpError extends Error {\n\n\n\n /**\n *\n * @param {string} message\n */\n constructor(message: string) {\n super(message);\n this.name = \"HttpError\";\n }\n}","import { HttpError } from \"./http-error\";\n\nexport class HttpResponseError extends HttpError {\n\n readonly code: number;\n readonly name: string;\n\n /**\n *\n * @param {Response} response\n */\n constructor(message: string, response: Response) {\n super(HttpResponseError.buildMessage(message, response));\n this.code = response.status;\n this.name = \"HttpResponseError\";\n }\n\n static buildMessage(message : string, response: Response) : string {\n if(message) {\n return `HTTP Error: ${message}: ${response.status} ${response.statusText}`;\n } else {\n return `HTTP Error: ${response.status} ${response.statusText}`;\n }\n }\n}","import { ClientError } from \"../client/client-error\";\nimport { IHttpClient } from \"./http-client-interface\";\nimport { HttpError } from \"./http-error\";\nimport { HttpResponseError } from \"./http-response-error\";\nimport {ResponseBase} from \"./response-base\";\nimport {v4 as uuidv4} from 'uuid';\nimport { LoggerInterface, } from '@aws-lambda-powertools/logger/types';\nimport { BodyInit, HeadersInit } from \"undici-types/fetch\";\n\nexport class HttpClient implements IHttpClient {\n\n \n private headers : Record<string,string> = {}\n\n private baseUrl: string = \".\";\n \n private logger : LoggerInterface;\n\n constructor(logger : LoggerInterface) {\n this.logger = logger;\n }\n\n /**\n * \n * @returns The configuration service base URL\n */\n getBaseUrl(): string {\n return <string>this.baseUrl;\n }\n\n setBaseUrl(baseUrl : string) : void {\n this.baseUrl = baseUrl;\n }\n\n setCommonHeaders(headers : Record<string,string>) : void{\n this.headers = headers;\n }\n\n\n async request(httpMethod: string, path: string, query?: URLSearchParams, body?: any): Promise<any> {\n httpMethod = httpMethod.toUpperCase();\n\n if (query === undefined) {\n query = new URLSearchParams();\n }\n\n const url = this.getBaseUrl() + '/' + path + (query.size > 0 ? '?' + query.toString() : '');\n\n const request: RequestInit = {\n method: httpMethod.toUpperCase(),\n headers: { ...this.headers} // Clone headers\n }\n\n console.log(`HttpClient::_request: httpMethod=[${httpMethod}], url=[${url}]`);\n if (httpMethod === 'POST') {\n this.logger.debug(`HttpClient::_request: body=[${JSON.stringify(body)}]`);\n console.log(\"HttpClient::_request: body:\", body);\n request.body = JSON.stringify(body);\n // @ts-ignore request.Headers is always set.\n request.headers['Content-Type'] = 'application/json';\n }\n\n const response = await fetch(url, request);\n\n let data: ResponseBase | null = null;\n\n const contentType: string = <string>response.headers.get(\"Content-Type\");\n switch (contentType) {\n case \"application/json\":\n data = (await response.json()) as ResponseBase;\n break;\n default:\n throw new HttpResponseError(`Unsupported content type: ${contentType}`, response);\n }\n\n data = this._checkResponse(data);\n\n return data.Result;\n }\n\n\n /**\n *\n * @param url\n * @returns \n */\n async downloadFile(url : string, query?: URLSearchParams) : Promise<ArrayBuffer>{\n if (query === undefined) {\n query = new URLSearchParams();\n } \n\n const parsedUrl = new URL(url)\n\n query.forEach((value, key) => {\n parsedUrl.searchParams.set(key, value);\n });\n\n\n //url = url + (query.size > 0 ? '?' + query.toString() : '');\n url = parsedUrl.toString();\n\n \n const response = await fetch(url);\n\n if (!response.ok) {\n throw new HttpResponseError(\"Object cannot be downloaded from Studio.\", response);\n }\n\n const buffer = await response.arrayBuffer();\n\n console.log(`Downloaded ${buffer.byteLength} bytes`);\n\n return buffer;\n }\n\n /**\n * Upload a file to the Studio transfer server.\n * \n * \n * @param body \n * @param size\n * @param contentType \n * @param ticket \n * @param studiobaseUrl The Studio base url\n *\n * @returns The url to the uploaded file\n */\n async uploadFile(body : BodyInit, size : number | null, contentType : string, ticket : string, studiobaseUrl : string) : Promise<string> {\n this.logger.debug(`HttpClient::uploadFile: ticket=[${ticket}], studiobaseUrl=[${studiobaseUrl}]`)\n\n const url = `${studiobaseUrl}/transferindex.php?ticket=${ticket}&fileguid=${uuidv4()}`;\n\n const headers : HeadersInit = {\n 'Content-Type' : contentType,\n }\n\n if(size !== null) {\n headers['Content-Length'] = String(size);\n }\n\n const response = await fetch(url, {\n method: 'PUT',\n // To prevent the error: RequestInit: duplex option is required when sending a body\n // Note: The order is important!!!! The 'duplex' setting must be set before the body otherwise it will be ignored.\n duplex: 'half',\n body: body,\n headers: headers\n });\n\n if (!response.ok) {\n throw new HttpResponseError('Unable to upload file.',response);\n }\n\n return url;\n }\n\n /**\n * @param {object} data\n * @private\n */\n _checkResponse(data: ResponseBase | null) : ResponseBase {\n console.log(\"HttpClient::_checkResponse: \", data);\n\n if (data === null) {\n throw new HttpError(\"No JSON data received\");\n }\n\n if (data.hasOwnProperty('Status')) {\n if (data.Status !== 'ok') {\n if (data.StatusMessage !== undefined) {\n throw new ClientError(`The status is not 'ok': ${data.Status}: ${data.StatusMessage}`);\n } else {\n throw new ClientError(`The status is not 'ok': ${data.Status}`);\n }\n }\n } else {\n throw new HttpError(\"No 'Status' property found in response\");\n }\n\n if (!data.hasOwnProperty('Result')) {\n throw new HttpError(\"No 'Result' property found in response\");\n }\n\n return data;\n }\n\n _sanitizeUrl(url: string): string {\n return url.replace(/\\/$/, \"\");\n }\n}","import { ObjectInfo } from \"./object-info\";\nimport { ObjectLabel } from \"./object-label\";\nimport { Placement } from \"./placement\";\nimport { Target } from \"./target\";\n\nexport enum RelationType {\n Contained = \"Contained\",\n Placed = \"Placed\",\n DeletedContained = \"DeletedContained\"\n}\n\nexport class Relation {\n public __classname__: string = 'Relation';\n\n public Parent: string | null = null;\n public Child: string | null = null;\n public Type: RelationType | null = null;\n public Placements: Placement[] | null = null;\n public ParentVersion: string | null = null;\n public ChildVersion: string | null = null;\n public Rating: number | null = null;\n public Targets: Target[] | null = null;\n public ParentInfo: ObjectInfo | null = null;\n public ChildInfo: ObjectInfo | null = null;\n public ObjectLabels: ObjectLabel[] | null = null;\n\n constructor(params: RelationNamedParameters) {\n this.Parent = params.Parent ?? null;\n this.Child = params.Child ?? null;\n this.Type = params.Type ?? null;\n this.Placements = params.Placements ?? null;\n this.ParentVersion = params.ParentVersion ?? null;\n this.ChildVersion = params.ChildVersion ?? null;\n this.Rating = params.Rating ?? null;\n this.Targets = params.Targets ?? null;\n this.ParentInfo = params.ParentInfo ?? null;\n this.ChildInfo = params.ChildInfo ?? null;\n this.ObjectLabels = params.ObjectLabels ?? null;\n }\n}\n\nexport interface RelationNamedParameters {\n Parent: string\n Child: string\n Type: RelationType\n Placements?: Placement[]\n ParentVersion?: string\n ChildVersion?: string\n Rating?: number\n Targets?: Target[]\n ParentInfo?: ObjectInfo\n ChildInfo?: ObjectInfo\n ObjectLabels?: ObjectLabel[]\n}","\nexport class ClientOptionError extends Error {\n constructor(message: string, public optionName: string, error?: Error) {\n super(ClientOptionError.buildMessage(message, optionName, error));\n this.name = 'ClientOptionError';\n }\n\n private static buildMessage(message: string, optionName: string, error?: Error) {\n return `${message} (Option '${optionName}')`;\n }\n}","import { ClientOptionError } from \"./client-option-error\";\n\nexport class ClientOptions {\n \n\n constructor() {\n\n }\n\n // -------------------- baseUrl --------------------\n\n private _baseUrl: string | null = null;\n\n /**\n * \n * @throws QqAwsServiceStudioClientClientError When the baseurl is not set\n */\n get baseUrl(): string {\n if (this._baseUrl === null) {\n throw new ClientOptionError(\"Option not set\", 'baseUrl');\n };\n return this._baseUrl;\n }\n\n setBaseUrl(value: string) : ClientOptions {\n // Normalize URL (trailing slash)\n this._baseUrl = value.replace(/\\/$/, \"\");\n return this;\n }\n\n // -------------------- apiKey --------------------\n\n private _apiKey : string | null = null;\n\n /**\n * @returns The apiKey\n * @throws QqAwsServiceStudioClientClientError When the apiKey is not set\n */\n get apiKey(): string {\n if (this._apiKey === null) {\n throw new ClientOptionError(\"Option not set\", 'apiKey');\n };\n return this._apiKey;\n }\n\n /**\n * \n * @param value The API key\n * @returns \n */\n setApiKey(value: string) : ClientOptions {\n this._apiKey = value;\n return this;\n }\n\n}","\nexport class Attachment {\n public __classname__: string = 'Attachment';\n\t\n public Rendition : string | null = null;\n\tpublic Type: string | null = null;\n\tpublic Content: string | null = null;\n\tpublic FilePath: string | null = null;\n\tpublic FileUrl: string | null = null;\n\tpublic EditionId: string | null = null;\n\tpublic ContentSourceFileLink: string | null = null;\n\tpublic ContentSourceProxyLink: string | null = null;\n \n constructor(params : AttachmentNamedParameters) {\n this.Rendition = params.Rendition ?? null;\n this.Type = params.Type ?? null;\n this.Content = params.Content ?? null;\n this.FilePath = params.FilePath ?? null;\n this.FileUrl = params.FileUrl ?? null;\n this.EditionId = params.EditionId ?? null;\n this.ContentSourceFileLink = params.ContentSourceFileLink ?? null;\n this.ContentSourceProxyLink = params.ContentSourceProxyLink ?? null;\n }\n\n}\n\nexport interface AttachmentNamedParameters {\n Rendition?: string,\n Type?: string,\n Content?: string,\n FilePath?: string,\n FileUrl?: string,\n EditionId?: string,\n ContentSourceFileLink?: string,\n ContentSourceProxyLink?: string\n}","\nexport class ContentMetaData {\n public __classname__: string = 'ContentMetaData';\n\n public Description : string | null = null;\n\tpublic DescriptionAuthor: string | null = null;\n\tpublic Keywords: string[] | null = null;\n\tpublic Slugline: string | null = null;\n\tpublic Format: string | null = null;\n\tpublic Columns: number | null = null;\n\tpublic Width: number | null = null;\n\tpublic Height: number | null = null;\n\tpublic Dpi: number | null = null;\n\tpublic LengthWords: number | null = null;\n\tpublic LengthChars: number | null = null;\n\tpublic LengthParas: number | null = null;\n\tpublic LengthLines: number | null = null;\n\tpublic PlainContent: string | null = null;\n\tpublic FileSize: number | null = null;\n\tpublic ColorSpace: string | null = null;\n\tpublic HighResFile: string | null = null;\n\tpublic Encoding: string | null = null;\n\tpublic Compression: string | null = null;\n\tpublic KeyFrameEveryFrames: number | null = null;\n\tpublic Channels: string | null = null;\n\tpublic AspectRatio: string | null = null;\n\tpublic Orientation: number | null = null;\n\tpublic Dimensions: string | null = null;\n\n constructor(params : ContentMetaDataNamedParameters) {\n this.Description = params.Description ?? null;\n this.DescriptionAuthor = params.DescriptionAuthor ?? null;\n this.Keywords = params.Keywords ?? null;\n this.Slugline = params.Slugline ?? null;\n this.Format = params.Format ?? null;\n this.Columns = params.Columns ?? null;\n this.Width = params.Width ?? null;\n this.Height = params.Height ?? null;\n this.Dpi = params.Dpi ?? null;\n this.LengthWords = params.LengthWords ?? null;\n this.LengthChars = params.LengthChars ?? null;\n this.LengthParas = params.LengthParas ?? null;\n this.LengthLines = params.LengthLines ?? null;\n this.PlainContent = params.PlainContent ?? null;\n this.FileSize = params.FileSize ?? null;\n this.ColorSpace = params.ColorSpace ?? null;\n this.HighResFile = params.HighResFile ?? null;\n this.Encoding = params.Encoding ?? null;\n this.Compression = params.Compression ?? null;\n this.KeyFrameEveryFrames = params.KeyFrameEveryFrames ?? null;\n this.Channels = params.Channels ?? null;\n this.AspectRatio = params.AspectRatio ?? null;\n this.Orientation = params.Orientation ?? null;\n this.Dimensions = params.Dimensions ?? null;\n }\n}\n\nexport interface ContentMetaDataNamedParameters{\n Description? : string \n DescriptionAuthor? : string \n Keywords? : string[] \n Slugline? : string \n Format? : string \n Columns? : number \n Width? : number \n Height? : number \n Dpi? : number\n LengthWords? : number \n LengthChars? : number \n LengthParas? : number \n LengthLines? : number \n PlainContent? : string \n FileSize? : number \n ColorSpace? : string \n HighResFile? : string \n Encoding? : string \n Compression? : string \n KeyFrameEveryFrames? : number \n Channels? : string \n AspectRatio? : string \n Orientation? : number \n Dimensions? : string \n}","import { Edition } from \"./edition\";\nimport { RenditionTypeInfo } from \"./rendition-type-info\";\n\nexport class EditionRenditionsInfo {\n public __classname__: string = 'EditionRenditionsInfo';\n\n\tpublic $Edition : Edition | null = null;\n\tpublic $Renditions : RenditionTypeInfo | null = null;\n\n constructor(\n $Edition: Edition | null = null,\n $Renditions: RenditionTypeInfo | null = null\n ) {\n this.$Edition = $Edition;\n this.$Rendit