UNPKG

@eddye68/studio-client

Version:

The AWS service Studio client

1 lines 59.9 kB
{"version":3,"sources":["../../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"],"sourcesContent":["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}"],"mappings":"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