diff --git a/CHANGELOG.md b/CHANGELOG.md index bbceeed8c..ccc4c9010 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,13 +12,22 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). * Added requirement that Standard versions SHOULD avoid the use unions in context and API definitions wherever possible as these can be hard to replicate and MUST avoid unions of primitive types as these can be impossible to replicate in other languages. ([#120](https://github.com/finos/FDC3/pull/1200)) * Added `addEventListener` to the `DesktopAgent` API to provide support for event listener for non-context and non-intent events, including a `userChannelChanged` event ([#1207](https://github.com/finos/FDC3/pull/1207)) * Added an `async` `addEventListener` function to the `PrivateChannel` API to replace the deprecated, synchronous `onAddContextListener`, `onUnsubscribe` and `onDisconnect` functions and to keep consistency with the DesktopAgent API. ([#1305](https://github.com/finos/FDC3/pull/1305)) +* Added reference materials and supported platforms information for FDC3 in .NET via the [finos/fdc3-dotnet](https://github.com/finos/fdc3-dotnet) project. ([#1108](https://github.com/finos/FDC3/pull/1108)) +* Specifications for getAgent() and Browser-Resident Desktop Agents. +* Specification for Preload Desktop Agents. This content was previously in the supported platforms section. It had been revised and amended to include recommended behavior related to the new validateAppIdentity() function. +* Added optional validateAppIdentity() function to DesktopAgent interface. +* Typescript definitions for getAgent() and related types +* Typescript definitions for Browser Communication Protocol (BCP). These constitute the internal "wire protocol" that the "@finos/fdc3" library uses to communicate with Browser-Resident DAs. +* Typescript definitions for Web Connection Protocol (WCP). These constitute the messages used to establish connectivity between "@finos/fdc3" and a Browser-Resident DA. * Added support for broadcast actions to the `fdc3.action` context type, allowing an Action to represent the broadcast of a specified context to an app or user channel. ([#1368](https://github.com/finos/FDC3/pull/1368)) ### Changed +* `window.fdc3` is now an optional property and may or may not be defined. Applications should now use `getAgent()` as the recommended way of retrieving a reference to the FDC3 API. ([#1386](https://github.com/finos/FDC3/pull/1386)) * `Listener.unsubscribe()` was made async (the return type was changed from `void` to `Promise`) for consistency with the rest of the API. ([#1305](https://github.com/finos/FDC3/pull/1305)) * Added reference materials and supported platforms information for FDC3 in .NET via the [finos/fdc3-dotnet](https://github.com/finos/fdc3-dotnet) project. ([#1108](https://github.com/finos/FDC3/pull/1108)) * The supported platforms page in the FDC3 documentation was moved into the API section as the information it provides all relates to FDC3 Desktop Agent API implementations. ([#1108](https://github.com/finos/FDC3/pull/1108)) +* FDC3 apps are now encouraged to instantiate their FDC3 interface (DesktopAgent) using the `getAgent()` function provided by the `@finos/fdc3` module. This will allow apps to interoperate in either traditional Preload DAs (i.e. Electron) as well as the new Browser-Resident DAs. ### Deprecated @@ -70,7 +79,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). * Updated definition of the `otherConfig` element of the `Chart` context type from an Object to an array of Contexts as this allows the `type` of each additional item of config to be examined before it is used ([#985](https://github.com/finos/FDC3/pull/985)) * Corrected the appD `interop.appChannels` metadata to use an `id` field to identify channels, rather than `name` ([#981](https://github.com/finos/FDC3/pull/981)) * The App Directory OpenAPI schema was converted from YAML to JSON Schema, containing the same definitions. ([#1035](https://github.com/finos/FDC3/pull/1035)) -* Switched to union types (from enums) for constrained string values in generated source files as they provide better type checking and cross-compatability of types. ([#1093](https://github.com/finos/FDC3/pull/1093)) +* Switched to union types (from enums) for constrained string values in generated source files as they provide better type checking and cross-compatibility of types. ([#1093](https://github.com/finos/FDC3/pull/1093)) ### Deprecated @@ -86,7 +95,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). * Further clarified the difference between the behavior of User channels and other channel types on joinUserChannel/addContextListener. ([#971](https://github.com/finos/FDC3/pull/971)) * Clarified description of the behavior of `IntentResolution.getResult()` when the intent handler returned void (which is not an error). ([#1004](https://github.com/finos/FDC3/pull/1004)) * An error was fixed in the appD schema where launch details sub-schemas were combined with `oneOf`, rather than `anyOf`. This causes validation errors for web or online native apps as their details elements overlap on a `url` field. ([#1034](https://github.com/finos/FDC3/pull/1034)) -* The appD `icon` and `screenshot` sub-schemas were updated to require the `src` value is set and restrict additional values, ensuring that common mistakes (such as ussing a `url` rather than `src` field are caught by the schemas when used to validate. ([#1037](https://github.com/finos/FDC3/pull/1037)) +* The appD `icon` and `screenshot` sub-schemas were updated to require the `src` value is set and restrict additional values, ensuring that common mistakes (such as using a `url` rather than `src` field are caught by the schemas when used to validate. ([#1037](https://github.com/finos/FDC3/pull/1037)) * Linting, spell checking other corrections were applied to markdown syntax throughout the FDC3 documentation ([#1032](https://github.com/finos/FDC3/pull/1032)) * Corrected bad example URLs in the App Directory overview/discovery page in the current and past versions as they did not agree with the paths provided in the API specification and OpenAPI schema. ([#1060](https://github.com/finos/FDC3/pull/1060)) @@ -114,8 +123,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). * Added a field to specify the Context type that intent can return to the AppD Application schema and extended the findIntent API calls to be able to use it for resolution. ([#499](https://github.com/finos/FDC3/pull/499)) * Added the ability to return a Channel from an intent (via the `IntentResult` type), resolver support for intents that return Channels and the concept of PrivateChannels. ([#508](https://github.com/finos/FDC3/pull/508)) * Added error `UserCancelled` to the `ResolveError` enumeration to be used when user closes the resolver UI or otherwise cancels resolution of a raised intent ([#522](https://github.com/finos/FDC3/pull/522)) -* Added `IntentDeliveryFailed` to the `ResolveError` enumeration to be used when delivery of an intent and context to a targetted app or instance fails. ([#601](https://github.com/finos/FDC3/pull/601)) -* Added an `instanceId` (and optional `instanceMetadata`) field to `AppMetadata` allowing it to refer to specific app instances and thereby supporting targetting of intents to specific app instances. Also added a `findInstances()` function to the desktop agent and `TargetAppUnavailable` and `TargetInstanceUnavailable` Errors to the `ResolveError` enumeration. ([#509](https://github.com/finos/FDC3/pull/509)) +* Added `IntentDeliveryFailed` to the `ResolveError` enumeration to be used when delivery of an intent and context to a targeted app or instance fails. ([#601](https://github.com/finos/FDC3/pull/601)) +* Added an `instanceId` (and optional `instanceMetadata`) field to `AppMetadata` allowing it to refer to specific app instances and thereby supporting targeting of intents to specific app instances. Also added a `findInstances()` function to the desktop agent and `TargetAppUnavailable` and `TargetInstanceUnavailable` Errors to the `ResolveError` enumeration. ([#509](https://github.com/finos/FDC3/pull/509)) * Added a References and Bibliography section to the Standard's documentation to hold links to 'normative references' and other documentation that is useful for understanding the standard ([#530](https://github.com/finos/FDC3/pull/530)) * Added a Trademarks page to website to acknowledge trademarks used within the Standard not owned by FINOS or the Linux Foundation ([#534](https://github.com/finos/FDC3/pull/534)) * Added details of FDC3's existing versioning and deprecation policies to the FDC3 compliance page ([#539](https://github.com/finos/FDC3/pull/539)) @@ -143,7 +152,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). * Added `categories` field and recommended categories list to AppD application records to enable category based browsing of AppDs ([#673](https://github.com/finos/FDC3/pull/673)) * Added an `interop` field to AppD application records, replacing the `intents` field, to more fully describe an app's use of FDC3 and enable search for apps that 'interoperate' with a selected app ([#697](https://github.com/finos/FDC3/pull/697)) * Added `AppIdentifier` type, which is a new parent of `AppMetadata` and clarifies required fields for API call parameters which now prefer `appId` and `instanceId` over `name` ([#722](https://github.com/finos/FDC3/pull/722)) -* Added a `getAppMetdata()` function to the desktop agent that can be used to retrieve the full `AppMetadata` for an `AppIdentifier` and reduced types such as `IntentResolution.source` and `ContextMetadata.source` from `AppMetadata` to `AppIdentifier` to clarify what fields a developer can rely on and that they should manually retrieve the full `AppMetadata` when they need it for display purposes. ([#751](https://github.com/finos/FDC3/pull/751)) +* Added a `getAppMetadata()` function to the desktop agent that can be used to retrieve the full `AppMetadata` for an `AppIdentifier` and reduced types such as `IntentResolution.source` and `ContextMetadata.source` from `AppMetadata` to `AppIdentifier` to clarify what fields a developer can rely on and that they should manually retrieve the full `AppMetadata` when they need it for display purposes. ([#751](https://github.com/finos/FDC3/pull/751)) ### Changed @@ -248,7 +257,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Added * Build an npm package with exported TypeScript typings for API, Context Data and `window.fdc3` global ([#252](https://github.com/finos/FDC3/pull/252)) -* Export helper enums for names of standardised `Intents` and `ContextTypes` ([#264](https://github.com/finos/FDC3/pull/264)) +* Export helper enums for names of standardized `Intents` and `ContextTypes` ([#264](https://github.com/finos/FDC3/pull/264)) * Export API operations as ES6 functions that can be directly imported ([#266](https://github.com/finos/FDC3/pull/266)) * Check for the existence of `window.fdc3` in ES6 functions, and reject or throw if not defined ([#356](https://github.com/finos/FDC3/pull/356)) @@ -318,13 +327,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Changed * General cleanup of spelling, grammar and punctuation ([#34](https://github.com/finos/FDC3/pull/34)) -* Use cases callout on website landing page ([#54](https://github.com/finos/FDC3/pull/54)) +* Use cases call-out on website landing page ([#54](https://github.com/finos/FDC3/pull/54)) * Proofreading of docs ([#62](https://github.com/finos/FDC3/pull/62)) ### Fixed * Remove unnecessary dates from use case file names ([#41](https://github.com/finos/FDC3/pull/41)) -* Header colouring on responsive website ([#56](https://github.com/finos/FDC3/pull/56)) +* Header coloring on responsive website ([#56](https://github.com/finos/FDC3/pull/56)) * Workflow numbers in Use Case 1 ([#60](https://github.com/finos/FDC3/pull/60)) * Examples in Intent Overview ([#65](https://github.com/finos/FDC3/pull/65)) * Errors in DesktopAgent API Reference ([#66](https://github.com/finos/FDC3/pull/66)) diff --git a/docs/agent-bridging/spec.md b/docs/agent-bridging/spec.md index 78dc2f3f9..09e6e54fd 100644 --- a/docs/agent-bridging/spec.md +++ b/docs/agent-bridging/spec.md @@ -43,9 +43,9 @@ In any Desktop Agent Bridging scenario, it is expected that each DA is being ope The Desktop Agent Bridging Part of the FDC3 Standard is composed of three components: -- **[Connection](#connection)**: A means for Desktop Agents to communicate with a bridge, and through that bridge, with each other. -- **[Connection Protocol](#connection-protocol)**: A protocol defining message exchanges necessary to connect to a Bridge and to perform initial state synchronization. -- **[Messaging Protocol](#messaging-protocol)**: A protocol defining message exchanges that allow FDC3 API interop to extend across multiple Desktop Agents. +- **[Bridge Connection](#connection)**: A means for Desktop Agents to communicate with a bridge, and through that bridge, with each other. +- **[Bridge Connection Protocol (BCP)](#bridge-connection-protocol)**: A protocol defining message exchanges necessary to connect to a Bridge and to perform initial state synchronization. +- **[Bridge Messaging Protocol (BMP)](#bridge-messaging-protocol)**: A protocol defining message exchanges that allow FDC3 API interop to extend across multiple Desktop Agents. Detail on each of these components is defined in the following sections. @@ -69,7 +69,7 @@ Agent Bridging is introduced in FDC3 2.1 as an [@experimental](../fdc3-complianc ### JSON Message Protocol & JSON Schema -The connection and messaging protocols that the Desktop Agent Bridging Part defines are based on messages encoded in JSON. [JSON Schema](https://json-schema.org/) is used to define the format of each message in the protocol and should be considered the 'source of truth' for each and may be used to validate that individual messages are in the correct format. However, examples are provided in the documentation in TypeScript and JavaScript formats for convenience. TypeScript interfaces for individual messages, included in the FDC3 NPM module, are generated from the JSON Schema source files using [quicktype](https://quicktype.io/). +The Bridge Connection Protocol (BCP) and Bridge Messaging Protocols (BMP) that the Desktop Agent Bridging Part defines are based on messages encoded in JSON. [JSON Schema](https://json-schema.org/) is used to define the format of each message in the protocol and should be considered the 'source of truth' for each and may be used to validate that individual messages are in the correct format. However, examples are provided in the documentation in TypeScript and JavaScript formats for convenience. TypeScript interfaces for individual messages, included in the FDC3 NPM module, are generated from the JSON Schema source files using [quicktype](https://quicktype.io/). ## Connection @@ -156,7 +156,7 @@ Both DAs and bridge implementations SHOULD support at least connection to the re As the bridge binds its websocket on the loopback address (127.0.0.1) it cannot be connected to from another device. Hence, an instance of the standalone bridge may be run on each device and those instances exchange messages by other means in order to implement the bridge cross-device. -## Connection Protocol +## Bridge Connection Protocol On connection to the bridge's websocket, a handshake must be completed that may include an authentication step before a name is assigned to the Desktop Agent for use in routing messages. The purpose of the handshake is to allow: @@ -435,7 +435,7 @@ Desktop Agents SHOULD provide visual feedback to end users when they or other ag Although not part of the connection protocol, it should be noted that the `connectedAgentsUpdate` message sent in step 6 should also be sent whenever an agent disconnects from the bridge to update other agents. If any agents remain connected, then the `channelState` does not change and can be omitted. However, if the last agent disconnects the bridge SHOULD discard its internal `channelState`, instead of issuing the update. -## Messaging Protocol +## Bridge Messaging Protocol In order for Desktop Agents to communicate with the Desktop Agent Bridge and thereby other Desktop Agents, a messaging protocol is required. FDC3 supports both 'fire and forget' interactions (such as the broadcast of context messages) and interactions with specific responses (such as raising intents and returning a resolution and optional result), both of which must be handled by that messaging protocol and message formats it defines, as described in this section. @@ -836,7 +836,7 @@ And an error enumeration is created for errors related to bridging that may occu ```typescript enum BridgingError { /** Returned if a Desktop Agent did not return a response, via Desktop Agent Bridging, - * within the alloted timeout. */ + * within the allotted timeout. */ ResponseTimedOut = 'ResponseToBridgeTimedOut', /** Returned if a Desktop Agent that has been targeted by a particular request has * been disconnected from the Bridge before a response has been received from it. */ @@ -1006,7 +1006,7 @@ However, `PrivateChannel` instances allow the registration of additional event h #### Message Schemas and generated sources -JSONSchema definitions are provided for all Desktop Agent Bridging message exchanges (see links in each reference page), which may be used to validate the correct generation of messages to or from a bridge (a separate schema is provided for the agent and bridge versions of each message). +JSONSchema definitions are provided for all Desktop Agent Bridging message exchanges defined by the Bridge Messaging Protocol (see links in each reference page), which may be used to validate the correct generation of messages to or from a bridge (a separate schema is provided for the agent and bridge versions of each message). The JSONSchema definitions are also used to generate TypeScript interfaces for the messages to aid in implementation of a Desktop Agent Bridge or client library. These may be imported from the FDC3 npm module: diff --git a/docs/api/ref/Errors.md b/docs/api/ref/Errors.md index 6ce1b39ae..963b179fd 100644 --- a/docs/api/ref/Errors.md +++ b/docs/api/ref/Errors.md @@ -5,10 +5,44 @@ title: Errors import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -FDC3 API operations may sometimes result in an error, which must be returned to the caller. Errors should be returned by rejecting the promise returned by the API with a JavaScript `Error` object (or equivalent for the language of the implementation). The `Error` Object's message should be chosen from the appropriate Error enumeration below. +FDC3 API operations may sometimes result in an error that is returned to the caller. Errors MUST be returned by rejecting the promise returned by the API with a JavaScript `Error` object (or equivalent for the language of the implementation). The `Error` Object's message should be chosen from the appropriate Error enumeration below. + +## `AgentError` + +Contains constants representing the errors that can be encountered when calling the [`getAgent`](getAgent) function to establish connectivity to a Desktop Agent. Primarily used with web applications, but may also be used in other language implementations. + + + + +```ts +enum AgentError { + /** Returned if no Desktop Agent was found by any means available or + * if the Agent previously connected to is not contactable on a + * subsequent connection attempt.*/ + AgentNotFound = "AgentNotFound", + + /** Returned if validation of the app identity by the Desktop Agent + * Failed or the app is not being allowed to connect to the Desktop Agent + * for another reason. */ + AccessDenied = "AccessDenied", + + /** Returned if an error or exception occurs while trying to set + * up communication with a Desktop Agent. */ + ErrorOnConnect = "ErrorOnConnect", + + /** Returned if either the failover function itself, or what it returned, + * was not the right type. */ + InvalidFailover = "InvalidFailover", +} +``` + + + ## `ChannelError` +Contains constants representing the errors that can be encountered when calling channels using the [`joinUserChannel`](DesktopAgent#joinuserchannel) or [`getOrCreateChannel`](DesktopAgent#getorcreatechannel) methods, or the [`getCurrentContext`](Channel#getcurrentcontext), [`broadcast`](Channel#broadcast) or [`addContextListener`](Channel#addcontextlistener) methods on the `Channel` object. + @@ -17,24 +51,24 @@ enum ChannelError { /** Returned if the specified channel is not found when attempting to join a * channel via the `joinUserChannel` function of the DesktopAgent (`fdc3`). */ - NoChannelFound = 'NoChannelFound', + NoChannelFound = "NoChannelFound", /** SHOULD be returned when a request to join a user channel or to a retrieve * a Channel object via the `joinUserChannel` or `getOrCreateChannel` methods * of the DesktopAgent (`fdc3`) object is denied. */ - AccessDenied = 'AccessDenied', + AccessDenied = "AccessDenied", /** SHOULD be returned when a channel cannot be created or retrieved via the * `getOrCreateChannel` method of the DesktopAgent (`fdc3`). */ - CreationFailed = 'CreationFailed', + CreationFailed = "CreationFailed", /** Returned if a call to the `broadcast` functions is made with an invalid * context argument. Contexts should be Objects with at least a `type` field * that has a `string` value. */ - MalformedContext = 'MalformedContext', + MalformedContext = "MalformedContext", } ``` @@ -75,8 +109,6 @@ public static class ChannelError -Contains constants representing the errors that can be encountered when calling channels using the [`joinUserChannel`](DesktopAgent#joinuserchannel) or [`getOrCreateChannel`](DesktopAgent#getorcreatechannel) methods, or the [`getCurrentContext`](Channel#getcurrentcontext), [`broadcast`](Channel#broadcast) or [`addContextListener`](Channel#addcontextlistener) methods on the `Channel` object. - **See also:** - [`DesktopAgent.createPrivateChannel`](DesktopAgent#createprivatechannel) @@ -88,36 +120,38 @@ Contains constants representing the errors that can be encountered when calling ## `OpenError` +Contains constants representing the errors that can be encountered when calling the [`open`](DesktopAgent#open) method on the [DesktopAgent](DesktopAgent) object. + ```ts enum OpenError { /** Returned if the specified application is not found.*/ - AppNotFound = 'AppNotFound', + AppNotFound = "AppNotFound", /** Returned if the specified application fails to launch correctly.*/ - ErrorOnLaunch = 'ErrorOnLaunch', + ErrorOnLaunch = "ErrorOnLaunch", /** Returned if the specified application launches but fails to add a context * listener in order to receive the context passed to the `fdc3.open` call. */ - AppTimeout = 'AppTimeout', + AppTimeout = "AppTimeout", /** Returned if the FDC3 desktop agent implementation is not currently able * to handle the request. */ - ResolverUnavailable = 'ResolverUnavailable', + ResolverUnavailable = "ResolverUnavailable", /** Returned if a call to the `open` function is made with an invalid * context argument. Contexts should be Objects with at least a `type` field * that has a `string` value. */ - MalformedContext = 'MalformedContext', + MalformedContext = "MalformedContext", /** @experimental Returned if the specified Desktop Agent is not found, via a connected * Desktop Agent Bridge. */ - DesktopAgentNotFound = 'DesktopAgentNotFound', + DesktopAgentNotFound = "DesktopAgentNotFound", } ``` @@ -161,14 +195,14 @@ public static class OpenError -Contains constants representing the errors that can be encountered when calling the [`open`](DesktopAgent#open) method on the [DesktopAgent](DesktopAgent) object. - **See also:** - [`DesktopAgent.open`](DesktopAgent#open) ## `ResolveError` +Contains constants representing the errors that can be encountered when calling the [`findIntent`](DesktopAgent#findintent), [`findIntentsByContext`](DesktopAgent#findintentsbycontext), [`raiseIntent`](DesktopAgent#raiseintent) or [`raiseIntentForContext`](DesktopAgent#raiseintentforcontext) methods on the [DesktopAgent](DesktopAgent). + @@ -177,49 +211,49 @@ export enum ResolveError { /** SHOULD be returned if no apps are available that can resolve the intent * and context combination. */ - NoAppsFound = 'NoAppsFound', + NoAppsFound = "NoAppsFound", /** Returned if the FDC3 desktop agent implementation is not currently able * to handle the request. */ - ResolverUnavailable = 'ResolverUnavailable', + ResolverUnavailable = "ResolverUnavailable", /** Returned if the user cancelled the resolution request, for example by * closing or cancelling a resolver UI. */ - UserCancelled = 'UserCancelledResolution', + UserCancelled = "UserCancelledResolution", /** SHOULD be returned if a timeout cancels an intent resolution that * required user interaction. Please use `ResolverUnavailable` instead for * situations where a resolver UI or similar fails. */ - ResolverTimeout = 'ResolverTimeout', + ResolverTimeout = "ResolverTimeout", /** Returned if a specified target application is not available or a new * instance of it cannot be opened. */ - TargetAppUnavailable = 'TargetAppUnavailable', + TargetAppUnavailable = "TargetAppUnavailable", /** Returned if a specified target application instance is not available, * for example because it has been closed. */ - TargetInstanceUnavailable = 'TargetInstanceUnavailable', + TargetInstanceUnavailable = "TargetInstanceUnavailable", /** Returned if the intent and context could not be delivered to the selected * application or instance, for example because it has not added an intent * handler within a timeout. */ - IntentDeliveryFailed = 'IntentDeliveryFailed', + IntentDeliveryFailed = "IntentDeliveryFailed", /** Returned if a call to one of the `raiseIntent` functions is made with an * invalid context argument. Contexts should be Objects with at least a `type` * field that has a `string` value. */ - MalformedContext = 'MalformedContext', + MalformedContext = "MalformedContext", /** @experimental Returned if the specified Desktop Agent is not found, via a connected * Desktop Agent Bridge. */ - DesktopAgentNotFound = 'DesktopAgentNotFound', + DesktopAgentNotFound = "DesktopAgentNotFound", } ``` @@ -285,8 +319,6 @@ public static class ResolveError -Contains constants representing the errors that can be encountered when calling the [`findIntent`](DesktopAgent#findintent), [`findIntentsByContext`](DesktopAgent#findintentsbycontext), [`raiseIntent`](DesktopAgent#raiseintent) or [`raiseIntentForContext`](DesktopAgent#raiseintentforcontext) methods on the [DesktopAgent](DesktopAgent). - **See also:** - [`DesktopAgent.findIntent`](DesktopAgent#findintent) @@ -296,6 +328,8 @@ Contains constants representing the errors that can be encountered when calling ## `ResultError` +Contains constants representing the errors that can be encountered when calling the [`getResult`](DesktopAgent#findintent) method on the [IntentResolution](Metadata#intentresolution) Object. + @@ -304,12 +338,12 @@ enum ResultError { /** Returned if the intent handler exited without returning a valid result * (a promise resolving to a Context, Channel object or void). */ - NoResultReturned = 'NoResultReturned', + NoResultReturned = "NoResultReturned", /** Returned if the `IntentHandler` function processing the raised intent * throws an error or rejects the Promise it returned. */ - IntentHandlerRejected = 'IntentHandlerRejected', + IntentHandlerRejected = "IntentHandlerRejected", } ``` @@ -336,8 +370,6 @@ public static class ResultError -Contains constants representing the errors that can be encountered when calling the [`getResult`](DesktopAgent#findintent) method on the [IntentResolution](Metadata#intentresolution) Object. - **See also:** - [`DesktopAgent.addIntentListener`](DesktopAgent#addintentlistener) @@ -346,7 +378,7 @@ Contains constants representing the errors that can be encountered when calling ## `BridgingError` -`@experimental` +[`@experimental`](../../fdc3-compliance#experimental-features) @@ -354,21 +386,24 @@ Contains constants representing the errors that can be encountered when calling ```ts enum BridgingError { /** @experimental Returned if a Desktop Agent did not return a response, via - * Desktop Agent Bridging, within the alloted timeout. */ - ResponseTimedOut = 'ResponseToBridgeTimedOut', + * Desktop Agent Bridging, within the allotted timeout. */ + ResponseTimedOut = "ResponseToBridgeTimedOut", + /** @experimental Returned if a Desktop Agent that has been targeted by a * particular request has been disconnected from the Bridge before a * response has been received from it. */ - AgentDisconnected = 'AgentDisconnected', + AgentDisconnected = "AgentDisconnected", + /** @experimental Returned for FDC3 API calls that are specified with * arguments indicating that a remote Desktop agent should be targeted * (e.g. raiseIntent with an app on a remote DesktopAgent targeted), * when the local Desktop Agent is not connected to a bridge. */ - NotConnectedToBridge = 'NotConnectedToBridge', + NotConnectedToBridge = "NotConnectedToBridge", + /** @experimental Returned if a message to a Bridge deviates from the schema * for that message sufficiently that it could not be processed. */ - MalformedMessage = 'MalformedMessage' + MalformedMessage = "MalformedMessage", } ``` diff --git a/docs/api/ref/GetAgent.md b/docs/api/ref/GetAgent.md new file mode 100644 index 000000000..a2fd80b8e --- /dev/null +++ b/docs/api/ref/GetAgent.md @@ -0,0 +1,235 @@ +--- +id: GetAgent +sidebar_label: GetAgent +title: GetAgent +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +The `getAgent()` function is the recommended way for **web applications** to connect to an FDC3 Desktop Agent. The function is exported by the [`@finos/fdc3`](https://www.npmjs.com/package/@finos/fdc3) NPM module and returns a [Desktop Agent](./DesktopAgent) implementation: + + + + +```ts +import { getAgent, DesktopAgent, AgentError } from "@finos/fdc3"; + +try { + const desktopAgent: DesktopAgent = await getAgent(); + //do FDC3 things here +} catch (e: AgentError) { + // Failed to connect +} +``` + + + + +```js +import { getAgent } from "@finos/fdc3"; + +try { + const desktopAgent = await getAgent(); + //do FDC3 things here +} catch (e) { + // Failed to connect +} +``` + + + + +The `getAgent()` function allows web applications to retrieve an FDC3 Desktop Agent API interface to work with, whether they are running in an environment that supports a Desktop Agent Preload (a container-injected API implementation) or a Desktop Agent Proxy (a Browser-based Desktop Agent running in another window or frame). The behavior of `getAgent()` is defined by the [FDC3 Web Connection Protocol (WCP)](../specs/webConnectionProtocol) and communication with a Desktop Agent Proxy in a web-browser is defined by the [Desktop Agent Communication Protocol (DACP)](../specs/desktopAgentCommunicationProtocol). Hence, it allows applications to be written that will work in either scenario without modification or the inclusion of vendor-specific libraries. + +To handle situations where no Desktop Agent is found, a failover function may be supplied by an app allowing it to start or otherwise connect to a Desktop Agent (e.g. by loading a proprietary adaptor that returns a `DesktopAgent` implementation or by creating a window or iframe of its own that will provide a Desktop Agent Proxy). + +The definition of the `getAgent()` function is as follows: + +```ts +type GetAgentType = ( + params?: GetAgentParams, +) => Promise; +``` + +A small number of arguments are accepted that can affect the behavior of `getAgent` and to provide a fallback in case a Desktop Agent is not found, allowing the application to start its own agent or use another mechanism (such as a proprietary adaptor) to connect to one. + +```ts +/** + * @typedef {Object} GetAgentParams Type representing parameters passed to the + * getAgent function. + * + * @property {number} timeoutMs Number of milliseconds to allow for an FDC3 + * implementation to be found before calling the failover function or + * rejecting (default 750). Note that the timeout is cancelled as soon as a + * Desktop Agent is detected. There may be additional set-up steps to perform + * which will happen outside the timeout. + * + * @property {string} identityUrl The app's current URL is normally sent to + * a web-based desktop agent to help establish its identity. This property + * may be used to override the URL sent (to handle situations where an app's + * URL is not sufficiently stable to use for identity purposes, e.g. due to + * client-side route changes when navigating within the app). The URL set MUST + * match the origin of the application (scheme, hostname, and port) or it will + * be ignored. If not specified, the app's current URL will be used. + * + * @property {boolean} channelSelector Flag indicating that the application + * needs access to a channel selector UI (i.e. because it supports User Channels + * and does not implement its own UI for selecting channels). Defaults to + * `true`. MAY be ignored by Desktop Agent Preload (container) implementations. + * + * @property {boolean} intentResolver Flag indicating that the application + * needs access to an intent resolver UI (i.e. because it supports raising one + * or more intents and and does not implement its own UI for selecting target + * apps). Defaults to `true`. MAY be ignored by Desktop Agent Preload (container) + * implementations. + * + * @property {boolean} dontSetWindowFdc3 For backwards compatibility, `getAgent` + * will set a reference to the Desktop Agent implementation at `window.fdc3` + * if one does not already exist, and will fire the fdc3Ready event. Defaults to + * `false`. Setting this flag to `true` will inhibit that behavior, leaving + * `window.fdc3` unset. + * + * @property {function} failover An optional function that provides a + * means of connecting to or starting a Desktop Agent, which will be called + * if no Desktop Agent is detected. Must return either a Desktop Agent + * implementation directly (e.g. by using a proprietary adaptor) or a + * WindowProxy (e.g a reference to another window returned by `window.open` + * or an iframe's `contentWindow`) for a window or frame in which it has loaded + * a Desktop Agent or suitable proxy to one that works with FDC3 Web Connection + * and Desktop Agent Communication Protocols. + */ +type GetAgentParams = { + timeoutMs?: number, + identityUrl?: string, + channelSelector?: boolean, + intentResolver?: boolean, + dontSetWindowFdc3?: boolean, + failover?: (args: GetAgentParams) => Promise +}; +``` + +:::note + +As web applications can navigate to or be navigated by users to different URLs and become different applications, validation of an app's identity is necessary. The web application's current URL is passed to web browser-based Desktop Agents to allow them to establish the app's identity - usually connecting it with an App Directory record already known to the Desktop Agent. For more details on identity validation see the identity validation section of the [Web Connection Protocol (WCP)](specs/webConnectionProtocol). + +::: + +Finally, if there is still no Desktop Agent available, or an issue prevent connection to it, the `getAgent()` function will reject its promise with a message from the [`AgentError`](./Errors#agenterror) enumeration. + +## Injected iframes for adaptors and user interfaces + +The `getAgent()` function may try to create hidden iframes within an application window in order to load either an adaptor to a Desktop Agent, or Intent Resolver and Channel Selector user interfaces when needed. The iframes are used in order to sandbox the relevant software, and are communicated with securely via the HTML Standard's Channel Messaging API ([MDN](https://developer.mozilla.org/en-US/docs/Web/API/Channel_Messaging_API), [HTML Living Standard](https://html.spec.whatwg.org/multipage/web-messaging.html)). + +:::warning + +The [Content-Security-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy) directives [frame-src](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-src), [child-src](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/child-src) and [default-src](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/default-src) can prevent iframes injected into an application from loading content. Where these are used, please ensure that they allow the loading of content from the domains of Desktop Agents and UI implementations that you wish to work with (including [fdc3.finos.org](https://fdc3.finos.org/) where the reference Intent Resolver and Channel Selector UIs may be loaded from). + +::: + +## Failover function + +Desktop Agent retrieval can time out, for instance if the DA doesn't exist or is unresponsive. The default timeout of 750 milliseconds can be overridden by setting the `timeoutMs` parameter. An application may also provide a failover function which will be called if an interface cannot be retrieved or times out. + +Example: Decreasing the timeout and providing a failover function + +```js + const desktopAgent = await getAgent({ + timeoutMs: 250, + failover: async (params: GetAgentParams) => { + // return WindowProxy | DesktopAgent + } + }); +``` + +The failover function allows an application to provide a backup mechanism for connecting to a DA. It is called only when establishment through normal procedures fails or times out. + +:::note + +If you wish to _completely override FDC3's standard discovery mechanisms_, then do not use a failover function. Instead, simply skip the `getAgent()` call and provide your own DesktopAgent object. + +::: + +Failover functions MUST be asynchronous and MUST resolve to one of the following types: + +1. [`DesktopAgent`](./DesktopAgent) + The application may choose to directly import or load code that provides a `DesktopAgent` implementation. `getAgent()` will then resolve to the provided `DesktopAgent`. +2. [`WindowProxy`](https://html.spec.whatwg.org/multipage/nav-history-apis.html#the-windowproxy-exotic-object) ([MDN](https://developer.mozilla.org/en-US/docs/Glossary/WindowProxy)) + The application may open a window or create a hidden iframe which may then provide access to a compliant browser-resident DA. Ensure that the iframe has loaded (listen for the `load` event) or for separate windows allow a suitable timeout for the window load, then resolve to the `WindowProxy` object for the window or iframe. The `getAgent()` call will then use the supplied `WindowProxy` to establish a connection. + +## Persisted Connection Data + +The `getAgent()` function uses [`SessionStorage`](https://html.spec.whatwg.org/multipage/webstorage.html) ([MDN](https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage)) to persist information on an instance of an app under the key `"FDC3-Desktop-Agent-Details"` and how it connected to a Desktop Agent in order to ensure a consistent connection type and `instanceId` when reconnecting after navigation or refresh events. Applications are not expected to interact with this information directly, rather it is set and used by the `getAgent()` implementation. + +The details persisted conform to the following type: + +```ts +/** Type representing data on the Desktop Agent that an app + * connected to that is persisted by the getAgent function + * to be used when re-connecting (after a navigation or + * refresh event) and to ensure a consistent instanceId. + */ +type DesktopAgentDetails = { + /** The type of Desktop Agent connected to. Used to + * prevent an inadvertent switch to a different agent.*/ + agentType: WebDesktopAgentType, + + /** The URL that was previously sent to the Desktop Agent + * to establish the app's identity.*/ + identityUrl?: string, + + /** The current URL at the time of the last connection to + * a Desktop Agent.*/ + actualUrl?: string, + + /** Optional URL field that should be used to store any + * URL that was used to connect to a Desktop Agent. URLs + * may have been provided by a parent window that has since + * gone away and persisting may allow re-connection in such + * cases. */ + agentUrl?: string, + + /** The appId that was identified for the application by the + * Desktop Agent.*/ + appId: string, + + /** The instanceId that was issued to the app by the Desktop + * Agent. */ + instanceId: string, + + /** The instanceUuid that was issued to the app. This should be + * passed when connecting to the Desktop Agent to help + * identify that this app has connected before and which + * instance it is, enabling the Desktop Agent to reissue + * the same instanceId. The instanceUuid should never be shared + * with other applications and is not available through the + * FDC3 API, allowing it to be used as a shared secret with + * the Desktop Agent that issued the associated instanceId.*/ + instanceUuid: string +} + +/** Enumeration of values used to describe types of web-based + * Desktop Agent. Each 'type' refers to the means by which + * a connection to the agent is made and/or an interface to it + * received. */ +enum WebDesktopAgentType { + /** Denotes Desktop Agents that inject the FDC3 interface + * at `window.fdc3`. */ + Preload = "PRELOAD", + + /** Denotes Desktop Agents that run (or provide an interface) + * within a parent window or frame, a reference to which + * will be found at `window.opener`, `window.parent`, + * `window.parent.opener` etc. */ + ProxyParent = "PROXY_PARENT", + + /** Denotes Desktop Agents that are connected to by loading a URL + * into a hidden iframe whose URL was returned by a parent window + * or frame. */ + ProxyUrl = "PROXY_URL", + + /** Denotes a Desktop Agent that was returned by a failover + * function that was passed by the application. */ + Failover = "FAILOVER" +} +``` diff --git a/docs/api/ref/PrivateChannel.md b/docs/api/ref/PrivateChannel.md index d232cddda..12ff1f06b 100644 --- a/docs/api/ref/PrivateChannel.md +++ b/docs/api/ref/PrivateChannel.md @@ -142,7 +142,7 @@ _desktopAgent.AddIntentListener("QuoteStream", async (context, metad ### 'Client-side' example -The 'client' application retrieves a `Channel` by raising an intent with context and awaiting the result. It adds a `ContextListener` so that it can receive messages from it. If a `PrivateChannel` was returned this may in turn trigger a handler added on the 'server-side' with `onAddContextListener()` and start the stream. A listener may also be to clear up if the 'server-side' disconnects from the stream. +The 'client' application retrieves a `Channel` by raising an intent with context and awaiting the result. It adds a `ContextListener` so that it can receive messages from it. If a `PrivateChannel` was returned this may in turn trigger a handler added on the 'server-side' with `onAddContextListener()` and start the stream. The `onDisconnect()` listener may also be to clean up when the 'server-side' disconnects the stream. Although this interaction occurs entirely in frontend code, we refer to it as the 'client-side' interaction as it requests and receives a stream of responses. diff --git a/docs/api/spec.md b/docs/api/spec.md index dde1210ba..b15eec8ce 100644 --- a/docs/api/spec.md +++ b/docs/api/spec.md @@ -48,8 +48,9 @@ The FDC3 API specification consists of interfaces. It is expected that each Des - [`Channel`](ref/Channel) - [`PrivateChannel`](ref/PrivateChannel) - [`Listener`](ref/Types#listener) +- [Utility types](ref/Types) and [Metadata Objects](ref/Metadata). -Other interfaces defined in the spec are not critical to define as concrete types. Rather, the Desktop Agent should expect to have objects of the interface shape passed into or out of their library. +The means to access the main FDC3 API interface (a `DesktopAgent` implementation) is defined separately for each language in which FDC3 is implemented. These definitions are important as they affect whether applications can be written in a vendor agnostic format so that they run under any Standards-conformant implementation. ### Implementation language @@ -67,9 +68,9 @@ The surface area of FDC3 standardization (shown in *white* above) itself is quit For example: -- workspace management -- user identity and SSO -- entitlements +- Workspace management +- User identity and SSO +- Entitlements - UX of application resolution Are all areas of functionality that any feature-complete desktop agent would implement, but are not currently areas considered for standardization under FDC3. @@ -78,7 +79,7 @@ Are all areas of functionality that any feature-complete desktop agent would imp A goal of the FDC3 Standard is that applications running in different Desktop Agent contexts on the same desktop, or operated by the same user, would be able to interoperate and that one Desktop Agent context would be able to discover and launch an application in another Desktop Application context. As Desktop Agent interop is supported by common standards for APIs an app in one Desktop Agent context would not need to know a different syntax to launch or interact with an app in another Desktop Agent context. -Inter-agent communication at the API layer may be achieved via the [Desktop Agent Bridging Part of the FDC3 Standard](../agent-bridging/spec) ([@experimental](../fdc3-compliance#experimental-features)), which defines an independent service that Desktop Agents may connect to, and a protocol for the exchange of messages relating to FDC3 API calls. Hence, by implementing support for Desktop Agent Bridging, a platform may extend interop across applications running in multiple Desktop Agent contexts. +Inter-agent communication at the API layer may be achieved via the [Desktop Agent Bridging Part of the FDC3 Standard](../agent-bridging/spec) ([@experimental](../fdc3-compliance#experimental-features)), which defines an independent service that Desktop Agents may connect to (via the Bridge Connection Protocol or BCP), and a protocol for the exchange of messages relating to FDC3 API calls (the Bridge Messaging Protocol or BMP). Hence, by implementing support for Desktop Agent Bridging, a platform may extend interop across applications running in multiple Desktop Agent contexts. Desktop Agent Bridging provides message exchanges and a workflow for performing intent resolution across multiple agents. Hence, app discovery is supported across the agents connected to the bridge for intent-based workflows. Further, as channels are also supported by bridging, context sharing also works across multiple agents. @@ -90,12 +91,10 @@ There is currently no method of discovering all the apps supported by a Desktop An FDC3 Standard compliant Desktop Agent implementation **MUST**: -- Provide the FDC3 API to web applications via a global accessible as [`window.fdc3`](./supported-platforms#web). -- Provide a global [`fdc3Ready`](./supported-platforms#web) event to web applications that is fired when the API is ready for use. -- Provide a method of resolving ambiguous intents (i.e. those that might be resolved by multiple applications) or unspecified intents (calls to `raiseIntentForContext` that return multiple options), such as a resolver UI. - - Intent resolution MUST take into account any specified input or return context types - - Requests for resolution to apps returning a channel MUST include any apps that are registered as returning a channel with a specific type. -- Return (JavaScript or platform appropriate) Error Objects with messages from the [`ChannelError`](ref/Errors#channelerror), [`OpenError`](ref/Errors#openerror), [`ResolveError`](ref/Errors#resolveerror) and [`ResultError`](ref/Errors#resulterror) enumerations as appropriate. +- Be able to provide the FDC3 API to applications in accordance with with any requirements defined for that platform, as defined in [Supported Platforms](supported-platforms) and linked specifications: + - For web applications this includes: + - Implementing the [Browser-Resident Desktop Agent spec](specs/browserResidentDesktopAgents.md) if it is intended to support apps running in a standard web browser. + - Implementing the [Preload Desktop Agent spec](specs/preloadDesktopAgents.md) if it is intended to support apps running in a container or other environment that supports injecting a global `fdc3` object. - Accept as input and return as output data structures that are compatible with the interfaces defined in this Standard. - Include implementations of the following [Desktop Agent](ref/DesktopAgent) API functions, as defined in this Standard: - [`addContextListener`](ref/DesktopAgent#addcontextlistener) @@ -113,6 +112,10 @@ An FDC3 Standard compliant Desktop Agent implementation **MUST**: - [`open`](ref/DesktopAgent#open) - [`raiseIntent`](ref/DesktopAgent#raiseintent) - [`raiseIntentForContext`](ref/DesktopAgent#raiseintentforcontext) +- Provide a method of resolving ambiguous intents (i.e. those that might be resolved by multiple applications) or unspecified intents (calls to `raiseIntentForContext` that return multiple options), such as a resolver UI. + - Intent resolution MUST take into account any specified input or return context types + - Requests for resolution to apps returning a channel MUST include any apps that are registered as returning a channel with a specific type. +- Return (JavaScript or platform appropriate) Error Objects with messages from the [`ChannelError`](ref/Errors#channelerror), [`OpenError`](ref/Errors#openerror), [`ResolveError`](ref/Errors#resolveerror) and [`ResultError`](ref/Errors#resulterror) enumerations as appropriate. - Provide an ID for each [`PrivateChannel`](ref/PrivateChannel) created via [`createPrivateChannel`](ref/DesktopAgent#createprivatechannel) and prevent them from being retrieved via [`getOrCreateChannel`](ref/DesktopAgent#getorcreatechannel) by ID. - Only require app directories that they connect to to have implemented only the minimum requirements specified in the [App Directory API Part](../app-directory/spec) of this Standard. - Provide details of whether they implement optional features of the Desktop Agent API in the `optionalFeatures` property of the [`ImplementationMetadata`](ref/Metadata#implementationmetadata) object returned by the [`fdc3.getInfo()`](ref/DesktopAgent#getinfo) function. @@ -179,12 +182,12 @@ Since version 1.2 of the FDC3 Standard it may do so via the [`fdc3.getInfo()`](r ```ts -import {compareVersionNumbers, versionIsAtLeast} from '@finos/fdc3'; +import { compareVersionNumbers, versionIsAtLeast } from "@finos/fdc3"; -if (fdc3.getInfo && versionIsAtLeast(await fdc3.getInfo(), '1.2')) { +if (fdc3.getInfo && versionIsAtLeast(await fdc3.getInfo(), "1.2")) { await fdc3.raiseIntentForContext(context); } else { - await fdc3.raiseIntent('ViewChart', context); + await fdc3.raiseIntent("ViewChart", context); } ``` @@ -204,8 +207,8 @@ The [`ImplementationMetadata`](ref/Metadata#implementationmetadata) object retur ```ts -let implementationMetadata = await fdc3.getInfo(); -let {appId, instanceId} = implementationMetadata.appMetadata; +const implementationMetadata = await fdc3.getInfo(); +const { appId, instanceId } = implementationMetadata.appMetadata; ``` @@ -271,26 +274,34 @@ await fdc3.raiseIntent("StartChat", context, appIntent.apps[0]); const appIntent = await fdc3.findIntent("ViewContact", context, "fdc3.contact"); try { const resolution = await fdc3.raiseIntent(appIntent.intent, context, appIntent.apps[0].name); - const result = await resolution.getResult(); - console.log(`${resolution.source} returned ${JSON.stringify(result)}`); -} catch(error) { - console.error(`${resolution.source} returned a result error: ${error}`); + try { + const result = await resolution.getResult(); + console.log(`${resolution.source} returned ${JSON.stringify(result)}`); + } catch(resultError: ResultError) { + console.error(`${resolution.source} returned an error: ${resultError.message}`); + } +} catch(resolveError: ResolveError) { + console.error(`${JSON.stringify(appIntent.apps[0])} returned an error: ${resolveError.message}`); } //Find apps to resolve an intent and return a channel const appIntent = await fdc3.findIntent("QuoteStream", context, "channel"); try { const resolution = await fdc3.raiseIntent(appIntent.intent, context, appIntent.apps[0].name); - const result = await resolution.getResult(); - if (result && result.addContextListener) { - result.addContextListener(null, (context) => { - console.log(`received context: ${JSON.stringify(context)}`); - }); - } else { - console.log(`${resolution.source} didn't return a channel! Result: ${JSON.stringify(result)}`); + try { + const result = await resolution.getResult(); + if (result && result.addContextListener) { + result.addContextListener(null, (context) => { + console.log(`received context: ${JSON.stringify(context)}`); + }); + } else { + console.log(`${resolution.source} didn't return a channel! Result: ${JSON.stringify(result)}`); + } + } catch(resultError: ResultError) { + console.error(`${resolution.source} returned an error: ${resultError.message}`); } -} catch(error) { - console.error(`${resolution.source} returned a result error: ${error}`); +} catch (resolveError: ResolveError) { + console.error(`${JSON.stringify(appIntent.apps[0])} returned an error: ${resolveError.message}`); } //Find apps that can perform any intent with the specified context @@ -378,9 +389,9 @@ For example, to raise a specific intent: ```ts try { - const resolution = await fdc3.raiseIntent('StageOrder', context); + const resolution = await fdc3.raiseIntent("StageOrder", context); } -catch (err){ ... } +catch (err: ResolveError) { ... } ``` @@ -408,8 +419,7 @@ try { if (resolution.data) { const orderId = resolution.data.id; } -} -catch (err){ ... } +} catch (err: ResolveError) { ... } ``` @@ -437,13 +447,13 @@ Use metadata about the resolving app instance to target a further intent ```ts try { - const resolution = await fdc3.raiseIntent('StageOrder', context); + const resolution = await fdc3.raiseIntent("StageOrder", context); ... //some time later await agent.raiseIntent("UpdateOrder", context, resolution.source); } -catch (err) { ... } +catch (err: ResolveError) { ... } ``` @@ -475,13 +485,13 @@ try { /* Detect whether the result is Context or a Channel by checking for properties unique to Channels. */ if (result && result.broadcast) { console.log(`${resolution.source} returned a channel with id ${result.id}`); - } else if (result){ + } else if (result) { console.log(`${resolution.source} returned data: ${JSON.stringify(result)}`); } else { console.error(`${resolution.source} didn't return anything`); } -} catch(error) { - console.error(`${resolution.source} returned a data error: ${error}`); +} catch(err: ResultError) { + console.error(`${resolution.source} returned a data error: ${err.message}`); } ``` @@ -603,7 +613,7 @@ To find a User channel, one calls: ```ts // returns an array of channels const allChannels = await fdc3.getUserChannels(); -const redChannel = allChannels.find(c => c.id === 'red'); +const redChannel = allChannels.find(c => c.id === "red"); ``` @@ -653,75 +663,75 @@ Future versions of the FDC3 Standard may support connections between desktop age ```ts const recommendedChannels = [ { - id: 'fdc3.channel.1', - type: 'user', + id: "fdc3.channel.1", + type: "user", displayMetadata: { - name: 'Channel 1', - color: 'red', - glyph: '1', + name: "Channel 1", + color: "red", + glyph: "1", }, }, { - id: 'fdc3.channel.2', - type: 'user', + id: "fdc3.channel.2", + type: "user", displayMetadata: { - name: 'Channel 2', - color: 'orange', - glyph: '2', + name: "Channel 2", + color: "orange", + glyph: "2", }, }, { - id: 'fdc3.channel.3', - type: 'user', + id: "fdc3.channel.3", + type: "user", displayMetadata: { - name: 'Channel 3', - color: 'yellow', - glyph: '3', + name: "Channel 3", + color: "yellow", + glyph: "3", }, }, { - id: 'fdc3.channel.4', - type: 'user', + id: "fdc3.channel.4", + type: "user", displayMetadata: { - name: 'Channel 4', - color: 'green', - glyph: '4', + name: "Channel 4", + color: "green", + glyph: "4", }, }, { - id: 'fdc3.channel.5', - type: 'user', + id: "fdc3.channel.5", + type: "user", displayMetadata: { - name: 'Channel 5', - color: 'cyan', - glyph: '5', + name: "Channel 5", + color: "cyan", + glyph: "5", }, }, { - id: 'fdc3.channel.6', - type: 'user', + id: "fdc3.channel.6", + type: "user", displayMetadata: { - name: 'Channel 6', - color: 'blue', - glyph: '6', + name: "Channel 6", + color: "blue", + glyph: "6", }, }, { - id: 'fdc3.channel.7', - type: 'user', + id: "fdc3.channel.7", + type: "user", displayMetadata: { - name: 'Channel 7', - color: 'magenta', - glyph: '7', + name: "Channel 7", + color: "magenta", + glyph: "7", }, }, { - id: 'fdc3.channel.8', - type: 'user', + id: "fdc3.channel.8", + type: "user", displayMetadata: { - name: 'Channel 8', - color: 'purple', - glyph: '8', + name: "Channel 8", + color: "purple", + glyph: "8", }, }, ]; @@ -741,7 +751,7 @@ To get (or create) a [`Channel`](ref/Channel) reference, then interact with it: ```ts -const appChannel = await fdc3.getOrCreateChannel('my_custom_channel'); +const appChannel = await fdc3.getOrCreateChannel("my_custom_channel"); // get the current context of the channel const current = await appChannel.getCurrentContext(); // add a listener @@ -780,7 +790,7 @@ let joinedChannel = await fdc3.getCurrentChannel() const listener = await fdc3.addContextListener(null, context => { ... }); //retrieve an App channel and add a listener that is specific to that channel -const myChannel = await fdc3.getOrCreateChannel('my_custom_channel'); +const myChannel = await fdc3.getOrCreateChannel("my_custom_channel"); const myChannelListener = await myChannel.addContextListener(null, context => { ... }); fdc3.joinChannel('blue') diff --git a/docs/api/specs/browserResidentDesktopAgents.md b/docs/api/specs/browserResidentDesktopAgents.md new file mode 100644 index 000000000..edbd6796c --- /dev/null +++ b/docs/api/specs/browserResidentDesktopAgents.md @@ -0,0 +1,265 @@ +--- +id: browserDesktopAgents +sidebar_label: Browser Desktop Agents +title: Browser-Resident Desktop Agents (next) +--- + +:::info _[@experimental](../fdc3-compliance#experimental-features)_ + +Browser Resident Desktop Agents (DAs) are an experimental feature added to FDC3 in 2.2. Limited aspects of their design may change in future versions and they are exempted from the FDC3 Standard's normal versioning and deprecation policies in order to facilitate any necessary change. + +::: + +This document specifies the required behavior for Browser-Resident Desktop Agents (DA). Such agents allow FDC3 applications running directly in a browser to participate in FDC3 interop by way of a `getAgent()` function that is provided by the [`@finos/fdc3` NPM module](https://www.npmjs.com/package/@finos/fdc3) and a standardized communication protocol. This approach is in contrast to "Preload DAs" which run on technology that allows the FDC3 interface to be injected (such as Electron, WebView2 or a browser-extension based implementation). + +This specification only applies to apps running in a browser and therefore assumes use of JavaScript/TypeScript and HTML APIs. Implementations in other languages such as .NET are not covered. + +Along with this specification, a new general connection strategy has been established for FDC3 compliant web-applications: FDC3 compliant apps SHOULD make use of `getAgent()` function provided by the [`@finos/fdc3` NPM module](https://www.npmjs.com/package/@finos/fdc3) to retrieve their FDC3 interface (an instance of an implementation of the [`DesktopAgent`](../ref/DesktopAgent) interface). Apps that follow these guidelines will be able to interop through either Browser-Resident DAs or [Preload DAs](./preloadDesktopAgents) without the inclusion of code or libraries specific to a particular Desktop Agent vendor or implementation. We refer to this concept as Write Once Run Anywhere (WORA). + +:::info + +Prior to FDC3 2.2, only [Preload Desktop Agents](./preloadDesktopAgents) were supported. + +::: + +:::note + +This document covers the requirements for _implementors of Browser-Resident Desktop Agents_. The `getAgent()` function that applications use to gain access to an FDC3 interface is provided by the [`@finos/fdc3` NPM module](https://www.npmjs.com/package/@finos/fdc3). Many behavioral details of `getAgent()` are purposefully omitted from this document in order to reduce the required scope of understanding. Please refer to the [getAgent() specification in the FDC3 Web Connection Protocol](webConnectionProtocol.md) for information on how the client side operates or [supported platforms](../supported-platforms) for details of how to access the Desktop Agent API in an application. + +::: + +:::tip + +When referencing "DA" in the subsequent sections of this document we will hereafter always mean a "Browser-Resident Desktop Agent" - code that runs in a browser page (iframe or window) and which conforms to this specification. + +::: + +## Launching apps + +As a prerequisite for launching an app via FDC3 in the browser, a DA must first exist as running code in a browser window (See failover functions for an exception to this rule), although that code MAY also connect to or rely on remotely hosted services. We will refer to this window as the "DA Window". + +As the DA typically acts as a launcher for applications, it will often be the case that the DA window is related to the application window(s) in that it may have created the application window with `window.open()` or have created an iframe and loaded the application URL into it. Hence, the DA window may be referred to as a 'parent' (window or frame) of the application frame and the relationship may be used to implement communication between the frames. + +:::note + +It is possible to have multiple DA Windows. For instance, a DA may propagate itself into new windows. Communication and coordination between DA Windows is an implementation detail and is not covered by this specification. + +::: + +When an app runs `getAgent()`, it checks for the existence of `window.parent`, `window.opener` and `window.parent.opener` (and will continue up the chain of parent frames, e.g. `window.parent.parent`, `window.parent.parent.opener` until the reference to the next parent is equal to the current one (e.g. `window.parent.parent === window.parent` indicating that the frame does not have a parent). `getAgent()` will then send a standardized `WCP1Hello` message to each parent window or frame reference via [`postMessage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) in order to discover a DA. + +Hence, apps may be launched: + +1. By creating iframes in a DA Window +2. By calling `window.open` from a DA Window +3. By creating iframes in a window that was opened from a DA Window + +and the Desktop Agent application will be found in a 'parent' of the application frame. + +## Responding to app instance connections - Web Connection Protocol (WCP) + +Browser Resident DAs MUST call `window.addEventListener("message", ...)` to receive incoming connection requests from apps, in the form of [`"WCP1Hello"`](https://fdc3.finos.org/schemas/next/api/WCP1Hello.schema.json) messages defined in the [Web Connection Protocol](./webConnectionProtocol). + +Upon receiving an incoming [`"WCP1Hello"`](https://fdc3.finos.org/schemas/next/api/WCP1Hello.schema.json) the Desktop Agent MUST either: + +1. Respond with a [`WCP2LoadUrl`](https://fdc3.finos.org/schemas/next/api/WCP2LoadUrl.schema.json) message (as defined in the [Web Connection Protocol](./webConnectionProtocol)). + - This message indicates that `getAgent()` should create an iframe, load the provided URL (for an adaptor to the Desktop Agent) into it and then restart the connection process by sending [`"WCP1Hello"`](https://fdc3.finos.org/schemas/next/api/WCP1Hello.schema.json) to the iframe. + + :::warning + + The [Content-Security-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy) directives [frame-src](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-src), [child-src](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/child-src) and [default-src](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/default-src) can prevent iframes injected into an application from loading content. Where these are used in app implementations, please advise app implementors to include domains from which the adaptor content is served. + + ::: +2. Create a [`MessageChannel`](https://developer.mozilla.org/en-US/docs/Web/API/Channel_Messaging_API) with two entangled `MessagePort` instances that will be used for further communication with the application. + - Before returning one of `MessagePort` instances, the DA MUST set up event listeners to receive and process a [`"WCP4ValidateAppIdentity"`](https://fdc3.finos.org/schemas/next/api/WCP4ValidateAppIdentity.schema.json) message from the application. + - To deliver the `MessagePort`, the DA MUST respond to the event's `source` window by responding with a [`WCP3Handshake`](https://fdc3.finos.org/schemas/next/api/WCP3Handshake.schema.json) message (as defined in the [Web Connection Protocol](./webConnectionProtocol)) and append `port2` from the `MessageChannel` to the message. + +All further communication is conducted over the `MessageChannel`. The Desktop Agent should consider the newly created port to be inactive until a [`"WCP4ValidateAppIdentity"`](https://fdc3.finos.org/schemas/next/api/WCP4ValidateAppIdentity.schema.json) message is received via the `MessagePort` and successfully processed. + +### Validating app identity + +The first message received by the Desktop Agent on `MessagePort` `port1` from an application via a `MessageChannel` it created MUST be [`"WCP4ValidateAppIdentity"`](https://fdc3.finos.org/schemas/next/api/WCP4ValidateAppIdentity.schema.json). Once received and successfully processed, the Desktop Agent should respond with a [`WCP5ValidateAppIdentityResponse`](https://fdc3.finos.org/schemas/next/api/WCP5ValidateAppIdentityResponse.schema.json) message containing an `appId`, `instanceId` and `instanceUuid` to identify the app and this specific instance and then enable processing of [Desktop Agent Communication Protocol](./desktopAgentCommunicationProtocol.md) messages for this application. If validation fails, it should instead respond with [`WCP5ValidateAppIdentityFailedResponse`](https://fdc3.finos.org/schemas/next/api/WCP5ValidateAppIdentityFailedResponse.schema.json) and close the `MessageChannel`. + +App identity is validated and an `appId` assigned by matching the application to an AppD record already known to the Desktop Agent. This is achieved by matching `identityUrl` (supplied by the application via the `getAgent()` implementation) to the `details.url` field of the known App Directory records. + +As web applications may vary their URL during use, or serve multiple applications from the same origin (differentiated by path, search params and/or hash), care must be taken in matching URLs to appD records. Two URLs are sent to the Desktop Agent in the [`"WCP4ValidateAppIdentity"`](https://fdc3.finos.org/schemas/next/api/WCP4ValidateAppIdentity.schema.json) message: + +- `identityUrl`: the URL to match to the app directory record. +- `actualUrl`: the current URL of the application, which MUST be captured automatically by the `getAgent()` implementation. + +Applications _may_ specify the `identityUrl` value as an argument to `getAgent()`. If not specified, the `getAgent()` implementation MUST use the current URL of the application. The Desktop Agent MUST validate that the origin of the `identityUrl` is the same as the origin of _both_ the `actualUrl` and the `WCPValidateAppIdentity` message sent over the `MessagePort`. The Desktop Agent MUST then match the URL to that of applications known to the Desktop Agent. + +The `actualUrl` field may be used for logging and debug purposes by the Desktop Agent and it differing from the `identityUrl` indicates that the application provided an override via `getAgent()`. + +Owing to the fact that the different parts of a URL (origin, path, search parameters, anchor) are used differently by web applications, matching of the `identityUrl` to known application URLs can be more complex than a simple string match. To allow application developers control the requirements of matching, Desktop Agents SHOULD consider a URL to match if all elements (origin, path, search parameters, anchor) present in the App Directory record's URL are present in the `identityUrl`. As multiple App Directory records may match a given identity URL, Desktop Agents SHOULD look for the best match that meets the requirements. + +For example, given an identity URL `url`, and an array of App Directory records `appDRecords`, a Desktop Agent MAY implement matching as follows: + +```js +/** Return the AppD record whose URL best matches the input URL or `null` if no + * match is found. To be considered a match all elements of the AppD URL + * (origin, path, searchParams and hash) MUST be found in the input URL. + * The best match is the AppD URL that contains the most elements from the + * input URL. + */ +let matchUrlToAppD = (url, appDRecords) => { + //parse the URL + const inputUrl = new URL(url); + + //fn to trim trailing / from paths + const trimTrailingSlash = (path) => { + if (path.endsWith("/")) { + const out = path.slice(0, -1); + //return null if it was just a / + return out === "" ? null : out; + } else { + return path; + } + }; + + const matchScores = []; + + //score appD records based on the match of their URL to the input URL + // if any component of the appD record URL is missing from input URL, + // score 0 otherwise count the number of input elements matched. + appDRecords.map((record) => { + //record must contain a URL + if (!record.details?.url) { return; } + + //parse record URL + const parsedUrl = new URL(record.details.url); + + //origin of URL must match record + if (parsedUrl.origin !== inputUrl.origin) { return; } + let score = 1; + + //path must match if present in appD record - Path of "/" is ignored + const appDPath = trimTrailingSlash(parsedUrl.pathname); + if (appDPath) { + if (trimTrailingSlash(inputUrl.pathname) != appDPath) { + return; + } else { + score++; + } + } + + //hash must match if present in appD record + if (parsedUrl.hash) { + if (inputUrl.hash != parsedUrl.hash) { + return; + } else { + score++; + } + } + + if (!!parsedUrl.search) { + //search params present in appD record must be present in URL + const recordSearchKeys = parsedUrl.searchParams.keys().toArray(); + for (let i=0; i { + if (parsedUrl.searchParams.get(key) === inputUrl.searchParams.get(key)) { + score++; + } + }); + } + + //everything present in the record was found in the inputUrl + matchScores.push([score, record]); + }); + + //return the best scoring match (ignore ties) + matchScores.sort((a,b) => b[0]-a[0]); + return matchScores[0][1] ?? null; +}; +``` + +### Validating instance identity + +If the [`"WCP4ValidateAppIdentity"`](https://fdc3.finos.org/schemas/next/api/WCP4ValidateAppIdentity.schema.json) request message contains `instanceId` and `instanceUuid` fields then the window may represent an app instance that has navigated or refreshed and requires reconnecting with the previously assigned `instanceId`. The DA SHOULD reissue the same instanceId if the `instanceUuid`, `appId`, `WindowProxy` object and origin provided **all** match what is already on record and return details via the [`WCP5ValidateAppIdentityResponse`](https://fdc3.finos.org/schemas/next/api/WCP5ValidateAppIdentityResponse.schema.json) message. + +If an `instanceId` and `instanceUuid` are not provided or do not pass the checks defined above, a new `instanceId` and `instanceUuid` should be generated by the Desktop Agent and returned in the [`WCP5ValidateAppIdentityResponse`](https://fdc3.finos.org/schemas/next/api/WCP5ValidateAppIdentityResponse.schema.json) message. All generated `instanceId` and `instanceUuid` values should be retained by the DA (for the session or other appropriate period of time), along with a reference to the `WindowProxy` (`event.source` from the initial message received), as these can later be used for comparison to help determine if a new connection request is coming from a previously connected window which may or may not represent an existing app instance. If a previously connected window is reconnecting, any existing `MessageChannel` instance created for it can be cleaned up. + +Details of the received `instanceId` and `instanceUuid` are stored by the `getAgent()` implementation in [SessionStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage) within the application window and are automatically reused when reconnecting to the Desktop Agent. SessionStorage is used as it is scoped to a particular window (rather than origin, as is the case with LocalStorage), allowing separate storage for each app instance. + +:::warning + +Apps launched via a call to `window.open()` from a window or app instance on the same origin can appear to be the original window. This is because browsers may clone SessionStorage for newly opened windows. When a child window calls `getAgent()` with the same `appId`, `instanceId` and `instanceUuid` as the parent window, it will appear to the DA that a navigation event occurred on the parent window. DAs therefore MUST also compare the `WindowProxy` object that is used to establish each connection to differentiate such cloned instances. If the WindowProxy objects do not match, then a new `instanceId` and `instanceUuid` MUST be assigned. + +::: + +For more details on the connection process, please see the documentation for the [Web Connection Protocol](./webConnectionProtocol). + +### Disconnects + +DAs are responsible for tracking when app windows close or navigates, which is necessary to provide accurate responses to the `findIntent`, `findIntentsByContext` & `findInstances` API calls, and to correctly resolve raised intents. + +:::info + +The HTML Standard specifies an [onclose event handler on `MessagePort`](https://html.spec.whatwg.org/multipage/web-messaging.html#handler-messageport-onclose) which would provide an ideal event-based solution for tracking the closing of app windows. However, this event is not currently implemented in Chrome/Chromium due to security concerns (it reveals the garbage collection activity of the process holding the other end of the pipe, see comment on [whatwg/html/issues/1766](https://github.com/whatwg/html/issues/1766#issuecomment-1958782062), see also proposals to [restrict when MessagePort's onclose event can fire](https://github.com/whatwg/html/issues/10201)). + +::: + +Checking whether an application has closed may be achieved by a number of approaches: + +- By checking the `closed` property of WindowProxy objects that were received via the `source` property of the original `WCP1Hello` message, or any subsequent message over the `MessageChannel`. `closed` will be true if the window or frame was closed or destroyed, or the window or frame has navigated cross-domain. + - However, it should be noted that the `closed` will be `false` if the window has navigated same-domain, but is no longer an FDC3 app or has become a different FDC3 app. Hence, checking the `closed` property will not catch all cases. + - If an equivalent `WindowProxy` object (`WindowProxy` objects can be compared with `==` and will be equivalent if they represent the same window) is received from a different application the DA should consider the original application using that `WindowProxy` to have closed. +- By receiving a `WCP6Goodbye` message from the application when it is closing. The `getAgent()` implementation automates the sending of this message via the HTML Standard's [Page Life Cycle API](https://wicg.github.io/page-lifecycle/spec.html). Specifically, the `getAgent()` implementation MUST attempt to detect windows closing by listening for the `pagehide` event and considering a window to be closed if the event's `persisted` property is `false`. + - Note that the `pagehide` event may not fire if the window's render thread crashes or is closed while 'frozen'. +- By polling the application for responses via the `heartbeatEvent` and `heartbeatAcknowledgement` messages provided in the [Desktop Agent Communication Protocol](./desktopAgentCommunicationProtocol#checking-apps-are-alive). These message may be used for both periodic and on-demand polling by DA implementations. On-demand polling could, for example, be used to check that all instances returned in a findIntent response or displayed in an intent resolver are still alive. + - Desktop Agents MAY determine their own timeout, or support configuration, to be used for considering an application to have closed as this may be affected by the implementation details of app and DAs. + +Finally, Desktop Agents SHOULD retain instance details for applications that have closed as they may appear to close during navigation events, or may navigate away and then navigate back. By retaining the instance data (`instanceId`, `instanceUuid` and `WindowProxy`) the same instance identity can be maintained or reissued. There is no standard length of time that such details should be retained, hence, Desktop Agents MAY determine for themselves how long to retain instance details for closed instances. + +## Responding to app communications with Desktop Agent Communication Protocol (DACP) + +After validating an application's identity and any instance identity to be reused, the Desktop Agent is ready to support communication with the application. This is achieved via the [Desktop Agent Communication Protocol](./desktopAgentCommunicationProtocol) (DACP) over the `MessageChannel` established in the previous steps. + +## Implementing DAs in hidden iframes + +As described above, DA providers can leverage hidden iframes to establish a communication mechanism that is independent of a parent window or frame. This approach allows apps to reconnect to a DA even when the parent window or frame has closed, or to connect a DA they've started themselves via a `failover` function. + +The hidden iframe URL can be provided in two ways: + +1. By a Parent window or frame - This allows DAs to handle communication via a hidden iframe that loads a known URL. The main benefit of this approach is that it can allow a system to continue to operate even if the parent window or frame is closed. +2. By a `failover` function - When no parent DA can be found (such as when a tab is opened directly by an end user) then a failover function can create a hidden iframe and return a reference to it (a `WindowProxy`) that is used to initiate communication via the WCP in the same way as we do with a parent window or frame. Alternatively, a `DesktopAgent` implementation may be loaded directly and returned from the `failover` function, which `getAgent()` will pass-through. + +## Channel Selector and Intent Resolver User Interfaces + +Channel Selector and Intent Resolver user-interfaces are normally provided by Desktop Agents to applications. However, when running in a web browser, a DA may not have the ability to present a channel selector in a window that has been opened with `window.open()`, and it may be challenging to display a secondary window over the application when needed (due to pop-up blocking and user preferences). + +The `getAgent()` implementation can facilitate the injection and management of iframes in an application window. An app may provide the optional `channelSelector` and `intentResolver` parameters to the `getAgent()` to indicate whether or not they need these interfaces. For example, the apps may not raise intents. Some apps may also resolve intents internally by leveraging the Desktop Agent's `findIntent` or `findIntentsForContext` API functions. In these situations, the apps won't need a DA-provided interface. Once an app calls `getAgent()`, the parameters that the app provides are forwarded onto the Desktop Agent in the `WCP1Hello` connection message. + +Desktop Agents may implement their own user interfaces for channel selection and intent resolution. The URL for each interface may be returned in the `channelSelectorUrl` and `intentResolverUrl` properties of the payload of the `WCP3Handshake` message sent by the DA during the connection sequence. Alternatively, if the Desktop Agent is able to provide these user interfaces by other means (for example DAs that render applications in iframes within a window they control may use other iframes to render these UIs) or if they app indicated that it did not need them then `channelSelectorUrl` and `intentResolverUrl` may be set to `false`. Finally, `channelSelectorUrl` and `intentResolverUrl` may be set to `true` to indicate that `getAgent()` should use the default reference implementations of these UIs provided via the website. + +:::warning + +The [Content-Security-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy) directives [frame-src](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-src), [child-src](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/child-src) and [default-src](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/default-src) can prevent iframes injected into an application from loading content. Where these are used in app implementations, please advise app implementors to include domains from which the UI implementations are served (including [fdc3.finos.org](https://fdc3.finos.org/) if you are working with the reference Intent Resolver and Channel Selector UIs). + +::: + +User interface iframes are initially injected into the application window with CSS that prevents their display: + +```css +{ + width: "0"; + height: "0"; + position: "fixed"; +} +``` + +and are always displayed with `position: "fixed"` so that they are not part of the document flow. + +Implementations of the UIs may then indicate a limited set of CSS to apply to their frame in the initial `Fdc3UserInterfaceHello` message (when the width and height will be removed if not explicitly set in that message), and later adjust that via `Fdc3UserInterfaceRestyle`. See the [Controlling injected User Interfaces section](./desktopAgentCommunicationProtocol#controlling-injected-user-interfaces-section) in the DACP specification for more details. + +Communication between the `DesktopAgentProxy` and the iframes it injects is achieved via a similar mechanism to that used for communication between an App and the Desktop Agent: a `MessageChannel` is established between the app and iframe, via a `postMessage` sent from the iframe (`Fdc3UserInterfaceHello`) and responded to by the `DesktopAgentProxy` in the app's window (`Fdc3UserInterfaceHandshake`), with a `MessagePort` from a `MessageChannel` appended. + +A further set of messages are provided for working with the injected user interfaces over their `MessageChannel` as part of the DACP, these are: `Fdc3UserInterfaceRestyle`, `Fdc3UserInterfaceDrag`, `Fdc3UserInterfaceChannels`, `Fdc3UserInterfaceChannelSelected`, `Fdc3UserInterfaceResolve` and `Fdc3UserInterfaceResolveAction`. + +See the [Desktop Agent Communication Protocol](./desktopAgentCommunicationProtocol) (DACP) for more details. diff --git a/docs/api/specs/desktopAgentCommunicationProtocol.md b/docs/api/specs/desktopAgentCommunicationProtocol.md new file mode 100644 index 000000000..919e97f39 --- /dev/null +++ b/docs/api/specs/desktopAgentCommunicationProtocol.md @@ -0,0 +1,457 @@ +--- +id: desktopAgentCommunicationProtocol +sidebar_label: Desktop Agent Communication Protocol +title: Desktop Agent Communication Protocol (next) +--- + +:::info _[@experimental](../fdc3-compliance#experimental-features)_ + +FDC3's Desktop Agent Communication Protocol (DACP) is an experimental feature added to FDC3 in 2.2. Limited aspects of its design may change in future versions and it is exempted from the FDC3 Standard's normal versioning and deprecation polices in order to facilitate any necessary change. + +::: + +The Desktop Agent Communication Protocol (DACP) constitutes a set of standardized JSON messages or 'wire protocol' that can be used to implement an interface to a Desktop Agent, encompassing all API calls events defined in the [Desktop Agent API](../ref/DesktopAgent.md). For example, the DACP is used by the [`@finos/fdc3` npm module](https://www.npmjs.com/package/@finos/fdc3) to communicate with Browser-Resident Desktop Agents or a connection setup via the [FDC3 Web Connection Protocol](./webConnectionProtocol). + +## Protocol conventions + +DACP messages are defined in [JSON Schema](https://json-schema.org/) in the [FDC3 github repository](https://github.com/finos/FDC3/tree/fdc3-for-web/schemas/api). + +:::tip + +TypeScript types representing all DACP and WCP messages are generated from the JSON Schema source and can be imported from the [`@finos/fdc3` npm module](https://www.npmjs.com/package/@finos/fdc3): + +```ts +import { BrowserTypes } from "@finos/fdc3"; +``` + +::: + +The protocol is composed of several different classes of message, each governed by a message schema: + +1. **App Request Messages** ([`AppRequest` schema](https://fdc3.finos.org/schemas/next/api/appRequest.schema.json)): + - Messages sent by an application representing an API call, such as [`DesktopAgent.broadcast`](../ref/DesktopAgent#broadcast), [`Channel.addContextListener`](../ref/Channel#addcontextlistener), or [`Listener.unsubscribe`](../ref/Types#listener). + - Message names all end in 'Request'. + - Each instance of a request message sent is uniquely identified by a `meta.requestUuid` field. + +2. **Agent Response Messages** ([`AgentResponse` schema](https://fdc3.finos.org/schemas/next/api/agentResponse.schema.json)): + - Response messages sent from the DA to the application, each relating to a corresponding _App Request Message_. + - Message names all end in 'Response'. + - Each instance of an Agent Response Message is uniquely identified by a `meta.responseUuid` field. + - Each instance of an Agent Response Message quotes the `meta.requestUuid` value of the message it is responding to. + +3. **Agent Event Messages** ([`AgentEvent` schema](https://fdc3.finos.org/schemas/next/api/agentEvent.schema.json)): + - Messages sent from the DA to the application that are due to actions in other applications, such as an inbound context resulting from another app's broadcast. + - Message names all end in 'Event'. + - Each instance of an Agent Response Message is uniquely identified by a `meta.eventUuid` field. + +Each individual message is also governed by a message schema, which is composed with the schema for the message type. + +:::info + +In rare cases, the payload of a request or event message may quote the `requestUuid` or `eventUuid` of another message that it represents a response to, e.g. `intentResultRequest` quotes the `eventUuid` of the `intentEvent` that delivered the intent and context to the app, as well as the `requestUuid` of the `raiseIntentRequest` message that originally raised the intent. + +::: + +All messages defined in the DACP follow a common structure: + +```json +{ + "type": "string", // string identifying the message type + "payload": { + //message payload fields defined for each message type + }, + "meta": { + "timestamp": "2024-09-17T10:15:39+00:00" + //other meta fields determined by each 'class' of message + // these include requestUuid, responseUuid and eventUuid + // and a source field identifying an app where appropriate + } +} +``` + +`meta.timestamp` fields are formatted as strings, according to the format defined by [ISO 8601-1:2019](https://www.iso.org/standard/70907.html), which is produced in JavaScript via the `Date` class's `toISOString()` function, e.g. `(new Date()).toISOString()`. + +### Routing, Registering Listeners & Multiplexing + +The design of the Desktop Agent Communication Protocol is guided by the following sentence from the introduction to the Desktop Agent overview: + +> A Desktop Agent is a desktop component (or aggregate of components) that serves as a launcher and message router (broker) for applications in its domain. + +Hence, that design is based on the assumption that all messaging between applications passes through an entity that acts as the 'Desktop Agent' and routes those messages on to the appropriate recipients (for example a context message broadcast by an app to a channel is routed onto other apps that have added a listener to that channel, or an intent and context pair raised by an application is routed to another app chosen to resolve that intent). While implementations based on a shared bus are possible, they have not been specifically considered in the design of the DACP messages. + +Further, the design of the DACP is based on the assumption that applications will interact with an implementation of the [`DesktopAgent`](../ref/DesktopAgent) interface, with the DACP used behind the scenes to support communication between the implementation of that interface and an entity acting as the Desktop Agent which is running in another process or location, necessitating the use of a 'wire protocol' for communication. For example, [Browser-Resident Desktop Agent](./browserResidentDesktopAgents) implementations use the [FDC3 Web Communication Protocol (WCP)](./webConnectionProtocol.md) to connect a 'Desktop Agent Proxy', provided by the `getAgent()` implementation in the [`@finos/fdc3` npm module](https://www.npmjs.com/package/@finos/fdc3), and a Desktop Agent running in another frame or window which is communicated with via the DACP. + +As a Desktop Agent is expected to act as a router for messages sent through the Desktop Agent API, the DACP provides message exchanges for the registration and un-registration of listeners for particular message types (e.g. events, contexts broadcast on user channels, contexts broadcast on other channel types, raised intents etc.). In most cases, apps can register multiple listeners for the same messages (often filtered for different context or event types). However, where multiple listeners are present, only a single DACP message should be sent representing the action taken in the FDC3 API (e.g. broadcasting a message to a channel) and any multiplexing to multiple listeners should be applied at the receiving end. For example, when working with the WCP, this should be handled by the Desktop Agent Proxy implementation provided by the `getAgent()` implementation. + +## Message Definitions Supporting FDC3 API calls + +This section provides details of the messages defined in the DACP, grouped according to the FDC3 API functions that they support, and defined by JSON Schema files. Many of these message definitions make use of JSON versions of [metadata](../ref/Metadata) and other [types](../ref/Types) defined by the Desktop Agent API, the JSON versions of which can be found in [api.schema.json](https://fdc3.finos.org/schemas/next/api/api.schema.json), while a number of DACP specific object definitions that are reused through the messages can be found in [common.schema.json](https://fdc3.finos.org/schemas/next/api/common.schema.json). + +### `DesktopAgent` + +#### `addContextListener()` + +Request and response used to implement the [`DesktopAgent.addContextListener()`](../ref/DesktopAgent#addcontextlistener) and [`Channel.addContextListener()`](../ref/Channel#addcontextlistener) API calls: + +- [`addContextListenerRequest`](https://fdc3.finos.org/schemas/next/api/addContextListenerRequest.schema.json) +- [`addContextListenerResponse`](https://fdc3.finos.org/schemas/next/api/addContextListenerResponse.schema.json) + +Event message used to deliver context objects that have been broadcast to listeners: + +- [`broadcastEvent`](https://fdc3.finos.org/schemas/next/api/broadcastEvent.schema.json) + +Request and response for removing the context listener ([`Listener.unsubscribe()`](../ref/Types#listener)): + +- [`contextListenerUnsubscribeRequest`](https://fdc3.finos.org/schemas/next/api/contextListenerUnsubscribeRequest.schema.json) +- [`contextListenerUnsubscribeResponse`](https://fdc3.finos.org/schemas/next/api/contextListenerUnsubscribeResponse.schema.json) + +#### `addEventListener()` + +Request and response used to implement the [`addEventListener()`](../ref/DesktopAgent#addeventlistener) API call: + +- [`addEventListenerRequest`](https://fdc3.finos.org/schemas/next/api/addEventListenerRequest.schema.json) +- [`addEventListenerResponse`](https://fdc3.finos.org/schemas/next/api/addEventListenerResponse.schema.json) + +Event messages used to deliver events that have occurred: + +- [`channelChangedEvent`](https://fdc3.finos.org/schemas/next/api/channelChangedEvent.schema.json) + +Request and response for removing the event listener ([`Listener.unsubscribe()`](../ref/Types#listener)): + +- [`eventListenerUnsubscribeRequest`](https://fdc3.finos.org/schemas/next/api/eventListenerUnsubscribeRequest.schema.json) +- [`eventListenerUnsubscribeResponse`](https://fdc3.finos.org/schemas/next/api/eventListenerUnsubscribeResponse.schema.json) + +#### `addIntentListener()` + +Request and response used to implement the [`addIntentListener()`](../ref/DesktopAgent#addintentlistener) API call: + +- [`addIntentListenerRequest`](https://fdc3.finos.org/schemas/next/api/addIntentListenerRequest.schema.json) +- [`addIntentListenerResponse`](https://fdc3.finos.org/schemas/next/api/addIntentListenerResponse.schema.json) + +Event message used to a raised intent and context object from another app to the listener: + +- [`intentEvent`](https://fdc3.finos.org/schemas/next/api/intentEvent.schema.json) + +An additional request and response used to deliver an [`IntentResult`](../ref/Types#intentresult) from the intent handler to the Desktop Agent, so that it can convey it back to the raising application: + +- [`intentResultRequest`](https://fdc3.finos.org/schemas/next/api/intentResultRequest.schema.json) +- [`intentResultResponse`](https://fdc3.finos.org/schemas/next/api/intentResultResponse.schema.json) + +Please note this exchange (and the `IntentResolution.getResult()` API call) support `void` results from a raised intent and hence this message exchange should occur for all raised intents, including those that do not return a result. In such cases, the void intent result allows resolution of the `IntentResolution.getResult()` API call and indicates that the intent handler has finished running. + +Request and response for removing the intent listener ([`Listener.unsubscribe()`](../ref/Types#listener)): + +- [`intentListenerUnsubscribeRequest`](https://fdc3.finos.org/schemas/next/api/intentListenerUnsubscribeRequest.schema.json) +- [`intentListenerUnsubscribeResponse`](https://fdc3.finos.org/schemas/next/api/intentListenerUnsubscribeResponse.schema.json) + +A typical exchange of messages between an app raising an intent, a Desktop agent and an app resolving an intent is: + +```mermaid +sequenceDiagram + AppA ->> DesktopAgent: raiseIntentRequest + DesktopAgent ->> AppB: intentEvent + DesktopAgent ->> AppA: raiseIntentResponse + AppB ->> DesktopAgent: intentResultRequest + DesktopAgent ->> AppB: intentResultResponse + DesktopAgent ->> AppA: raiseIntentResultResponse +``` + +The above flow assumes that AppB has already been launched and added an intent listener. As apps can be launched to resolve an intent a typical message exchange (that includes registration of the intent listener) is: + +```mermaid +sequenceDiagram + AppA ->> DesktopAgent: raiseIntentRequest + break intent resolution determines a new instance of AppB should be launched + DesktopAgent -->> AppB: Launch + AppB -->> DesktopAgent: Connect via WCP + end + AppB ->> DesktopAgent: addIntentListenerRequest + DesktopAgent ->> AppB: addIntentListenerResponse + DesktopAgent ->> AppB: intentEvent + DesktopAgent ->> AppA: raiseIntentResponse + AppB ->> DesktopAgent: intentResultRequest + DesktopAgent ->> AppB: intentResultResponse + DesktopAgent ->> AppA: raiseIntentResultResponse +``` + +:::tip + +See [`raiseIntent`](#raiseintent) below for further examples of message exchanges involved in raising intents and intent resolution. + +::: + +#### `broadcast()` + +Request and response used to implement the [`DesktopAgent.broadcast()`](../ref/DesktopAgent#broadcast) and [`Channel.broadcast()`](../ref/Channel#broadcast) API calls: + +- [`broadcastRequest`](https://fdc3.finos.org/schemas/next/api/broadcastRequest.schema.json) +- [`broadcastResponse`](https://fdc3.finos.org/schemas/next/api/broadcastResponse.schema.json) + +See [`addContextListener()`](#addcontextlistener) above for the `broadcastEvent` used to deliver the broadcast to other apps. + +#### `createPrivateChannel()` + +Request and response used to implement the [`createPrivateChannel()`](../ref/DesktopAgent#createprivatechannel) API call: + +- [`createPrivateChannelRequest`](https://fdc3.finos.org/schemas/next/api/createPrivateChannelRequest.schema.json) +- [`createPrivateChannelResponse`](https://fdc3.finos.org/schemas/next/api/createPrivateChannelResponse.schema.json) + +#### `findInstances()` + +Request and response used to implement the [`findInstances()`](../ref/DesktopAgent#findinstances) API call: + +- [`findInstancesRequest`](https://fdc3.finos.org/schemas/next/api/findInstancesRequest.schema.json) +- [`findInstancesResponse`](https://fdc3.finos.org/schemas/next/api/findInstancesResponse.schema.json) + +#### `findIntent()` + +Request and response used to implement the [`findIntent()`](../ref/DesktopAgent#findintent) API call: + +- [`findIntentRequest`](https://fdc3.finos.org/schemas/next/api/findIntentRequest.schema.json) +- [`findIntentResponse`](https://fdc3.finos.org/schemas/next/api/findIntentResponse.schema.json) + +#### `findIntentsByContext()` + +Request and response used to implement the [`findIntentsByContext()`](../ref/DesktopAgent#findintentsbycontext) API call: + +- [`findIntentsByContextRequest`](https://fdc3.finos.org/schemas/next/api/findIntentsByContextRequest.schema.json) +- [`findIntentsByContextResponse`](https://fdc3.finos.org/schemas/next/api/findIntentsByContextResponse.schema.json) + +#### `getAppMetadata()` + +Request and response used to implement the [`getAppMetadata()`](../ref/DesktopAgent#getappmetadata) API call: + +- [`getAppMetadataRequest`](https://fdc3.finos.org/schemas/next/api/getAppMetadataRequest.schema.json) +- [`getAppMetadataResponse`](https://fdc3.finos.org/schemas/next/api/getAppMetadataResponse.schema.json) + +#### `getCurrentChannel()` + +Request and response used to implement the [`getCurrentChannel()`](../ref/DesktopAgent#getcurrentchannel) API call: + +- [`getCurrentChannelRequest`](https://fdc3.finos.org/schemas/next/api/getCurrentChannelRequest.schema.json) +- [`getCurrentChannelResponse`](https://fdc3.finos.org/schemas/next/api/getCurrentChannelResponse.schema.json) + +#### `getInfo()` + +Request and response used to implement the [`getInfo()`](../ref/DesktopAgent#getinfo) API call: + +- [`getInfoRequest`](https://fdc3.finos.org/schemas/next/api/getInfoRequest.schema.json) +- [`getInfoResponse`](https://fdc3.finos.org/schemas/next/api/getInfoResponse.schema.json) + +#### `getOrCreateChannel()` + +Request and response used to implement the [`getOrCreateChannel()`](../ref/DesktopAgent#getorcreatechannel) API call: + +- [`getOrCreateChannelRequest`](https://fdc3.finos.org/schemas/next/api/getOrCreateChannelRequest.schema.json) +- [`getOrCreateChannelResponse`](https://fdc3.finos.org/schemas/next/api/getOrCreateChannelResponse.schema.json) + +#### `getUserChannels()` + +Request and response used to implement the [`getUserChannels()`](../ref/DesktopAgent#getuserchannels) API call: + +- [`getUserChannelsRequest`](https://fdc3.finos.org/schemas/next/api/getUserChannelsRequest.schema.json) +- [`getUserChannelsResponse`](https://fdc3.finos.org/schemas/next/api/getUserChannelsResponse.schema.json) + +#### `joinUserChannel()` + +Request and response used to implement the [`joinUserChannel()`](../ref/DesktopAgent#joinchannel) API call: + +- [`joinUserChannelRequest`](https://fdc3.finos.org/schemas/next/api/joinUserChannelRequest.schema.json) +- [`joinUserChannelResponse`](https://fdc3.finos.org/schemas/next/api/joinUserChannelResponse.schema.json) + +#### `leaveCurrentChannel()` + +Request and response used to implement the [`leaveCurrentChannel()`](../ref/DesktopAgent#leavecurrentchannel) API call: + +- [`leaveCurrentChannelRequest`](https://fdc3.finos.org/schemas/next/api/leaveCurrentChannelRequest.schema.json) +- [`leaveCurrentChannelResponse`](https://fdc3.finos.org/schemas/next/api/leaveCurrentChannelResponse.schema.json) + +#### `open()` + +Request and response used to implement the [`open()`](../ref/DesktopAgent#open) API call: + +- [`openRequest`](https://fdc3.finos.org/schemas/next/api/openRequest.schema.json) +- [`openResponse`](https://fdc3.finos.org/schemas/next/api/openResponse.schema.json) + +Where a context object is passed (e.g. `fdc3.open(app, context)`) the `broadcastEvent` message described above in [`addContextListener`](#addcontextlistener) should be used to deliver it after the context listener has been added: + +```mermaid +sequenceDiagram + AppA ->> DesktopAgent: openRequest
(with context) + break Desktop Agent launches AppB + DesktopAgent -->> AppB: Launch + AppB -->> DesktopAgent: Connect via WCP + end + AppB ->> DesktopAgent: addContextListenerRequest + DesktopAgent ->> AppB: addContextListenerResponse + DesktopAgent ->> AppB: broadcastEvent + DesktopAgent ->> AppA: openResponse
(with AppIdentifier) +``` + +However, if the app opened doesn't add a context listener within a timeout (defined by the Desktop Agent) then the `openResponse` should be sent with `AppTimeout` error from the [`OpenError`](../ref/Errors#openerror) enumeration. + +:::tip + +Desktop Agents MUST allow at least 15 seconds for an app to add a context listener before timing out (see [Desktop Agent API Standard Compliance](https://fdc3.finos.org/docs/next/api/spec#desktop-agent-api-standard-compliance) for more detail) and applications SHOULD add their listeners as soon as possible to keep the delay short (see the [addContextListener reference doc](https://fdc3.finos.org/docs/next/api/ref/DesktopAgent#addcontextlistener)). + +::: + +#### `raiseIntent()` + +Request and response used to implement the [`raiseIntent()`](../ref/DesktopAgent#raiseintent) API call: + +- [`raiseIntentRequest`](https://fdc3.finos.org/schemas/next/api/raiseIntentRequest.schema.json) +- [`raiseIntentResponse`](https://fdc3.finos.org/schemas/next/api/raiseIntentResponse.schema.json) + +An additional response message is provided for the delivery of an `IntentResult` from the resolving application to the raising application (which is collected via the [`IntentResolution.getResult()`](../ref/Metadata#intentresolution) API call), which should quote the `requestUuid` from the original `raiseIntentRequest`: + +- [`raiseIntentResultResponse`](https://fdc3.finos.org/schemas/next/api/raiseIntentResultResponse.schema.json) + +There is no request message to indicate a call to the `resolution.getResult()` function of `IntentResolution`. Hence, Desktop Agents should always send this additional response message to indicate the status of the intent handling function and to deliver its result (or void if none was returned). + +:::tip + +See [`addIntentListener`](#addintentlistener) above for details of the messages used for the resolving app to deliver the result to the Desktop Agent. + +::: + +Where there are multiple options for resolving a raised intent, there are two possible versions of the resulting message exchanges. Which to use depends on whether the Desktop Agent uses an intent resolver user interface (or other suitable mechanism) that it controls, or one injected into the application (for example an iframe injected by a `getAgent()` implementation into an application window) to perform resolution. + +When working with an injected interface, the Desktop Agent should respond with a `raiseIntentResponse` containing a `RaiseIntentNeedsResolutionResponsePayload`: + +```mermaid +--- +title: Intent resolution with injected Intent Resolver iframe +--- +sequenceDiagram + AppA ->> DesktopAgent: raiseIntentRequest + DesktopAgent ->> AppA: raiseIntentResponse + Note left of DesktopAgent: raiseIntentResponse includes a
RaiseIntentNeedsResolutionResponsePayload
containing an AppIntent + break when AppIntent return with multiple options + DesktopAgent --> AppA: getAgent displays IntentResolver + AppA --> DesktopAgent: User picks an option + end + AppA ->> DesktopAgent: raiseIntentRequest + Note left of DesktopAgent: New request includes a
specific 'app' target
and new requestUuid + DesktopAgent ->> AppB: intentEvent + DesktopAgent ->> AppA: raiseIntentResponse + AppB ->> DesktopAgent: intentResultRequest + DesktopAgent ->> AppB: intentResultResponse + DesktopAgent ->> AppA: raiseIntentResultResponse +``` + +Alternatively, if the Desktop Agent is able to provide its own user interface or another suitable means of resolving the intent, then it may do so and respond with a `raiseIntentResponse` containing a `RaiseIntentSuccessResponsePayload`: + +```mermaid +--- +title: Intent resolution with Desktop Agent provided Intent Resolver +--- +sequenceDiagram + AppA ->> DesktopAgent: raiseIntentRequest + break DA determines there are multiple options + DesktopAgent-->AppA: Desktop Agent displays an
IntentResolver UI + AppA-->DesktopAgent: User picks an option + end + DesktopAgent ->> AppB: intentEvent + DesktopAgent ->> AppA: raiseIntentResponse + Note left of DesktopAgent: DesktopAgent responds
to the original
raiseIntentRequest message with
a RaiseIntentSuccessResponsePayload + AppB ->> DesktopAgent: intentResultRequest + DesktopAgent ->> AppB: intentResultResponse + DesktopAgent ->> AppA: raiseIntentResultResponse +``` + +#### `raiseIntentForContext()` + +Request and response used to implement the [`raiseIntentForContext()`](../ref/DesktopAgent#raiseintentforcontext) API call: + +- [`raiseIntentForContextRequest`](https://fdc3.finos.org/schemas/next/api/raiseIntentForContextRequest.schema.json) +- [`raiseIntentForContextResponse`](https://fdc3.finos.org/schemas/next/api/raiseIntentForContextResponse.schema.json) + +Message exchanges for handling `raiseIntentForContext()` are the same as for `raiseIntent`, except for the substitution of `raiseIntentForContextRequest` for `raiseIntentRequest` and `raiseIntentForContextResponse` for `raiseIntentResponse`. Hence, please see [`raiseIntent`](#raiseintent) and [`addIntentListener`](#addintentlistener) for further details. + +### `Channel` + +Owing to the significant overlap between the FDC3 [`DesktopAgent`](../ref/DesktopAgent) and [`Channel`](../ref/Channel) interfaces, which includes the ability to retrieve and work with User channels as App Channels, most of the messaging for the `Channel` API is shared with `DesktopAgent`. Specifically, all messages defined in the the [`broadcast`](#broadcast) and [`addContextListener`](#addcontextlistener) sections above are reused, with a few minor differences to note: + +- When working with a specific channel, the `channelId` property in `addContextListenerRequest` should be set to the ID of the channel, where it is set to `null` to work with the current user channel. +- When receiving a `broadcastEvent` a `channelId` that is `null` indicates that the context was sent via a call to `fdc3.open` and does not relate to a channel. + +The following additional function is unique to the `Channel` interface: + +#### `getCurrentContext()` + +Request and response used to implement the [`Channel.getCurrentContext()`](../ref/Channel#getcurrentcontext) API call: + +- [`getCurrentContextRequest`](https://fdc3.finos.org/schemas/next/api/getCurrentContextRequest.schema.json) +- [`getCurrentContextResponse`](https://fdc3.finos.org/schemas/next/api/getCurrentContextResponse.schema.json) + +### `PrivateChannel` + +The [`PrivateChannel`](../ref/PrivateChannel) interface extends [`Channel`](../ref/Channel) with a number of additional functions that are supported by the following messages: + +#### `addEventListener()` + +Request and response used to implement the [`PrivateChannel.addEventListener`](../ref/PrivateChannel#addeventlistener) API call: + +- [`privateChanneladdEventListenerRequest`](https://fdc3.finos.org/schemas/next/api/privateChanneladdEventListenerRequest.schema.json) +- [`privateChanneladdEventListenerResponse`](https://fdc3.finos.org/schemas/next/api/privateChanneladdEventListenerResponse.schema.json) + +Event messages used to deliver events that have occurred: + +- [`privateChannelOnAddContextListenerEvent`](https://fdc3.finos.org/schemas/next/api/privateChannelOnAddContextListenerEvent.schema.json) +- [`privateChannelOnDisconnectEvent`](https://fdc3.finos.org/schemas/next/api/privateChannelOnDisconnectEvent.schema.json) +- [`privateChannelOnUnsubscribeEvent`](https://fdc3.finos.org/schemas/next/api/privateChannelOnUnsubscribeEvent.schema.json) + +:::tip + +The above messages may also be used to implement the deprecated [`onAddContextListener()`](../ref/PrivateChannel#onaddcontextlistener), [`onUnsubscribe`](../ref/PrivateChannel#onunsubscribe) and [`onDisconnect`](../ref/PrivateChannel#ondisconnect) functions of the `PrivateChannel` interface. + +::: + +Message exchange for removing the event listener [`Listener.unsubscribe`](../ref/Types#listener): + +- [`privateChannelUnsubscribeEventListenerRequest`](https://fdc3.finos.org/schemas/next/api/privateChannelUnsubscribeEventListenerRequest.schema.json) +- [`privateChannelUnsubscribeEventListenerResponse`](https://fdc3.finos.org/schemas/next/api/privateChannelUnsubscribeEventListenerResponse.schema.json) + +#### `disconnect()` + +Request and response used to implement the [`PrivateChannel.disconnect()`](../ref/PrivateChannel#disconnect) API call: + +- [`privateChannelDisconnectRequest`](https://fdc3.finos.org/schemas/next/api/privateChannelDisconnectRequest.schema.json) +- [`privateChannelDisconnectResponse`](https://fdc3.finos.org/schemas/next/api/privateChannelDisconnectResponse.schema.json) + +### Checking apps are alive + +Depending on the connection over which the Desktop Agent and app are connected, it may be necessary for the Desktop Agent to check whether the application is still alive. This can be done, either periodically or on demand (for example to validate options that will be provided in an [`AppIntent`](../ref/Metadata#appintent) as part of a `findIntentResponse` or `raiseIntentResponse` and displayed in an intent resolver interface), using the following message exchange: + +- [`heartbeatEvent`](https://fdc3.finos.org/schemas/next/api/heartbeatEvent.schema.json) +- [`heartbeatAcknowledgment`](https://fdc3.finos.org/schemas/next/api/heartbeatAcknowledgment.schema.json) + +As a Desktop Agent initiated exchange, it is initiated with an `AgentEvent` message and completed via an `AppRequest` message as an acknowledgement. + +:::tip + +Additional procedures are defined in the [Browser Resident Desktop Agents specification](./browserResidentDesktopAgents#disconnects) and [Web Connection Protocol](./webConnectionProtocol#step-5-disconnection) for the detection of app disconnection or closure. Implementations will often need to make use of multiple procedures to catch all forms of disconnection in a web browser. + +::: + +### Controlling injected User Interfaces + +Desktop Agent implementations, such as those based on the [Browser Resident Desktop Agents specification](./browserResidentDesktopAgents) and [Web Connection Protocol](./webConnectionProtocol), may either provide their own user interfaces (or other appropriate mechanisms) for the selection of User Channels or Intent Resolution, or they may work with implementations injected into the application (for example, as described in the [Web Connection Protocol](./webConnectionProtocol#providing-channel-selector-and-intent-resolver-uis) and implemented in [`getAgent()`](../ref/GetAgent)). + +Where injected user interfaces are used, standardized messaging is needed to communicate with those interfaces. This is provided in the DACP via the following 'iframe' messages, which are governed by the [`Fdc3UserInterfaceMessage`](https://fdc3.finos.org/schemas/next/api/fdc3UserInterface.schema.json) schema. The following messages are provided: + +- [`Fdc3UserInterfaceHello`](https://fdc3.finos.org/schemas/next/api/fdc3UserInterfaceHello.schema.json): Sent by the iframe to its `window.parent` frame to initiate communication and to provide initial CSS to apply to the frame. This message should have a `MessagePort` appended over which further communication will be conducted. +- [`Fdc3UserInterfaceHandshake`](https://fdc3.finos.org/schemas/next/api/fdc3UserInterfaceHandshake.schema.json): Response to the `Fdc3UserInterfaceHello` message sent by the application frame, which should be sent over the `MessagePort`. Includes details of the FDC3 version that the application is using. +- [`Fdc3UserInterfaceDrag`](https://fdc3.finos.org/schemas/next/api/fdc3UserInterfaceDrag.schema.json): Message sent by the iframe to indicate that it is being dragged to a new position and including offsets to indicate direction and distance. +- [`Fdc3UserInterfaceRestyle`](https://fdc3.finos.org/schemas/next/api/fdc3UserInterfaceRestyle.schema.json): Message sent by the iframe to indicate that its frame should have updated CSS applied to it, for example to support a channel selector interface that can be 'popped open' or an intent resolver that wishes to resize itself to show additional content. + +Messages are also provided that are specific to each user interface type provided by a Desktop Agent. The following messages are specific to Channel Selector user interfaces: + +- [`Fdc3UserInterfaceChannels`](https://fdc3.finos.org/schemas/next/api/fdc3UserInterfaceChannels.schema.json): Sent by the parent frame to initialize a Channel Selector user interface by providing metadata for the Desktop Agent's user channels and details of any channel that is already selected. This message will typically be sent by a `getAgent()` implementation immediately after the `fdc3UserInterfaceHandshake` and before making the injected iframe visible. +- [`Fdc3UserInterfaceChannelSelected`](https://fdc3.finos.org/schemas/next/api/fdc3UserInterfaceChannelSelected.schema.json): Sent by the Channel Selector to indicate that a channel has been selected or deselected. + +Messages specific to Intent Resolver user interfaces: + +- [`Fdc3UserInterfaceResolve`](https://fdc3.finos.org/schemas/next/api/fdc3UserInterfaceResolve.schema.json): Sent by the parent frame to initialize an Intent Resolver user interface to resolve a raised intent, before making the iframe visible. The message includes the context object sent with the intent and an array of one or more [`AppIntent`](../ref/Metadata#appintent) objects representing the resolution options for the intent ([`raiseIntent`](../ref/DesktopAgent#raiseintent)) or context ([`raiseIntentForContext`](../ref/DesktopAgent#raiseintentforcontext)) that was raised. +- [`Fdc3UserInterfaceResolveAction`](https://fdc3.finos.org/schemas/next/api/fdc3UserInterfaceResolveAction.schema.json): Sent by the Intent Resolver to indicate actions taken by the user in the interface, including hovering over an option, clicking a cancel button, or selecting a resolution option. The Intent Resolver should be hidden by the `getAgent()` implementation after a resolution option is selected to ensure that it does not interfere with user's ongoing interaction with the app's user interface. diff --git a/docs/api/specs/preloadDesktopAgents.md b/docs/api/specs/preloadDesktopAgents.md new file mode 100644 index 000000000..9e25259ce --- /dev/null +++ b/docs/api/specs/preloadDesktopAgents.md @@ -0,0 +1,28 @@ +--- +id: preloadDesktopAgents +sidebar_label: Preload Desktop Agents +title: Preload Desktop Agents (next) +--- + + +A Preload Desktop Agent is an FDC3 Desktop Agent (DA) supporting web applications that 'inject' or 'preload' scripts into web windows which provide access to an FDC3 Desktop Agent API implementation. This document specifies the required behavior for a Preload Desktop Agent (DA). + +:::info + +> The [getAgent() specification in the FDC3 Web Connection Protocol](webConnectionProtocol.md) relies on Preload DAs behaving as specified in this document. + +::: + +## Injecting the global FDC3 object + +Since FDC3 is typically available to the whole web application, Desktop Agents are expected to make the [`DesktopAgent`](../api/ref/DesktopAgent) interface available at a global level. Hence, a Preload Desktop Agent MUST provide the FDC3 API via a global accessible as `window.fdc3`. Implementors MAY additionally make the API available through modules, imports, or other means. + +The global `window.fdc3` MUST only be available after the API is ready to use. Implementors MUST provide a global `fdc3Ready` event that is fired when the API is ready for use. + +However, implementors SHOULD also ensure that the global is made available as soon as possible after the window is created to ensure that it can be detected by `getAgent()`. Queuing of requests to the API MAY be used to make the API available, while initialization is underway. + +:::note + +Prior to FDC3 2.2, apps were advised to check for the existence of the FDC3 API at `window.fdc3` and then add a listener for the `fdc3Ready` event if it was not found. This has since been superseded by the recommendation to use `getAgent()`, which handles those steps internally, alongside supporting FDC3 in web browsers ( via the [Browser Resident Desktop Agent spec](./browserResidentDesktopAgents)). + +::: diff --git a/docs/api/specs/webConnectionProtocol.md b/docs/api/specs/webConnectionProtocol.md new file mode 100644 index 000000000..775517679 --- /dev/null +++ b/docs/api/specs/webConnectionProtocol.md @@ -0,0 +1,384 @@ +--- +id: webConnectionProtocol +sidebar_label: Web Connection Protocol +title: Web Connection Protocol (next) +--- + +:::info _[@experimental](../fdc3-compliance#experimental-features)_ + +FDC3's Web Connection Protocol (WCP) is an experimental feature added to FDC3 in 2.2. Limited aspects of its design may change in future versions and it is exempted from the FDC3 Standard's normal versioning and deprecation polices in order to facilitate any necessary change. + +::: + +The FDC3 Web Connection Protocol (WCP) defines the procedure for a web-application to connect to an FDC3 Desktop Agent. The WCP is used to implement a [`getAgent()`](../ref/GetAgent) function in the [`@finos/fdc3` npm module](https://www.npmjs.com/package/@finos/fdc3), which is the recommended way for web applications to connect to a Desktop Agent. This specification details how it retrieves and provides the FDC3 `DesktopAgent` interface object and requirements that Desktop Agents MUST implement in order to support discovery and connection via `getAgent()`. Please see the [`getAgent` reference document](../ref/GetAgent.md) for its TypeScript definition and related types. + +:::tip + +The [`@finos/fdc3` npm module](https://www.npmjs.com/package/@finos/fdc3) provides a `getAgent()` implementation which app can use to connect to a Desktop Agent without having to interact with or understand the WCP directly. See [Supported Platforms](../supported-platforms) and the [`getAgent()`](../ref/GetAgent) reference page for more details on using `getAgent()` in an application. + +::: + +The WCP supports both interfaces to web-based Desktop Agents defined in the FDC3 Standard: + +- **Desktop Agent Preload**: An 'injected' or 'preloaded' Desktop Agent API implementation, typically provided by an [Electron](https://www.electronjs.org/) (or similar) container or browser extension, which is made available to web applications at `window.fdc3`. +- **Desktop Agent Proxy**: An interface to a web-based Desktop Agent (implementation of the Desktop Agent API) that uses the [Desktop Agent Communication Protocol (DACP)](./desktopAgentCommunicationProtocol) to communicate with a Desktop Agent implementation running in another frame or window, via the HTML Standard's Channel Messaging API ([MDN](https://developer.mozilla.org/en-US/docs/Web/API/Channel_Messaging_API), [HTML Living Standard](https://html.spec.whatwg.org/multipage/web-messaging.html)). + +The WCP allows FDC3-enabled applications to detect which FDC3 web-interface is present at runtime and returns a `DesktopAgent` interface implementation that the application can use to communicate, without the import of proprietary libraries or code. Hence, the WCP enables FDC3-enabled applications to be run within the scope of any standards compliant Desktop Agent without modification, enabling their developers to Write Once Run Anywhere (WORA). + +:::tip + +See the FDC3 [Glossary](../../fdc3-glossary) and [References](../../references.md) pages for definitions of terms and links to external APIs used throughout this document. + +::: + +:::tip + +Further details for implementing Preload Desktop Agents (which use a Desktop Agent Preload interface) or a Browser Resident Desktop Agent (which use a Desktop Agent Proxy interface) are available in the [Preload Desktop Agent](./preloadDesktopAgents) or [Browser Resident Desktop Agent Specification](./browserResidentDesktopAgents), respectively. + +::: + +## WCP Message Schemas + +There are a number of messages defined as part of the Web Connection Protocol. Definitions are provided in [JSON Schema](https://json-schema.org/) in the [FDC3 github repository](https://github.com/finos/FDC3/tree/fdc3-for-web/schemas/api). + +:::tip + +TypeScript types representing all DACP and WCP messages are generated from the JSON Schema source and can be imported from the [`@finos/fdc3` npm module](https://www.npmjs.com/package/@finos/fdc3): + +```ts +import { BrowserTypes } from "@finos/fdc3"; +``` + +::: + +WCP messages are derived from a base schema, [WCPConnectionStep](https://fdc3.finos.org/schemas/next/api/.schema.json), which defines a common structure for the messages: + +```json +{ + "type": "string", // string identifying the message type + "payload": { + //message payload fields defined for each message type + }, + "meta": { + "connectionAttemptUuid": "79be3ff9-7c05-4371-842a-cf08427c174d", + "timestamp": "2024-09-17T10:15:39+00:00" + } +} +``` + +A value for `meta.connectionAttemptUuid` should be generated as a version 4 UUID according to [IETF RFC 4122](https://datatracker.ietf.org/doc/html/rfc4122) at the start for the connection process and quoted in all subsequent messages, as described later in this document. + +`meta.timestamp` fields are formatted as strings, according to the format defined by [ISO 8601-1:2019](https://www.iso.org/standard/70907.html), which is produced in JavaScript via the `Date` class's `toISOString()` function, e.g. `(new Date()).toISOString()`. + +Messages defined as part of the Web Connection Protocol, which will be referenced later in this document, these are: + +- [`WCP1Hello`](https://fdc3.finos.org/schemas/next/api/WCP1Hello.schema.json) +- [`WCP2LoadUrl`](https://fdc3.finos.org/schemas/next/api/WCP2LoadUrl.schema.json) +- [`WCP3Handshake`](https://fdc3.finos.org/schemas/next/api/WCP3Handshake.schema.json) +- [`WCP4ValidateAppIdentity`](https://fdc3.finos.org/schemas/next/api/WCP4ValidateAppIdentity.schema.json) +- [`WCP5ValidateAppIdentityFailedResponse`](https://fdc3.finos.org/schemas/next/api/WCP5ValidateAppIdentityFailedResponse.schema.json) +- [`WCP5ValidateAppIdentityResponse`](https://fdc3.finos.org/schemas/next/api/WCP5ValidateAppIdentityResponse.schema.json) +- [`WCP6Goodbye`](https://fdc3.finos.org/schemas/next/api/WCP6Goodbye.schema.json) + +## Establishing Connectivity Using the Web Connection Protocol (WCP) + +The WCP algorithm (coordinated between the `getAgent()` implementation and Desktop Agent implementations) has four steps, followed by an optional disconnection step. Each step may contain sub-steps. + +1. Locate a Desktop Agent interface +2. Validate app & instance identity +3. Persist connection details to SessionStorage +4. Return DesktopAgent interface +5. Disconnect + +### Step 1: Locate a Desktop Agent interface + +#### 1.1 Check for a possible navigation or refresh event + +Check the SessionStorage key `FDC3-Desktop-Agent-Details` for a `DesktopAgentDetails` record. If it exists, then a navigation or refresh event may have occurred and the stored data MUST be sent when attempting to establish a connection to the DA. This ensures that the window can maintain a consistent `instanceId` between navigation or refresh events within an app. If it doesn't exist then proceed to step (2). + +Any data stored under the `FDC3-Desktop-Agent-Details` MUST conform to the [DesktopAgentDetails](../ref/GetAgent#persisted-connection-data) type. + +Existing `DesktopAgentDetails` records MUST be used to limit discovery actions (in the next step) to the same mechanism as previously used or to skip the discovery step entirely if an `agentUrl` exists, indicating that the connection should be established by loading the URL into a hidden iframe and initiating communication with that instead. + +If use of the persisted data fails to establish a connection to the DA then `getAgent()` should reject its promise with `AgentNotFound` error from the [`AgentError`](../ref/Errors#agenterror) enumeration. + +#### 1.2 Desktop Agent Discovery + +Next, attempt to discover whether Desktop Agent Preload or Desktop Agent Proxy interfaces are available, within a specified timeout. The optional `params.timeoutMs` argument to `getAgent()` allows an application to specify the timeout that should be used, with a default value of 750ms. Discovery of Desktop Agent Preload or Desktop Agent Proxy interfaces should be conducted in parallel where possible and the timeout cancelled as soon as an interface is discovered. If a `DesktopAgentDetails` record was found in the previous step, limit discovery to the interface specified, or, if an `agentUrl` property was specified in the `DesktopAgentDetails` record, skip the discovery step entirely and proceed to the next step. + +To discover a Desktop Agent Preload interface, check for the presence of an `fdc3` object in the global scope (i.e. `window.fdc3`). If it exists return it immediately. If it does not exist then add a listener for the global `fdc3Ready` event with the the specified timeout, e.g.: + +```ts +const discoverPreloadDA = async (timeoutMs: number): Promise => { + return new Promise((resolve, reject) => { + // if the global is already available resolve immediately + if (window.fdc3) { + resolve(window.fdc3); + } else { + // Setup a timeout to return a rejected promise + const timeoutId = setTimeout( + () => { + //clear the event listener to ignore a late event + window.removeEventListener("fdc3Ready", listener); + if (window.fdc3){ + resolve(window.fdc3); + } else { + reject("Desktop Agent Preload not found!"); + } + }, + timeoutMs + ); + //`fdc3Ready` event listener function + const listener = () => { + clearTimeout(timeoutId); + if (window.fdc3) { + resolve(window.fdc3); + } else { + reject("The `fdc3Ready` event fired, but `window.fdc3` Was not set!"); + } + }; + + // listen for the fdc3Ready event + window.addEventListener("fdc3Ready", listener, { once: true }); + } + }); +}; +``` + +To discover a Desktop Agent Proxy interface, locate all candidates for a `parent` window or frame by first checking the values of `window.opener` and `window.parent`. If `window.opener !== null` or `window.parent !== window` then they are candidates for a parent window or frame. As iframes can be nested we can also search for candidates that are parents of a parent frame, e.g.: + +```ts +const discoverProxyCandidates = (): WindowProxy[] => { + const candidates: WindowProxy[] = []; + //parent window + if (!!window.opener) { candidates.push(window.opener); } + + //parent frames + let currentWin = window; + while (currentWin.parent !== currentWin) { + candidates.push(currentWin.parent); + currentWin = currentWin.parent; + } + + //parent window of top-level parent frame + if (window !== currentWin && !!currentWin.opener) { + candidates.push(currentWin.opener); + } + return candidates; +} +``` + +Setup a timer for specified timeout, and then for each `candidate` found, attempt to establish communication with it as follows: + + 1. Add a listener (`candidate.addEventListener("message", (event) => {})`) to receive response messages from the `candidate`. + 2. Send a [`"WCP1Hello"`](https://fdc3.finos.org/schemas/next/api/WCP1Hello.schema.json) message to it via `postMessage`. + + ```ts + const hello = { + type: "WCP1Hello", + payload: { + identityUrl: identityUrl, + actualUrl: actualUrl, + fdc3Version: "2.2", + intentResolver: true, + channelSelector: true + }, + meta: { + connectionAttemptUuid: "bc96f1db-9b2b-465f-aab3-3870dc07b072", + timestamp: "2024-09-09T11:44:39+00:00" + } + }; + candidate.postMessage(hello, { targetOrigin: "*" }); + ``` + + Note that the `targetOrigin` is set to `*` as the origin of the Desktop Agent is not known at this point. + 3. Accept the first correct response received from a candidate. Correct responses MUST correspond to either the [`WCP2LoadUrl`](https://fdc3.finos.org/schemas/next/api/WCP2LoadUrl.schema.json) or [`WCP3Handshake`](https://fdc3.finos.org/schemas/next/api/WCP3Handshake.schema.json) message schemas and MUST quote the same `meta.connectionAttemptUuid` value provided in the original `WCP1Hello` message. Stop the timeout when a correct response is received. If no response is received from any candidate, the `getAgent()` implementation MAY retry sending the `WCP1Hello` message periodically until the timeout is reached. + 4. If a [`WCP3Handshake`](https://fdc3.finos.org/schemas/next/api/WCP3Handshake.schema.json) was received in the previous step, skip this step and move on to step 5. However, If a [`WCP2LoadUrl`](https://fdc3.finos.org/schemas/next/api/WCP2LoadUrl.schema.json) was received in the previous step: + - Create a hidden iframe within the page, set its URL to the URL provided by the `payload.iframeUrl` field of the message and add a handler to run when the iframe has loaded: + ```ts + const loadIframe = (url: string, loadedHandler: () => void): WindowProxy => { + const ifrm = document.createElement("iframe"); + iframe.onload = loadedHandler; + ifrm.src = url; + ifrm.style.width = "0"; + ifrm.style.height = "0"; + ifrm.style.visibility = "0"; + ifrm.ariaHidden = "true"; + document.body.appendChild(ifrm); + return ifrm.contentWindow; + }; + ``` + - Once the frame has loaded (i.e. when the `loadedHandler` in the above example runs), repeat steps 1-3 above substituting the iframe's `contentWindow` for the candidate window objects before proceeding to step 5. A new timeout should be used to limit the amount of time that the `getAgent()` implementation waits for a response. If the event that this subsequent timeout is exceeded, reject Error with the `ErrorOnConnect` message from the [`AgentError`](../ref/Errors#agenterror) enumeration. + + :::tip + + To ensure that the iframe is ready to receive the `WCP1Hello` message when the `load` event fires, implementations should call `window.addEventListener` for the `message` event synchronously and as early as possible. + + ::: + + 5. At this stage, a [`WCP3Handshake`](https://fdc3.finos.org/schemas/next/api/WCP3Handshake.schema.json) message should have been received from either a candidate parent or a hidden iframe created in step 4 above. This message MUST have a `MessagePort` appended to it, which is used for further communication with the Desktop Agent. + + Add a listener (`port.addEventListener("message", (event) => {})`) to receive messages from the selected `candidate`, before moving on to the next stage. + 6. If no candidates were found or no [`WCP3Handshake`](https://fdc3.finos.org/schemas/next/api/WCP3Handshake.schema.json) has been received by the time that the timeout expires, then neither a Desktop Agent Preload or Desktop Agent Proxy interface has been discovered. If this occurs, the `getAgent()` implementation will run any `failover` function provided as a parameter to `getAgent()`, allowing the application to provide an alternative means of connecting to or starting up a Desktop Agent. + + An async failover function may resolve to either a `DesktopAgent` implementation or the application may create either an iframe or open a new window, load an appropriate URL for a Desktop Agent implementation and resolve to its `WindowProxy` reference (e.g. `iframe.contentWindow` or the result of a call to `window.open(...)`). + + If the failover function resolves to a `DesktopAgent` implementation it should be immediately returned in the same way as a `window.fdc3` reference was and handled as if it represents a Desktop Agent Preload interface. + + If the failover function resolves to a `WindowProxy` object, repeat steps 1-3 & 5 above substituting the `WindowProxy` for the candidate window objects before proceeding to the next step. + + :::tip + + Where possible, iframe failover functions should wait for the iframe or window represented by a `WindowProxy` object to be ready to receive messages before resolving. For an iframe this is a case of waiting for the `load` event to fire. + + ::: + +### Step 2: Validate app & instance identity + +Apps and instances of them identify themselves so that DAs can positively associate them with their corresponding AppD records and any existing instance identity. + +In the current FDC3 version, no identity validation procedures are provided for Desktop Agent Preload interfaces. Hence, it is the responsibility of such implementations to validate the identity of apps within their scope and to ensure that they update their own record of the identity if it changes during the life of the window hosting the application (i.e. due to a navigation event). It is expected that FDC3 will adopt identity validation procedures for Desktop Agent Preload interfaces in future. + +#### 2.1 Determine App Identity + +In Desktop Agent Proxy interfaces, identity is ascertained via the [`WCP4ValidateAppIdentity`](/schemas/next/api/WCP4ValidateAppIdentity.schema.json) message, which should be the first message sent on the `MessagePort` received by the `getAgent()` implementation after receiving it via [`WCP3Handshake`](https://fdc3.finos.org/schemas/next/api/WCP3Handshake.schema.json). Any other messages sent via the `MessagePort` prior to successful validation of a [`WCP4ValidateAppIdentity`](/schemas/next/api/WCP4ValidateAppIdentity.schema.json) message should be ignored. + +An app identity is determined and an `appId` assigned by matching the application to an AppD record already known to the Desktop Agent, based on the `identityUrl` provided in the [`WCP4ValidateAppIdentity`](/schemas/next/api/WCP4ValidateAppIdentity.schema.json) message. An additional `actualUrl` field MUST also be provided to indicate whether the app overrode its `identityUrl` and to allow for logging. The origin (protocol, domain and port) of the `identityUrl`, `actualUrl` and the `MessageEvent.origin` field of the original `WCP1Hello` message that started the connection flow MUST all match. See the [Browser-Resident Desktop Agent Specification](./browserResidentDesktopAgents#validating-app-identity) for details of how to match an `identityUrl` to the `details.url` field of an AppD record. + +If the app identity is not recognized, the Desktop Agent MUST respond with a [WCP5ValidateAppIdentityFailedResponse](https://fdc3.finos.org/schemas/next/api/WCP5ValidateAppIdentityFailedResponse.schema.json) message and stop handling further messages on the `MessagePort`. On receiving this message, the `getAgent()` implementation should reject with an Error object with the `AccessDenied` message from the [`AgentError`](../ref/Errors#agenterror) enumeration. + +If the app identity is recognized the Desktop Agent will assign the appropriate appId and move on to determining the instance identity. + +#### 2.2 Determine Instance Identity + +If this instance of the application has connected to a Desktop Agent before and is reconnecting (due to a navigation or refresh event) then the optional `instanceId` and `instanceUuid` should be set in the [`WCP4ValidateAppIdentity`](/schemas/next/api/WCP4ValidateAppIdentity.schema.json) message. The Desktop Agent MUST use these values to determine if it recognizes the app instance identity and that it was previously applied to application with the same `appId`. + +An `instanceUuid` is used to validate instance identity because `instanceId` of an application is available to other apps through the FDC3 API and might be used to 'spoof' an identity. On the other hand, `instanceUuid` is only issued through the WCP to the specific app instance and is used as a shared secret to enable identity validation. However, as `SessionStorage` data may be cloned when new windows on the same origin are opened via `window.open()`, Desktop Agents MUST also compare the `WindowProxy` object (via the `==` operator) that the original `WCP1Hello` messages were received on to determine if they represent the same window. + +See the [Browser-Resident Desktop Agent Specification](./browserResidentDesktopAgents#validating-instance-identity) for further details of how instance identity is assigned. + +If no existing instance identity (`instanceId` and `instanceUuid`) is provided, or instance identity validation fails (as the `instanceUuid` is not known, or either the `appId` or `WindowProxy` objects don't match the previous connection), then the Desktop Agent MUST assign new `instanceId` and `instanceUuid` values. + +The Desktop Agent MUST then respond with a [WCP5ValidateAppIdentityResponse](https://fdc3.finos.org/schemas/next/api/WCP5ValidateAppIdentityResponse.schema.json) message containing the assigned `appId`, `instanceId` and `instanceUuid` values and the [`ImplementationMetadata`](../ref/Metadata#implementationmetadata) object for the Desktop Agent. This message indicates that the Desktop Agent will accept the application and we can begin processing [Desktop Agent Communication Protocol (DACP)](./desktopAgentCommunicationProtocol) messages relating to FDC3 API calls over the `MessagePort`. + +### Step 3: Persist DesktopAgentDetails to SessionStorage + +Once a connection is established, and the app and instance identity determined, a `DesktopAgentDetails` record MUST be stored in SessionStorage under the `FDC3-Desktop-Agent-Details` key by the `getAgent()` implementation. This record includes: + +- The `identityUrl` and `actualUrl` passed to `getAgent()`. +- The `appId`, `instanceId`, and `instanceUuid` assigned by the DA. +- An `agentUrl` field with the URL provided in any [`WCP2LoadUrl`](https://fdc3.finos.org/schemas/next/api/WCP2LoadUrl.schema.json) message that was received + - Used to skip sub-steps 1-3 in the discovery process described in Step 1.2. + - If no [`WCP2LoadUrl`](https://fdc3.finos.org/schemas/next/api/WCP2LoadUrl.schema.json) message was received, omit this field. +- An `agentType` field which indicates what type of connection to the DA was established + - Used to limit the discovery process in Step 1.2 above to only allow agents of the same type. + - the `getAgent()` implementation should determine what value to set, from the `WebDesktopAgentType` enumeration for this field based on what happened during the discovery process. + +See the [reference documentation for getAgent()](../ref/GetAgent#persisted-connection-data) for further details of the `DesktopAgentDetails` record that should be saved to SessionStorage. + +:::tip + +SessionStorage is ephemeral, only existing for the duration of the window's life. Hence, there is no concern with the key being overwritten or conflicting with other DAs. + +::: + +### Step 4: Resolve promise with DesktopAgent interface (step 4) + +Resolve the `getAgent()` promise with an object containing either a `DesktopAgent` implementation (that was found at `window.fdc3` or returned by a `failover` function) or a 'Desktop Agent Proxy' implementation (a class implementing the `DesktopAgent` interface that uses the [Desktop Agent Communication Protocol (DACP)](./desktopAgentCommunicationProtocol) to communicate with a Desktop Agent over the `MessagePort`). + +Where a `DesktopAgent` or 'Desktop Agent Proxy' implementation was successfully returned, any subsequent calls to `getAgent()` that are not preceded by a navigation or refresh event, should resolve to the same instance. + +### Step 5: Disconnection + +Desktop Agent Preload interfaces, as used in container-based Desktop Agent implementations, are usually able to track the lifecycle and current URL of windows that host web apps in their scope. Hence, there is currently no requirement nor means for an app to indicate that it is closing, rather it is the responsibility of the Desktop Agent to update its internal state when an app closes or changes identity. + +However, Browser Resident Desktop Agents working with a Desktop Agent Proxy interface may have more trouble tracking child windows and frames. Hence, a specific WCP message ([WCP6Goodbye](https://fdc3.finos.org/schemas/next/api/WCP6Goodbye.schema.json)) is provided for the `getAgent()` implementation to indicate that an app is disconnecting from the Desktop Agent and will not communicate further unless and until it reconnects via the WCP. The `getAgent()` implementation MUST listen for the `pagehide` event from the HTML Standard's [Page Life Cycle API](https://html.spec.whatwg.org/multipage/document-lifecycle.html#document-lifecycle) ([MDN](https://developer.mozilla.org/en-US/docs/Web/API/Window/pagehide_event), [Chrome for Developers](https://developer.chrome.com/docs/web-platform/page-lifecycle-api#developer-recommendations-for-each-state)) and send [WCP6Goodbye](https://fdc3.finos.org/schemas/next/api/WCP6Goodbye.schema.json) if it receives an event where the `persisted` property is `false`. + +As it is possible for a page to close without firing this event in some circumstances (e.g. where a browser render thread crashes), other procedures for detecting disconnection may also be used, these are described in the [Browser Resident Desktop Agents specification](./browserResidentDesktopAgents#disconnects) and [Desktop Agent Communication Protocol](./desktopAgentCommunicationProtocol#checking-apps-are-alive). + +### `getAgent()` Workflow Diagram + +The workflow defined in the Web Connection protocol for `getAgent()` is summarized in the below diagram: + +```mermaid +--- +title: "Web Connection Protocol Flowchart" +--- +flowchart TB + A1([DesktopAgent launches app]) --> A2["App calls getAgent()"] + A2 --> A3 + + subgraph getAgent ["getAgent()"] + A3["Check for DesktopAgentDetails in SessionStorage"] --> P1{"Does window.fdc3 exist?"} + P1 -->|yes|P2["Stop timeout"] + P2 --> P21["Save DesktopAgentDetails to SessionStorage"] + P1 -->|No|P3["Listen for fdc3Ready"] + P3 --> P31["fdc3Ready event fires"] + P31 --> P32["Stop timeout"] + P32 --> P33["Save DesktopAgentDetails to SessionStorage"] + + A3 --> B1{"Do parent refs exist?"} + B1 -->|yes|B11["Send WCP1Hello to all candidates"] + B11 --> B2["Receive WCP2LoadUrl"] + B2 --> B21["Stop timeout"] + B21 --> B22["Create hidden iframe with URL"] + B22 --> B23["Await iframe's load event"] + B23 --> B24["Send WCP1Hello to iframe"] + B24 --> B3["Receive WCP3Handshake with MessagePort"] + B3 --> B31["Stop timeout"] + B11 --> B3 + B31 --> B32["Send WCP4ValidateIdentity on MessagePort"] + B32 --> B321["Receive WCP5ValidateIdentityResponse"] + B321 --> B3211["Create DesktopAgentProxy to process DACP messages"] + B3211 --> B3212["Save DesktopAgentDetails to SessionStorage"] + B32 --> B322["Receive WCP5ValidateIdentityFailedResponse"] + + A3 --> T1["Set timeout"] + T1 --> T2["Timeout expires"] + T2 --> T3{"Was a failover fn provided"} + T3 -->|yes|T31["Run failover"] + T31 --> T311{"Check failover return type"} + T311 -->|WindowProxy|T3111["Send WCP1Hello via WindowProxy"] + T311 -->|DesktopAgent|T3112["Save DesktopAgentDetails to SessionStorage"] + T3111 --> B3 + end + P21 -->P22(["Resolve with window.fdc3"]) + P33 -->P34(["Resolve with window.fdc3"]) + B3212 --> B3213(["Resolve with DesktopAgentProxy"]) + B322 --> B3221(["Reject with AgentError.AccessDenied"]) + T3112 --> T31121(["Resolve with DesktopAgent"]) + T3 -->|no|T32(["Reject with AgentError.AgentNotFound"]) + T311 -->|other|T3113["Reject with AgentError.InvalidFailover"] +``` + +## Providing Channel Selector and Intent Resolver UIs + +Users of FDC3 Desktop Agents often need access to UI controls that allow them to select user channels or to resolve intents that have multiple resolution options. Whilst apps can implement these UIs on their own via data and API calls provided by the `DesktopAgent` API, Desktop Agents typically provide these interfaces themselves. + +However, Browser Resident Desktop Agents may have difficulty displaying user interfaces over applications for a variety of reasons (inability to inject code, lack of permissions to display popups, user gestures not following cross-origin comms, etc.), or may not (e.g. because they render applications in iframes within windows they control and can therefore display content over the iframe). The Web Connection Protocol and the `getAgent()` implementation based on it and incorporated into apps via the [`@finos/fdc3` npm module](https://www.npmjs.com/package/@finos/fdc3), is intended to help Desktop Agents deliver these UIs where necessary. + +```mermaid +flowchart LR + subgraph DA [Desktop Agent Window] + A[(Desktop Agent)] + end + A-->B["getAgent()"] + subgraph App [App Window] + B + subgraph iframe1 [iframe 1] + cs[Channel Selector] + end + subgraph iframe2 [iframe 2] + ir[Intent Resolver] + end + end + B-->cs + B-->ir +``` + +The WCP allows applications to indicate to the `getAgent()` implementation whether they need the UIs (they may not need one or the other based on their usage of the FDC3 API, or because they implement UIs themselves) and for Desktop Agents to provide custom implementations of them, or defer to reference implementations provided by the FDC3 Standard. This is achieved via the following messages: + +- [`WCP1Hello`](https://fdc3.finos.org/schemas/next/api/WCP1Hello.schema.json): Sent by an application and incorporating boolean `payload.intentResolver` and `payload.channelSelector` fields, which are set to `false` if either UI is not needed (defaults to `true`). +- [`WCP3Handshake`](https://fdc3.finos.org/schemas/next/api/WCP3Handshake.schema.json): Response sent by the Desktop Agent and incorporating `payload.intentResolverUrl` and `payload.channelSelectorUrl` fields, which should be set to the URL for each UI implementation that should be loaded into an iframe to provide the UI (defaults to URLs for reference UI implementations provided by the FDC3 project), or set to `false` to indicate that the respective UI is not needed. Setting these fields to `true` will cause the `getAgent()` implementation to use its default URLs representing a reference implementation of each UI. + +When UI iframes are created, the user interfaces may use the `Fdc3UserInterface` messages incorporated into the [Desktop Agent Communication Protocol (DACP)](./desktopAgentCommunicationProtocol#controlling-injected-user-interfaces) to communicate with the `getAgent()` implementation and through it the Desktop Agent. diff --git a/docs/api/supported-platforms.md b/docs/api/supported-platforms.md index e12b2e393..1f8c1a7c2 100644 --- a/docs/api/supported-platforms.md +++ b/docs/api/supported-platforms.md @@ -9,56 +9,36 @@ There are two main categories of platform: web and native, both of which are des ## Web -For a web application to be FDC3-enabled, it needs to run in the context of an environment or **_Platform Provider_** that makes the FDC3 API available to the application. This environment could be a browser extension, a web or native app, or a fully-fledged desktop container framework. +:::tip -### API Access & Globals - -The FDC3 API can be made available to an application through a number of different methods. In the case of web applications, a Desktop Agent MUST provide the FDC3 API via a global accessible as `window.fdc3`. Implementors MAY additionally make the API available through modules, imports, or other means. - -The global `window.fdc3` must only be available after the API is ready to use. To enable applications to avoid using the API before it is ready, implementors MUST provide a global `fdc3Ready` event that is fired when the API is ready for use. Implementations should first check for the existence of the FDC3 API and add a listener for this event if it is not found: +The recommended way to get access to the FDC3 Desktop Agent API in an application is to to import and call the `getAgent` function from the FDC3 NPM module, which supports all FDC3 Standard conformant Desktop Agents for web applications: ```ts -function fdc3Action() { - // Make some fdc3 API calls here -} - -if (window.fdc3) { - fdc3Action(); -} else { - window.addEventListener('fdc3Ready', fdc3Action); -} -``` - -Since FDC3 is typically available to the whole web application, Desktop Agents are expected to make the [`DesktopAgent`](ref/DesktopAgent) interface available at a global level. - -The global `window.fdc3` should only be available after the API is ready to use. To prevent the API from being used before it is ready, implementors should provide an `fdc3Ready` event. - -### Usage - -There are two main ways FDC3 can be used from web applications: - -#### 1. Direct Usage +import { DesktopAgent, getAgent, AgentError } from "@finos/fdc3"; -Simply rely on the global object being made available by your desktop agent, and address the API directly: +//... -```js -function sendData() { - window.fdc3.broadcast({ - type: 'fdc3.instrument', - id: { ticker: 'AAPL' } - }) +try { + const desktopAgent: DesktopAgent = await getAgent(); + //do FDC3 things here +} catch (e: AgentError) { + //connection failed } -if (window.fdc3) { - sendData(); -} else { - window.addEventListener("fdc3Ready", sendData); -} +//OR + +getAgent().then((desktopAgent: DesktopAgent) => { + //do FDC3 things here +}).catch((e: AgentError) => { + //connection failed +}); ``` -#### 2. NPM Wrapper +[For more details on the getAgent() function and arguments you can pass to it, see its reference page.](ref/GetAgent) + +::: -FDC3 offers the [`@finos/fdc3` npm package](https://www.npmjs.com/package/@finos/fdc3) that can be used by web applications to target operations from the [API Specification](./spec) in a consistent way. Each FDC3-compliant desktop agent that the application runs in, can then provide an implementation of the FDC3 API operations. +For a web application to use the FDC3 API it needs to retrieve a copy of the `DesktopAgent` API interface, which it will use to communicate with the Desktop Agent (this interface is often referred to as the `fdc3` object or the "FDC3 API"). FDC3 offers the [`@finos/fdc3` npm package](https://www.npmjs.com/package/@finos/fdc3) that can be used by web applications to retrieve a `DesktopAgent` interface and to provide typing. Each FDC3-compliant Desktop Agent that the application runs in, can then provide an implementation of the FDC3 API operations. import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; @@ -87,43 +67,88 @@ pnpm install @finos/fdc3
-The npm package provides a wrapper around FDC3, allowing you to use it with ES6 import syntax: +There are two standardized types of interface to a DA that a web application may use (which is appropriate depends on where the web application is run): -```javascript -import * as fdc3 from '@finos/fdc3'; +- **Desktop Agent Preload**: Used where the Desktop Agent is able to inject the the `DesktopAgent` API at `window.fdc3` allowing an app to access it directly, for example in an Electron app or where a browser Browser Extension is in use. +- **Desktop Agent Proxy**: Used when running in a standard web browser (without a browser extension or similar customization). The Desktop Agent will often be running in a different window or frame to the application and MUST be communicated with via cross-document messaging with `postMessage` and `MessagePorts` (see the [HTML5 Living Standard](https://html.spec.whatwg.org/multipage/web-messaging.html) for more details). A 'proxy' class implementing the Desktop Agent API is used to abstract the details of cross-document messaging, allowing the application to work with the FDC3 API directly. -await fdc3.raiseIntent('ViewAnalysis', { - type: 'fdc3.instrument', - id: { ticker: 'AAPL' } -}); +The FDC3 Standard defines a [Web Connection Protocol (WCP)](specs/webConnectionProtocol) that allows apps to work with either interface, by detecting which is applicable, and [Desktop Agent Communication Protocol (DACP)](../specs/desktopAgentCommunicationProtocol) that standardizes the messaging protocol used for cross-document messaging over `postMessage` and `MessagePorts` in a web browser. + +The FDC3 NPM module implements the `getAgent()` function defined by WCP and can return an injected Desktop Agent, a Desktop Agent Proxy, or other Desktop Agent implementation enabled by a non-standard interface. + +Hence, FDC3 apps SHOULD obtain access to a `DesktopAgent` object (`fdc3`) by importing or loading the `@finos/fdc3` library and then calling the provided `getAgent()` function, ensuring that they can support any of the standardized interfaces. + +:::info + +In prior versions of FDC3 (<= 2.1) Apps were required to use the 'Desktop Agent Preload' interface, i.e. they relied on the existence of the `window.fdc3` object, which meant that apps running in a standard web browser had to import libraries specific to the Desktop Agent implementation in use. From FDC3 2.2 onwards the 'Desktop Agent Proxy' interface is available, which allows apps in a standard web browser to connect to any Desktop Agent that implements that interface. + +Hence, from FDC3 2.2 onwards apps SHOULD call the `getAgent()` to retrieve a `DesktopAgent` API interface. + +::: + +As web applications can navigate to or be navigated by users to different URLs and become different applications, validation of apps identity is often necessary. The web application's current URL is passed to web browser-based Desktop Agents to allow them to establish the app's identity - usually connecting it with an App Directory record already known to the Desktop Agent. For more details on identity validation see the Identity Validation section of the [Web Connection Protocol (WCP)](specs/webConnectionProtocol). + +### Usage + +Once you've retrieved a `DesktopAgent` interface, there are two main ways FDC3 can be used from web applications: + +#### 1. Direct Usage + +Simply use the interface you've retrieved and address the API directly: + +```js +import { DesktopAgent, getAgent } from "@finos/fdc3"; + +async function sendData(desktopAgent: DesktopAgent) { + await desktopAgent.broadcast({ + type: "fdc3.instrument", + id: { ticker: "AAPL" } + }); +} + +const desktopAgent: DesktopAgent = await getAgent(); +await sendData(desktopAgent); ``` -It also includes a helper function you can use to wait for FDC3 to become available: +#### 2. ES6-style Function Wrappers -```javascript -import { fdc3Ready, addIntentListener } from '@finos/fdc3' +The npm package provides a wrapper around FDC3, allowing you to use it with ES6 import syntax: -await fdc3Ready(); +```javascript +import { raiseIntent } from "@finos/fdc3"; -const listener = await addIntentListener('ViewAnalysis', instrument => { - // handle intent +await raiseIntent("ViewAnalysis", { + type: "fdc3.instrument", + id: { ticker: "AAPL" } }); ``` +:::tip + +Please note that the wrapper functions will not work with the `dontSetWindowFdc3` parameter to `getAgent()` set to `true` as they rely on finding the `DesktopAgent` reference at `window.fdc3`. + +::: + ## Native +The FDC3 Standard currently only defines language specific API bindings for JavaScript/TypeScript and .NET, but is intended to be implemented in other languages (which can make use of the [Desktop Agent Communication Protocol (DACP)](../specs/desktopAgentCommunicationProtocol) as a wire protocol, but need to define a suitable connection protocol, which includes a defined communication channel to do so). + +Hence, for a native application to be FDC3-enabled, it needs to either: + +- Make use of a shared library (such as a .NET DLL or JAR file) that provides it with an implementation of the FDC3 API (which ties it to a specific Desktop Agent implementation). +- Model itself as a Desktop Agent (rather than just an app working with one) and use the Agent Bridging protocol to connect to a Desktop Agent Bridge and work through it to interoperate with apps managed by other Desktop Agents. + ### .NET -For a .NET application to be FDC3-enabled, it needs to run in the context of a platform provider that makes the FDC3 API available. The manner in which you get a reference to the desktop agent can be highly dependent on the provider chosen. For those looking to implement your own desktop agent, a recommended and typical design is to register an instance of the desktop agent at startup which can be injected into any class constructors that need references through inversion of control. More details for creating your own DesktopAgent can be found in the [fdc3-dotnet repository](https://github.com/finos/fdc3-dotnet). +For a .NET application to be FDC3-enabled, it needs to run in the context of a platform provider that makes the FDC3 API available. The manner in which you get a reference to the desktop agent can be highly dependent on the provider chosen. For those looking to implement your own desktop agent, a recommended and typical design is to register an instance of the Desktop Agent at startup which can be injected into any class constructors that need references through inversion of control. More details for creating your own DesktopAgent can be found in the [fdc3-dotnet repository](https://github.com/finos/fdc3-dotnet). #### Usage FDC3 offers the [`Finos.Fdc3` NuGet package](https://www.nuget.org/packages/Finos.Fdc3) that can be used by .NET applications to target operations from the [API Specification](./spec) in a consistent way. Each FDC3-compliant desktop agent that the application runs in, can then provide an implementation of the FDC3 API operations. - ## Hybrid -In a hybrid application, a standalone native application incorporates a web view, within which a web application runs. This may be considered a special case of the web platform where all platform-provider requirements for web applications must be satisfied, but it is the responsibility of the associated native application, rather than a platform provider, to ensure they are fulfilled. This may be achieved, for example, by injecting an implementation of the DesktopAgent API and ensuring that it is accessible at the usual location, `window.fdc3`. +In a hybrid application, a standalone native application incorporates a web view, within which a web application runs. This may be considered a special case of the web platform where all platform-provider requirements for web applications must be satisfied, but it is the responsibility of the associated native application, rather than a platform provider, to ensure they are fulfilled. This may be achieved via either of the defined web interfaces, i.e. by injecting an implementation of the DesktopAgent API at `window.fdc3` or via the FDC3 Web Connection Protocol (`postMessage`). ## Compliance diff --git a/docs/fdc3-glossary.md b/docs/fdc3-glossary.md index 6fa5a970c..db7416cce 100644 --- a/docs/fdc3-glossary.md +++ b/docs/fdc3-glossary.md @@ -20,23 +20,34 @@ For the purposes of this Standard, the following definitions apply. Other terms - **application-specific intent**: A custom intent defined by an application or applications, independent of the Standard. - **Bridge**: Shorthand for Desktop Agent Bridge. - **bridging**: Shorthand for the exchange of messages across a Desktop Agent Bridge for the purposes of extending interop between apps managed by different Desktop Agents. +- **Bridge Connection Protocol (BCP)**: A defined set of steps for a Desktop Agent to connect to a Desktop Agent Bridge. +- **Bridge Messaging Protocol (BMP)**: Protocol for Desktop Agents to communicate with each other over a Desktop Agent Bridge. +**Browser Resident Desktop Agent (DA)**: A Desktop Agent loaded in a window or frame within a web browser (in contrast to a Desktop Agent that "injects" a global fdc3 object) that is communicated with via a Desktop Agent Proxy. - **Channel**: A grouping of apps for the purposes of sharing stateful pieces of data. A secondary interface of the FDC3 API. - **context channels**: A mechanism to allow sets of apps to share stateful pieces of data among themselves, and to be alerted when that data changes. - **context**: Shorthand for context data. - **context data**: Objects encoding common identifiers and data in a standardized format that can be passed between apps via context channels or used in conjunction with intents to invoke actions creating a seamless cross-application workflow. Diverse context data types are created to encode different types of data, each having their own _type_ field and unique set of data fields. -- **DAB**: Acronym of Desktop Agent Bridge. - **Desktop Agent**: A desktop component (or aggregate of components) that serves as a launcher and message router (broker) for applications in its domain. The primary interface of the FDC3 API. -- **Desktop Agent Bridge**: An independent service that Desktop Agents connect to which allows them to relay requests to other Desktop Agents also connected to the bridge, allowing FDC3-based interop to extend across multiple Desktop Agents and machines. +- **Desktop Agent Bridge (DAB)**: An independent service that Desktop Agents connect to which allows them to relay requests to other Desktop Agents also connected to the bridge, allowing FDC3-based interop to extend across multiple Desktop Agents and machines. +- **Desktop Agent Communication Protocol (DACP)**: JSON communication protocol for the Desktop Agent API. Used by a Desktop Agent Proxy interface over the Channel Messaging API (as specified by the Web Connection Protocol) to communicate with a Desktop Agent running in another window/frame. +- **Desktop Agent Preload**: An 'injected' or 'preloaded' Desktop Agent API implementation, typically provided by an electron (or similar) container or browser extension, which is made available to web applications at `window.fdc3` and may be returned by the `getAgent()` function defined in the FDC3 Web Connection Protocol. +- **Desktop Agent Proxy**: An interface to a web-based Desktop Agent (implementation of the Desktop Agent API) that uses the Web Connection Protocol and Desktop Agent Communication protocol to communicate with a Desktop Agent implementation running in another frame or window. Returned by the `getAgent()` function provided by the FDC3 NPM module where a browser-based Desktop Agent is detected. - **FDC3 API**: A baseline, consistent developer interface for interoperability between applications. - **GUID**: Globally Unique IDentifier, synonymous with UUID. Defined by [IETF RFC4122](references). - **interop**: Shorthand for interoperability. - **interoperability**: the ability of software applications to exchange and make use of information and invoke specified actions. - **intent**: A verb, with a pre-agreed meaning (expected behavior), used to invoke an action between applications. A set of such verbs can, in conjunction with Context Data acting as nouns, be used to put together common cross-application workflows on the financial desktop. - **Listener**: API interface which allows unsubscribing from Intents or Context Channels. +- **MessageChannel**: An interface defined by the [HTML Standard's Channel Messaging API](https://html.spec.whatwg.org/multipage/web-messaging.html#channel-messaging) for a two-way pipe with a `MessagePort` at each end, used to implement communication between code running in different browsing contexts. Used by the Web Connection Protocol. +- **MessagePort**: An interface defined by the [HTML Standard's Channel Messaging API](https://html.spec.whatwg.org/multipage/web-messaging.html#channel-messaging) used to transmit and receive messages over a `MessageChannel`. Each channel has two message ports. Data sent through one port is received by the other port, and vice versa. Used by the Web Connection Protocol. - **Originating App**: The application that sent a particular context message or raised an intent. +- **Parent frame**: A browser window or frame that creates the window or iframe in which an application runs. (The parent provides a `WindowProxy` object which is used by Web Connection Protocol). - **Platform Provider**: An environment that provides an implementation of the FDC3 API that applications can use. - **raising an intent**: The act of requesting, via the FDC3 API/Desktop Agent that a specified action be performed by another application, using specified context data as input. - **resolver**: A facility of a Desktop Agent used to map a raised intent and associated context object to an application that will perform the action represented by the intent, using the context object as input. Where multiple applications can resolve the intent, a resolver will often display a user-interface allowing a user to pick from the available applications that support the intent and type of context supplied. - **resolving an intent**: The act of mapping a specified intent and context object to an application. +**SessionStorage**: A JavaScript storage API defined by the HTML Standard's Web Storage API](https://html.spec.whatwg.org/multipage/webstorage.html#webstorage) that persists data for web apps within the scope of a specific window or tab. SessionStorage is identical to the LocalStorage API but is scoped to a particular window/tab, as defined by the HTML Standard: - **standard intent**: An intent defined by this Standard. - **UUID**: Universally Unique IDentifier, synonymous with GUID. Defined by [IETF RFC4122](references). +- **Web Connection Protocol (WCP)**: A defined set of steps for a web application to connect to Desktop Agents that implement any of the interfaces defined for web applications in the FDC3 Standard, including both preloaded Desktop Agent interfaces and Browser-based Desktop Agents that work with a Desktop Agent Proxy. +- **WindowProxy**: An interface defined by the HTML standard that proxies a remote Window object: . WindowProxy objects are used for communication via `postMessage` as part of the Web Connection Protocol. \ No newline at end of file diff --git a/docs/references.md b/docs/references.md index 379c5342d..da23f8cf7 100644 --- a/docs/references.md +++ b/docs/references.md @@ -8,8 +8,12 @@ sidebar_label: References The following normative documents contain provisions, which, through reference in this text, constitute provisions of this Standard. For dated references, subsequent amendments to, or revisions of, any of these publications do not apply. However, parties to agreements based on this Standard are encouraged to investigate the possibility of applying the most recent editions of the normative documents indicated below. For undated references, the latest edition of the normative document referred to applies: - **Apache 2.0 open-source license**, . -- **Community Specification license**, +- **Community Specification license**, . +- **HTML Living Standard**, . +- **HTML Standard's Channel Messaging API**, . +- **HTML Standard's Web Storage API**, . - **ISO 3166-1**, _Codes for the representation of names of countries and their subdivisions – Part 1: Country codes_, . +- **ISO 4217:2015**, _Codes for the representation of currencies_, . - **ISO 8601-1:2019**, _Date and time — Representations for information interchange — Part 1: Basic rules_, - **JSON Schema**, . - **OpenAPI Standard v3.0**, . diff --git a/package.json b/package.json index e525b70df..be3b08bb4 100644 --- a/package.json +++ b/package.json @@ -20,18 +20,18 @@ "scripts": { "clean": "rimraf dist", "start": "rollup -c rollup.config.js --bundleConfigAsCjs -w", - "prebuild": "npm run clean && npm run typegen && npm run typegen-bridging && npm run lint", + "prebuild": "npm run clean && npm run typegen && npm run typegen-browser && npm run typegen-bridging && npm run lint", "build": "rollup -c rollup.config.js --silent --bundleConfigAsCjs", "test": "jest --verbose", "lint": "eslint src/ test/ --ext .ts --fix", "prepack": "npm run build", - "typegen": "node s2tQuicktypeUtil.js schemas/context src/context/ContextTypes.ts", - "typegen-bridging": "node s2tQuicktypeUtil.js schemas/api schemas/bridging schemas/context/context.schema.json src/bridging/BridgingTypes.ts", - "schema-2-markdown": "node schema2Markdown.js" + "typegen": "cd schemas && node ../s2tQuicktypeUtil.js context ../src/context/ContextTypes.ts", + "typegen-browser": "cd schemas && node ../s2tQuicktypeUtil.js api/api.schema.json api/common.schema.json context/context.schema.json api ../src/api/BrowserTypes.ts", + "typegen-bridging": "cd schemas && node ../s2tQuicktypeUtil.js api/api.schema.json api/common.schema.json api/broadcastRequest.schema.json api/findInstancesRequest.schema.json api/findInstancesResponse.schema.json api/findIntentRequest.schema.json api/findIntentResponse.schema.json api/findIntentsByContextRequest.schema.json api/findIntentsByContextResponse.schema.json api/getAppMetadataRequest.schema.json api/getAppMetadataResponse.schema.json api/openRequest.schema.json api/openResponse.schema.json api/raiseIntentRequest.schema.json api/raiseIntentResponse.schema.json api/raiseIntentResultResponse.schema.json context/context.schema.json bridging ../src/bridging/BridgingTypes.ts" }, "husky": { "hooks": { - "pre-commit": "npm run lint" + "pre-commit": "npm run prebuild" } }, "prettier": { diff --git a/s2tQuicktypeUtil.js b/s2tQuicktypeUtil.js index 6f5672328..bd0c7a855 100644 --- a/s2tQuicktypeUtil.js +++ b/s2tQuicktypeUtil.js @@ -7,44 +7,66 @@ * quicktype bug in command line argument handling (where a directory is used * as input the source language argument is ignored which causes our schemas * to be interpreted as JSON input, rather than JSONSchema). - * Bug issue: + * + * Individual file arguments will be interpreted as 'additional' schema files + * that will be referenced from the other schemas and will not have top-level output + * schemas generated, while folders will be listed and the schema files they contain + * added as inputs and will have top-level types generated. + * * */ const path = require('path'); const fs = require('fs'); +const { forEachChild } = require('typescript'); const exec = require('child_process').exec; const args = process.argv.slice(2); const outputFile = args.pop(); const inputs = args; +const toProcess = []; -console.log('Inputs: ' + inputs.join(' | ')); +console.log('Inputs schema files: ' + inputs.join(' | ')); console.log('Output file argument: ' + outputFile); let sources = ''; +let additionalSchemaFiles = '' -let dirIndex = 0; +//skip duplicate paths (we might want to specify some files to go first, and might duplicate them) +const allPaths = new Set(); -while (dirIndex < inputs.length) { - if (inputs[dirIndex].endsWith('.schema.json')) { - sources += `--src ${path.join(inputs[dirIndex])} `; +const addAPath = (aPath,paths,sources,type) => { + if (!paths.has(aPath)) { + paths.add(aPath) + return sources + ` ${type} ${aPath}`; } else { - fs.readdirSync(inputs[dirIndex], { withFileTypes: true }).forEach(file => { + console.log(`skipping duplicate path ${aPath}`); + return sources; + } +} + +//process the content of folders to produce code for top-level types +let inputIndex = 0; +while (inputIndex < inputs.length) { + if (inputs[inputIndex].endsWith('.schema.json')) { + //add individual files with -S as additional schema files used in references (rather than ones that need a top-level output) + additionalSchemaFiles = addAPath(path.join(inputs[inputIndex]),allPaths,additionalSchemaFiles, "-S"); + } else { + fs.readdirSync(inputs[inputIndex], { withFileTypes: true }).forEach(file => { if (file.isDirectory()) { - inputs.push(path.join(inputs[dirIndex], file.name)); + inputs.push(path.join(inputs[inputIndex], file.name)); } else if (file.name.endsWith('.schema.json')) { - sources += `--src ${path.join(inputs[dirIndex], file.name)} `; + sources = addAPath(path.join(inputs[inputIndex], file.name),allPaths,sources, "--src"); } }); } - dirIndex++; + inputIndex++; } // Normalise path to local quicktype executable. //const quicktypeExec = "node " + ["..","quicktype","dist","index.js"].join(path.sep); -const quicktypeExec = ['.', 'node_modules', '.bin', 'quicktype'].join(path.sep); +const quicktypeExec = ['..', 'node_modules', '.bin', 'quicktype'].join(path.sep); -const command = `${quicktypeExec} --prefer-const-values --prefer-unions -s schema -o ${outputFile} ${sources}`; +const command = `${quicktypeExec} --prefer-const-values --prefer-unions -s schema -o ${outputFile} ${additionalSchemaFiles} ${sources}`; console.log('command to run: ' + command); exec(command, function(error, stdout, stderr) { diff --git a/schemas/api/README.md b/schemas/api/README.md index c782f2e7a..95457be02 100644 --- a/schemas/api/README.md +++ b/schemas/api/README.md @@ -1,10 +1,29 @@ # Intro -Quicktype, the chosen generation tool currently has some limitations that prevent fully automatic schema generation from the existing TS types. For example it can not handle interfaces that contain methods in their definition. It also fails to generate schemas even if a type contains unused references to other types or interfaces that contain async functions (Promise return types). Therefore, in order to generate the `api\schemas\api.schema.json` some manual intervention was needed. +The _schemas/api_ folder contains JSONSchema definitions that are used to implement wire protocols for an app working with a Desktop Agent, and for import into the Bridging wire protocols that shares many of the same structures. -Once these limitations are not an issue the `api\schemas\t2sQuicktypeUtil.js` script should be moved to the root level of the project and a new npm script `"api-schema-gen": "node t2sQuicktypeUtil.js src/api schemas/api/api.schema.json"` should be added. +Please note: Quicktype, the chosen generation tool currently has some limitations that prevent fully automatic schema generation from the existing TS types. For example it can not handle interfaces that contain methods in their definition (as you can't define methods in JSON). It also fails to generate schemas even if a type contains unused references to other types or interfaces that contain async functions (Promise return types). Therefore, in order to generate the `api\schemas\api.schema.json` some manual intervention was needed. -`api\schemas\api.schema.json` - partially auto-generated schema from the existing `src\api` types. -`api\schemas\baseImplementationMetadata.schema.json` - Used by bridging types that leave out the metadata of the calling application as it does not apply to bridging. -`api\schemas\intentResolution.schema.json` - At the moment it is not possible to auto-generate this due to limitations in the generation tool (quicktype) -`api\schemas\t2sQuicktypeUtil.js` - Script used to run the generation of the schema from the types. Should be moved to the root level of the repo once fully-automated generation can be achieved. +Once these limitations are not an issue the `api\schemas\t2sQuicktypeUtil.js` script should be moved to the root level of the project and a new npm script `"api-schema-gen": "node t2sQuicktypeUtil.js src/api schemas/api/api.schema.json"` should be added. Alternatively, schemas (for API types) may be manually maintained against the matching TypeScript definitions + +Contents: + +- `api\schemas\t2sQuicktypeUtil.js` - Script used to run the generation of the schema from the types. Should be moved to the root level of the repo once fully-automated generation can be achieved. +- `api\schemas\api.schema.json` - partially auto-generated schema from the existing `src\api` types and metadata objects. +- `api\schemas\common.schema.json` - common element definitions referenced in multiple other schemas in both the API and Bridging API protocols. +- `api\schemas\appRequest.schema.json` - The base message definition that requests from an app to the DA are derived from. +- `api\schemas\agentResponse.schema.json` - The base message definition that API call response messages from a DA to an app are derived from. +- `api\schemas\agentEvent.schema.json` - The base message definition that event messages from a DA to an app are derived from. +- `api\schemas\*Request.schema.json` - Schemas defining request messages sent from apps to Desktop Agents. +- `api\schemas\*Response.schema.json` - Schemas defining responses from DAs to apps for request messages (sent from apps to Desktop Agents). +- `api\schemas\*Event.schema.json` - Schemas defining event messages sent from Desktop Agents to Apps. + +Please note that when adding a particular message type, that it needs its own schema file, which will declare the type (string). That type string MUST also be added to an enumeration in the base message schema it was derived from - each base message schema (appRequest, agentResponse, agentEvent) has an enumeration of the valid types and it must appear in that or the message will not validate. Unhelpfully, if you've forgotten to do that Quicktype will only report: + +``` +Error: Internal error: We got an empty string type. +``` + +or another similar error - its not always the same one! + +It can be very hard to figure out in which file the problem occurs. Generally, to figure out where an issue is, you can enable Quicktype's debug output by adding `--debug all` or `--debug print-schema-resolving` to the arguments assembled in s2tQuicktypeUtil.js or by taking the command it constructs (printed to the console) and manually add the option and re-run the command. If you're lucky, the error will be hit during the resolution steps which will point to the file(s) with an issue (often a disagreement between types combined with `allOf`). diff --git a/schemas/api/WCP1Hello.schema.json b/schemas/api/WCP1Hello.schema.json new file mode 100644 index 000000000..452193d1f --- /dev/null +++ b/schemas/api/WCP1Hello.schema.json @@ -0,0 +1,67 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/WCP1Hello.schema.json", + "title": "Web Connection Protocol 1 Hello", + "description": "Hello message sent by an application to a parent window or frame when attempting to establish connectivity to a Desktop Agent", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/WCP1HelloBase" + }, + { + "$ref": "WCPConnectionStep.schema.json" + } + ], + "$defs": { + "WCP1HelloBase": { + "type": "object", + "properties": { + "type": { + "title": "WCP1Hello Message Type", + "const": "WCP1Hello" + }, + "payload": { + "title": "WCP1Hello Payload", + "type": "object", + "properties": { + "identityUrl": { + "title": "Identity URL", + "description": "URL to use for the identity of the application. Desktop Agents MUST validate that the origin of the message matches the URL, but MAY implement custom comparison logic.", + "type": "string", + "format": "uri" + }, + "actualUrl": { + "title": "Actual URL", + "description": "The current URL of the page attempting to connect. This may differ from the identityUrl, but the origins MUST match.", + "type": "string", + "format": "uri" + }, + "fdc3Version": { + "title": "FDC3 version", + "description": "The version of FDC3 API that the app supports.", + "type": "string" + }, + "intentResolver": { + "title": "Intent Resolver Required", + "description": "A flag that may be used to indicate that an intent resolver is or is not required. Set to `false` if no intents, or only targeted intents, are raised.", + "type": "boolean" + }, + "channelSelector": { + "title": "Channel Selector Required", + "description": "A flag that may be used to indicate that a channel selector user interface is or is not required. Set to `false` if the app includes its own interface for selecting channels or does not work with user channels.", + "type": "boolean" + } + }, + "required": ["identityUrl","actualUrl","fdc3Version"] + }, + "meta": { + "title": "Connection Step Metadata", + "description": "Metadata for this connection step message", + "$ref": "WCPConnectionStep.schema.json#/$defs/ConnectionStepMeta" + } + }, + "required": [ "type", "payload", "meta"], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/WCP2LoadUrl.schema.json b/schemas/api/WCP2LoadUrl.schema.json new file mode 100644 index 000000000..e7c9a5ac9 --- /dev/null +++ b/schemas/api/WCP2LoadUrl.schema.json @@ -0,0 +1,52 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/WCP2LoadUrl.schema.json", + "title": "Web Connection Protocol 2 Load Url", + "description": "Response from a Desktop Agent to an application requesting access to it indicating that it should load a specified URL into a hidden iframe in order to establish connectivity to a Desktop Agent", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/WCP2LoadUrlBase" + }, + { + "$ref": "WCPConnectionStep.schema.json" + } + ], + "$defs": { + "WCP2LoadUrlBase": { + "type": "object", + "properties": { + "type": { + "title": "WCP2LoadUrl Message Type", + "const": "WCP2LoadUrl" + }, + "payload": { + "title": "WCP2LoadUrl Payload", + "type": "object", + "properties": { + "iframeUrl": { + "title": "iframe URL", + "type": "string", + "description": "A URL which can be used to establish communication with the Desktop Agent, via loading the URL into an iframe and restarting the Web Connection protocol with the iframe as the target", + "format": "uri" + } + }, + "required": [ + "iframeUrl" + ] + }, + "meta": { + "title": "Connection Step Metadata", + "description": "Metadata for this connection step message", + "$ref": "WCPConnectionStep.schema.json#/$defs/ConnectionStepMeta" + } + }, + "required": [ + "type", + "payload", + "meta" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/WCP3Handshake.schema.json b/schemas/api/WCP3Handshake.schema.json new file mode 100644 index 000000000..cfc829095 --- /dev/null +++ b/schemas/api/WCP3Handshake.schema.json @@ -0,0 +1,80 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/WCP3Handshake.schema.json", + "title": "Web Connection Protocol 3 Handshake", + "description": "Handshake message sent by the Desktop Agent to the app (with a MessagePort appended) that should be used for subsequent communication steps.", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/WCP3HandshakeBase" + }, + { + "$ref": "WCPConnectionStep.schema.json" + } + ], + "$defs": { + "WCP3HandshakeBase": { + "type": "object", + "properties": { + "type": { + "title": "WCP3Handshake Message Type", + "const": "WCP3Handshake" + }, + "payload": { + "title": "WCP3Handshake Payload", + "type": "object", + "properties": { + "fdc3Version": { + "title": "FDC3 version", + "type": "string", + "description": "The version of FDC3 API that the Desktop Agent will provide support for." + }, + "intentResolverUrl": { + "title": "Resolver URL", + "description": "Indicates whether an intent resolver user interface is required and the URL to use to do so. Set to `true` to use the default or `false` to disable the intent resolver (as the Desktop Agent will handle it another way).", + "oneOf": [ + { + "type": "string", + "format": "uri" + }, + { + "type": "boolean" + } + ] + }, + "channelSelectorUrl": { + "title": "Channel Selector URL", + "description": "Indicates whether a channel selector user interface is required and the URL to use to do so. Set to `true` to use the default or `false` to disable the channel selector (as the Desktop Agent will handle it another way).", + "oneOf": [ + { + "type": "string", + "format": "uri" + }, + { + "type": "boolean" + } + ] + } + }, + "additionalProperties": false, + "required": [ + "fdc3Version", + "intentResolverUrl", + "channelSelectorUrl" + ] + }, + "meta": { + "title": "Connection Step Metadata", + "description": "Metadata for this connection step message", + "$ref": "WCPConnectionStep.schema.json#/$defs/ConnectionStepMeta" + } + }, + "required": [ + "type", + "payload", + "meta" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/WCP4ValidateAppIdentity.schema.json b/schemas/api/WCP4ValidateAppIdentity.schema.json new file mode 100644 index 000000000..244b196d0 --- /dev/null +++ b/schemas/api/WCP4ValidateAppIdentity.schema.json @@ -0,0 +1,69 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/WCP4ValidateAppIdentity.schema.json", + "title": "Web Connection Protocol 4 Validate App Identity", + "description": "Identity Validation request from an app attempting to connect to a Desktop Agent.", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/WCP4ValidateAppIdentityBase" + }, + { + "$ref": "WCPConnectionStep.schema.json" + } + ], + "$defs": { + "WCP4ValidateAppIdentityBase": { + "type": "object", + "properties": { + "type": { + "title": "WCP4ValidateAppIdentity Message Type", + "const": "WCP4ValidateAppIdentity" + }, + "payload": { + "title": "WCP4ValidateAppIdentity Payload", + "type": "object", + "properties": { + "identityUrl": { + "title": "Identity URL", + "description": "URL to use for the identity of the application. Desktop Agents MUST validate that the origin of the message matches the URL, but MAY implement custom comparison logic.", + "type": "string", + "format": "uri" + }, + "actualUrl": { + "title": "Actual URL", + "description": "The current URL of the page attempting to connect. This may differ from the identityUrl, but the origins MUST match.", + "type": "string", + "format": "uri" + }, + "instanceId": { + "title": "instanceId", + "description": "If an application has previously connected to the desktop agent, it may specify its prior instance id and associated instance UUID to request the same same instance Id be assigned.", + "type": "string" + }, + "instanceUuid": { + "title": "instanceUuid", + "description": "Instance UUID associated with the requested instanceId.", + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "identityUrl", "actualUrl" + ] + }, + "meta": { + "title": "Connection Step Metadata", + "description": "Metadata for this connection step message", + "$ref": "WCPConnectionStep.schema.json#/$defs/ConnectionStepMeta" + } + }, + "required": [ + "type", + "payload", + "meta" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/WCP5ValidateAppIdentityFailedResponse.schema.json b/schemas/api/WCP5ValidateAppIdentityFailedResponse.schema.json new file mode 100644 index 000000000..b373e894a --- /dev/null +++ b/schemas/api/WCP5ValidateAppIdentityFailedResponse.schema.json @@ -0,0 +1,48 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/WCP5ValidateAppIdentityFailedResponse.schema.json", + "title": "Web Connection Protocol 5 Validate App Identity Failed Response", + "description": "Message sent by the Desktop Agent to an app if their identity validation fails.", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/WCP5ValidateAppIdentityFailedResponseBase" + }, + { + "$ref": "WCPConnectionStep.schema.json" + } + ], + "$defs": { + "WCP5ValidateAppIdentityFailedResponseBase": { + "type": "object", + "properties": { + "type": { + "title": "WCP5ValidateAppIdentityFailedResponse Message Type", + "const": "WCP5ValidateAppIdentityFailedResponse" + }, + "payload": { + "title": "WCP5ValidateAppIdentityFailedResponse Payload", + "type": "object", + "properties": { + "message": { + "title": "Identity Validation failed message", + "type": "string" + } + }, + "additionalProperties": false + }, + "meta": { + "title": "Connection Step Metadata", + "description": "Metadata for this connection step message", + "$ref": "WCPConnectionStep.schema.json#/$defs/ConnectionStepMeta" + } + }, + "required": [ + "type", + "payload", + "meta" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/WCP5ValidateAppIdentityResponse.schema.json b/schemas/api/WCP5ValidateAppIdentityResponse.schema.json new file mode 100644 index 000000000..b448995c9 --- /dev/null +++ b/schemas/api/WCP5ValidateAppIdentityResponse.schema.json @@ -0,0 +1,70 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/WCP5ValidateAppIdentityResponse.schema.json", + "title": "Web Connection Protocol 5 Validate App Identity Success Response", + "description": "Message sent by the Desktop Agent to an app after successful identity validation", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/WCP5ValidateAppIdentityResponseBase" + }, + { + "$ref": "WCPConnectionStep.schema.json" + } + ], + "$defs": { + "WCP5ValidateAppIdentityResponseBase": { + "type": "object", + "properties": { + "type": { + "title": "WCP5ValidateAppIdentityResponse Message Type", + "const": "WCP5ValidateAppIdentityResponse" + }, + "payload": { + "title": "WCP5ValidateAppIdentityResponse Payload", + "type": "object", + "properties": { + "appId": { + "title": "appId", + "description": "The appId that the app's identity was validated against", + "type": "string" + }, + "instanceId": { + "title": "instanceId", + "description": "The instance Id granted to the application by the Desktop Agent.", + "type": "string" + }, + "instanceUuid": { + "title": "instanceUuid", + "description": "Instance UUID associated with the instanceId granted, which may be used to retrieve the same instance Id if the app is reloaded or navigates.", + "type": "string" + }, + "implementationMetadata": { + "title": "ImplementationMetadata", + "description": "Implementation metadata for the Desktop Agent, which includes an appMetadata element containing a copy of the app's own metadata", + "$ref": "api.schema.json#/definitions/ImplementationMetadata" + } + }, + "additionalProperties": false, + "required": [ + "appId", + "instanceId", + "instanceUuid", + "implementationMetadata" + ] + }, + "meta": { + "title": "Connection Step Metadata", + "description": "Metadata for this connection step message", + "$ref": "WCPConnectionStep.schema.json#/$defs/ConnectionStepMeta" + } + }, + "required": [ + "type", + "payload", + "meta" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/WCP6Goodbye.schema.json b/schemas/api/WCP6Goodbye.schema.json new file mode 100644 index 000000000..25ae9319a --- /dev/null +++ b/schemas/api/WCP6Goodbye.schema.json @@ -0,0 +1,33 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/WCP6Goodbye.schema.json", + "title": "Web Connection Protocol 6 Goodbye", + "description": "Goodbye message to be sent to the Desktop Agent when disconnecting (e.g. when closing the window or navigating). Desktop Agents should close the MessagePort after receiving this message, but retain instance details in case the application reconnects (e.g. after a navigation event).", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/WCP6GoodbyeBase" + }, + { + "$ref": "WCPConnectionStep.schema.json" + } + ], + "$defs": { + "WCP6GoodbyeBase": { + "type": "object", + "properties": { + "type": { + "title": "WCP6Goodbye Message Type", + "const": "WCP6Goodbye" + }, + "meta": { + "title": "Disconnect Metadata", + "description": "Metadata for a disconnection step message", + "$ref": "WCPConnectionStep.schema.json#/$defs/DisconnectStepMeta" + } + }, + "required": [ "type", "meta"], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/WCPConnectionStep.schema.json b/schemas/api/WCPConnectionStep.schema.json new file mode 100644 index 000000000..11fb91463 --- /dev/null +++ b/schemas/api/WCPConnectionStep.schema.json @@ -0,0 +1,78 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/WCPConnectionStep.schema.json", + "title": "Web Connection Protocol Message", + "type": "object", + "description": "A message used during the connection flow for an application to a Desktop Agent in a browser window. Used for messages sent in either direction.", + "properties": { + "type": { + "title": "Connection Step Message type", + "type": "string", + "enum": [ + "WCP1Hello", + "WCP2LoadUrl", + "WCP3Handshake", + "WCP4ValidateAppIdentity", + "WCP5ValidateAppIdentityFailedResponse", + "WCP5ValidateAppIdentityResponse", + "WCP6Goodbye" + ], + "description": "Identifies the type of the connection step message." + }, + "payload": { + "title": "Message payload", + "type": "object", + "description": "The message payload, containing data pertaining to this connection step.", + "additionalProperties": true + }, + "meta": { + "oneOf": [ + { + "$ref": "#/$defs/DisconnectStepMeta" + }, + { + "$ref": "#/$defs/ConnectionStepMeta" + } + ] + } + }, + "required": [ + "type", + "meta" + ], + "additionalProperties": false, + "$defs": { + "ConnectionStepMeta": { + "title": "Connection Step Metadata", + "description": "Metadata for this connection step message", + "type": "object", + "properties": { + "connectionAttemptUuid": { + "$ref": "common.schema.json#/$defs/ConnectionAttemptUuid" + }, + "timestamp": { + "$ref": "common.schema.json#/$defs/Timestamp" + } + }, + "required": [ + "timestamp", + "connectionAttemptUuid" + ], + "additionalProperties": false + }, + "DisconnectStepMeta": { + "title": "Disconnect Metadata", + "description": "Metadata for a disconnection step message", + "type": "object", + "properties": { + "timestamp": { + "$ref": "common.schema.json#/$defs/Timestamp" + } + }, + "required": [ + "timestamp" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/addContextListenerRequest.schema.json b/schemas/api/addContextListenerRequest.schema.json new file mode 100644 index 000000000..dfbc03ad5 --- /dev/null +++ b/schemas/api/addContextListenerRequest.schema.json @@ -0,0 +1,65 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/addContextListenerRequest.schema.json", + "type": "object", + "title": "AddContextListener Request", + "description": "A request to add a context listener to a specified Channel OR to the current user channel. Where the listener is added to the current user channel (channelId == null), and this app has already been added to a user channel, client code should make a subsequent request to get the current context of that channel for this listener and then call its handler with it.", + "allOf": [ + { + "$ref": "appRequest.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/AddContextListenerRequestType" + }, + "payload": { + "$ref": "#/$defs/AddContextListenerRequestPayload" + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "AddContextListenerRequestType": { + "title": "AddContextListener Request Message Type", + "const": "addContextListenerRequest" + }, + "AddContextListenerRequestPayload": { + "title": "AddContextListener Request Payload", + "type": "object", + "properties": { + "channelId": { + "title": "Channel Id", + "description": "The id of the channel to add the listener to or `null` indicating that it should listen to the current user channel (at the time of broadcast).", + "oneOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "contextType": { + "title": "Context type", + "description": "The type of context to listen for OR `null` indicating that it should listen to all context types.", + "oneOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "required": [ + "channelId", "contextType" + ] + } + } +} \ No newline at end of file diff --git a/schemas/api/addContextListenerResponse.schema.json b/schemas/api/addContextListenerResponse.schema.json new file mode 100644 index 000000000..bd70fd066 --- /dev/null +++ b/schemas/api/addContextListenerResponse.schema.json @@ -0,0 +1,64 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/addContextListenerResponse.schema.json", + "type": "object", + "title": "AddContextListener Response", + "description": "A response to a addContextListener request. Where the listener was added to the current user channel (channelId == null), and this app has already been added to a user channel, client code should make a subsequent request to get the current context of that channel for this listener and then call its handler with it.", + "allOf": [ + { + "$ref": "agentResponse.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/AddContextListenerResponseType" + }, + "payload": { + "oneOf": [ + { + "$ref": "#/$defs/AddContextListenerSuccessResponsePayload" + }, + { + "$ref": "#/$defs/AddContextListenerErrorResponsePayload" + } + ] + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "AddContextListenerResponseType": { + "title": "AddContextListener Response Message Type", + "const": "addContextListenerResponse" + }, + "AddContextListenerSuccessResponsePayload": { + "title": "AddContextListener Response Payload", + "type": "object", + "properties": { + "listenerUUID": { + "$ref": "common.schema.json#/$defs/ListenerUuid" + } + }, + "required": [ + "listenerUUID" + ], + "additionalProperties": false + }, + "AddContextListenerErrorResponsePayload": { + "title": "AddContextListener Error Response Payload", + "type": "object", + "properties": { + "error": { + "$ref": "api.schema.json#/definitions/ChannelError" + } + }, + "required": [ + "error" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/addEventListenerRequest.schema.json b/schemas/api/addEventListenerRequest.schema.json new file mode 100644 index 000000000..1417499d0 --- /dev/null +++ b/schemas/api/addEventListenerRequest.schema.json @@ -0,0 +1,53 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/addEventListenerRequest.schema.json", + "type": "object", + "title": "AddEventListener Request", + "description": "A request to add an event listener for a specified event type to the DesktopAgent.", + "allOf": [ + { + "$ref": "appRequest.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/AddEventListenerRequestType" + }, + "payload": { + "$ref": "#/$defs/AddEventListenerRequestPayload" + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "AddEventListenerRequestType": { + "title": "AddEventListener Request Message Type", + "const": "addEventListenerRequest" + }, + "AddEventListenerRequestPayload": { + "title": "AddEventListener Request Payload", + "type": "object", + "properties": { + "type": { + "title": "Event type", + "description": "The type of the event to be listened to or `null` to listen to all event types.", + "oneOf": [ + { + "$ref": "api.schema.json#/definitions/FDC3EventType" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "required": [ + "type" + ] + } + } +} \ No newline at end of file diff --git a/schemas/api/addEventListenerResponse.schema.json b/schemas/api/addEventListenerResponse.schema.json new file mode 100644 index 000000000..f7a853635 --- /dev/null +++ b/schemas/api/addEventListenerResponse.schema.json @@ -0,0 +1,64 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/addEventListenerResponse.schema.json", + "type": "object", + "title": "AddEventListener Response", + "description": "A response to an addEventListener request.", + "allOf": [ + { + "$ref": "agentResponse.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/AddEventListenerResponseType" + }, + "payload": { + "oneOf": [ + { + "$ref": "#/$defs/AddEventListenerSuccessResponsePayload" + }, + { + "$ref": "#/$defs/AddEventListenerErrorResponsePayload" + } + ] + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "AddEventListenerResponseType": { + "title": "AddEventListener Response Message Type", + "const": "addEventListenerResponse" + }, + "AddEventListenerSuccessResponsePayload": { + "title": "AddEventListener Response Payload", + "type": "object", + "properties": { + "listenerUUID": { + "$ref": "common.schema.json#/$defs/ListenerUuid" + } + }, + "required": [ + "listenerUUID" + ], + "additionalProperties": false + }, + "AddEventListenerErrorResponsePayload": { + "title": "AddEventListener Error Response Payload", + "type": "object", + "properties": { + "error": { + "$ref": "common.schema.json#/$defs/ErrorMessages" + } + }, + "required": [ + "error" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/addIntentListenerRequest.schema.json b/schemas/api/addIntentListenerRequest.schema.json new file mode 100644 index 000000000..b639d39aa --- /dev/null +++ b/schemas/api/addIntentListenerRequest.schema.json @@ -0,0 +1,46 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/addIntentListenerRequest.schema.json", + "type": "object", + "title": "AddIntentListener Request", + "description": "A request to add an Intent listener for a specified intent type.", + "allOf": [ + { + "$ref": "appRequest.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/AddIntentListenerRequestType" + }, + "payload": { + "$ref": "#/$defs/AddIntentListenerRequestPayload" + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "AddIntentListenerRequestType": { + "title": "AddIntentListener Request Message Type", + "const": "addIntentListenerRequest" + }, + "AddIntentListenerRequestPayload": { + "title": "AddIntentListener Request Payload", + "type": "object", + "properties": { + "intent": { + "title": "Intent name", + "description": "The name of the intent to listen for.", + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "intent" + ] + } + } +} \ No newline at end of file diff --git a/schemas/api/addIntentListenerResponse.schema.json b/schemas/api/addIntentListenerResponse.schema.json new file mode 100644 index 000000000..1bc9b6203 --- /dev/null +++ b/schemas/api/addIntentListenerResponse.schema.json @@ -0,0 +1,63 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/addIntentListenerResponse.schema.json", + "type": "object", + "title": "AddIntentListener Response", + "description": "A response to a addIntentListener request.", + "allOf": [ + { + "$ref": "agentResponse.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/AddIntentListenerResponseType" + }, + "payload": { + "oneOf": [ + { + "$ref": "#/$defs/AddIntentListenerSuccessResponsePayload" + }, + { + "$ref": "#/$defs/AddIntentListenerErrorResponsePayload" + } + ] + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "AddIntentListenerResponseType": { + "title": "AddIntentListener Response Message Type", + "const": "addIntentListenerResponse" + }, + "AddIntentListenerSuccessResponsePayload": { + "title": "AddIntentListener Response Payload", + "type": "object", + "properties": { + "listenerUUID": { + "$ref": "common.schema.json#/$defs/ListenerUuid" + } + }, + "required": [ + "listenerUUID" + ] + }, + "AddIntentListenerErrorResponsePayload": { + "title": "AddIntentListener Response Error Payload", + "type": "object", + "properties": { + "error": { + "$ref": "api.schema.json#/definitions/ResolveError" + } + }, + "required": [ + "error" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/agentEvent.schema.json b/schemas/api/agentEvent.schema.json new file mode 100644 index 000000000..80c358b6d --- /dev/null +++ b/schemas/api/agentEvent.schema.json @@ -0,0 +1,47 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/agentEvent.schema.json", + "title": "Agent Event Message", + "type": "object", + "description": "A message from a Desktop Agent to an FDC3-enabled app representing an event.", + "properties": { + "type": { + "title": "Event Message Type", + "type": "string", + "enum": [ + "addEventListenerEvent", + "broadcastEvent", + "channelChangedEvent", + "heartbeatEvent", + "intentEvent", + "privateChannelOnAddContextListenerEvent", + "privateChannelOnDisconnectEvent", + "privateChannelOnUnsubscribeEvent" + ], + "description": "Identifies the type of the message and it is typically set to the FDC3 function name that the message relates to, e.g. 'findIntent', with 'Response' appended." + }, + "payload": { + "title": "Event Payload", + "type": "object", + "description": "The message payload contains details of the event that the app is being notified about.", + "additionalProperties": true + }, + "meta": { + "title": "Event Metadata", + "description": "Metadata for messages sent by a Desktop Agent to an App notifying it of an event.", + "type": "object", + "properties": { + "timestamp": { + "$ref": "common.schema.json#/$defs/Timestamp" + }, + "eventUuid": { + "$ref": "common.schema.json#/$defs/EventUuid" + } + }, + "required": ["timestamp", "eventUuid"], + "additionalProperties": false + } + }, + "additionalProperties": false, + "required": ["type", "payload", "meta"] +} diff --git a/schemas/api/agentResponse.schema.json b/schemas/api/agentResponse.schema.json new file mode 100644 index 000000000..1a30d1c14 --- /dev/null +++ b/schemas/api/agentResponse.schema.json @@ -0,0 +1,100 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/agentResponse.schema.json", + "title": "Agent Response Message", + "type": "object", + "description": "A message from a Desktop Agent to an FDC3-enabled app responding to an API call. If the payload contains an `error` property, the request was unsuccessful.", + "properties": { + "type": { + "title": "Response Message Type", + "type": "string", + "enum": [ + "addContextListenerResponse", + "addEventListenerResponse", + "addIntentListenerResponse", + "broadcastResponse", + "contextListenerUnsubscribeResponse", + "createPrivateChannelResponse", + "eventListenerUnsubscribeResponse", + "findInstancesResponse", + "findIntentResponse", + "findIntentsByContextResponse", + "getAppMetadataResponse", + "getCurrentChannelResponse", + "getCurrentContextResponse", + "getInfoResponse", + "getOrCreateChannelResponse", + "getUserChannelsResponse", + "intentListenerUnsubscribeResponse", + "intentResultResponse", + "joinUserChannelResponse", + "leaveCurrentChannelResponse", + "openResponse", + "privateChannelAddEventListenerResponse", + "privateChannelDisconnectResponse", + "privateChannelUnsubscribeEventListenerResponse", + "raiseIntentForContextResponse", + "raiseIntentResponse", + "raiseIntentResultResponse" + ], + "description": "Identifies the type of the message and it is typically set to the FDC3 function name that the message relates to, e.g. 'findIntent', with 'Response' appended." + }, + "payload": { + "title": "Response Payload", + "type": "object", + "description": "A payload for a response to an API call that will contain any return values or an `error` property containing a standardized error message indicating that the request was unsuccessful.", + "oneOf": [ + { + "type": "object", + "properties": {}, + "additionalProperties": true + }, + { + "type": "object", + "properties": { + "error": { + "$ref": "common.schema.json#/$defs/ErrorMessages" + } + }, + "required": [ + "error" + ], + "additionalProperties": false + } + ] + }, + "meta": { + "title": "Agent Response Message Metadata", + "description": "Metadata for messages sent by a Desktop Agent to an App in response to an API call", + "type": "object", + "properties": { + "timestamp": { + "$ref": "common.schema.json#/$defs/Timestamp" + }, + "requestUuid": { + "$ref": "common.schema.json#/$defs/ResponseUuid" + }, + "responseUuid": { + "$ref": "common.schema.json#/$defs/ResponseUuid" + }, + "source": { + "title": "Original Source AppIdentifier", + "description": "Field that represents the source application that the request being responded to was received from, for debugging purposes.", + "$ref": "api.schema.json#/definitions/AppIdentifier" + } + }, + "required": [ + "timestamp", + "requestUuid", + "responseUuid" + ], + "additionalProperties": false + } + }, + "additionalProperties": false, + "required": [ + "type", + "payload", + "meta" + ] +} \ No newline at end of file diff --git a/schemas/api/api.schema.json b/schemas/api/api.schema.json index 581762274..c9ffbb568 100644 --- a/schemas/api/api.schema.json +++ b/schemas/api/api.schema.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "$id": "https://fdc3.finos.org/schemas/next/api/api.schema.json", - "title": "FDC3 Desktop Agent API Schema", + "title": "FDC3 Desktop Agent API Schemas", "definitions": { "AppIdentifier": { "description": "Identifies an application, or instance of an application, and is used to target FDC3 API calls, such as `fdc3.open` or `fdc3.raiseIntent` at specific applications or application instances.\n\nWill always include at least an `appId` field, which uniquely identifies a specific app.\n\nIf the `instanceId` field is set then the `AppMetadata` object represents a specific instance of the application that may be addressed using that Id.", @@ -104,7 +104,7 @@ "instanceMetadata": { "description": "An optional set of, implementation specific, metadata fields that can be used to disambiguate instances, such as a window title or screen position. Must only be set if `instanceId` is set.", "type": "object", - "additionalProperties": {}, + "additionalProperties": true, "title": "instanceMetadata" }, "title": { @@ -467,6 +467,69 @@ "intent", "source" ] + }, + "IntentResult": { + "title": "IntentResult", + "anyOf": [ + { + "type": "object", + "title": "IntentResult Context", + "properties": { + "context": { + "$ref": "../context/context.schema.json" + } + }, + "required": [ + "context" + ], + "additionalProperties": false + }, + { + "type": "object", + "title": "IntentResult Channel", + "properties": { + "channel": { + "$ref": "#/definitions/Channel" + } + }, + "required": [ + "channel" + ], + "additionalProperties": false + }, + { + "type": "object", + "title": "IntentResult Void", + "properties": {}, + "additionalProperties": false + } + ] + }, + "FDC3EventType": { + "title": "FDC3 Event Type", + "description": "The type of a (non-context and non-intent) event that may be received via the FDC3 API's addEventListener function.", + "type": "string", + "enum": [ + "USER_CHANNEL_CHANGED" + ] + }, + "FDC3Event": { + "title": "FDC3 Event", + "description": "An event object received via the FDC3 API's addEventListener function. Will always include both type and details, which describe type of the event and any additional details respectively.", + "type": "object", + "properties": { + "type": { + "$ref": "#/definitions/FDC3EventType" + }, + "details": { + "title": "Event details", + "description": "Additional details of the event, such as the `currentChannelId` for a CHANNEL_CHANGED event", + "type": "object", + "additionalProperties": true + } + }, + "required":["type","details"], + "additionalProperties": false } } } \ No newline at end of file diff --git a/schemas/api/appRequest.schema.json b/schemas/api/appRequest.schema.json new file mode 100644 index 000000000..00f521c78 --- /dev/null +++ b/schemas/api/appRequest.schema.json @@ -0,0 +1,70 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/appRequest.schema.json", + "title": "App Request Message", + "type": "object", + "description": "A request message from an FDC3-enabled app to a Desktop Agent.", + "properties": { + "type": { + "title": "Request Message type", + "type": "string", + "enum": [ + "addContextListenerRequest", + "addEventListenerRequest", + "addIntentListenerRequest", + "broadcastRequest", + "contextListenerUnsubscribeRequest", + "createPrivateChannelRequest", + "eventListenerUnsubscribeRequest", + "findInstancesRequest", + "findIntentRequest", + "findIntentsByContextRequest", + "getAppMetadataRequest", + "getCurrentChannelRequest", + "getCurrentContextRequest", + "getInfoRequest", + "getOrCreateChannelRequest", + "getUserChannelsRequest", + "heartbeatAcknowledgementRequest", + "intentListenerUnsubscribeRequest", + "intentResultRequest", + "joinUserChannelRequest", + "leaveCurrentChannelRequest", + "openRequest", + "privateChannelAddEventListenerRequest", + "privateChannelDisconnectRequest", + "privateChannelUnsubscribeEventListenerRequest", + "raiseIntentForContextRequest", + "raiseIntentRequest" + ], + "description": "Identifies the type of the message and it is typically set to the FDC3 function name that the message relates to, e.g. 'findIntent', with 'Request' appended." + }, + "payload": { + "title": "Request payload", + "type": "object", + "description": "The message payload typically contains the arguments to FDC3 API functions." + }, + "meta": { + "title": "Request Metadata", + "description": "Metadata for a request message sent by an FDC3-enabled app to a Desktop Agent.", + "type": "object", + "properties": { + "requestUuid": { + "$ref": "common.schema.json#/$defs/RequestUuid" + }, + "timestamp": { + "$ref": "common.schema.json#/$defs/Timestamp" + }, + "source": { + "title": "Source AppIdentifier", + "description": "Field that represents the source application that a request or response was received from. Please note that this may be set by an app or Desktop Agent proxy for debugging purposes but a Desktop Agent should make its own determination of the source of a message to avoid spoofing.", + "$ref": "api.schema.json#/definitions/AppIdentifier" + } + }, + "required": ["requestUuid", "timestamp"], + "additionalProperties": false + } + }, + "required": ["type", "payload", "meta"], + "additionalProperties": false +} diff --git a/schemas/api/broadcastEvent.schema.json b/schemas/api/broadcastEvent.schema.json new file mode 100644 index 000000000..90fc28f1f --- /dev/null +++ b/schemas/api/broadcastEvent.schema.json @@ -0,0 +1,63 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/broadcastEvent.schema.json", + "type": "object", + "title": "broadcast Event", + "description": "An event message from the Desktop Agent to an app indicating that context has been broadcast on a channel it is listening to, or specifically to this app instance if it was launched via `fdc3.open` and context was passed.", + "allOf": [ + { + "$ref": "agentEvent.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/BroadcastEventType" + }, + "payload": { + "$ref": "#/$defs/BroadcastEventPayload" + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "BroadcastEventType": { + "title": "Broadcast Event Message Type", + "const": "broadcastEvent" + }, + "BroadcastEventPayload": { + "title": "broadcast Event Payload", + "type": "object", + "properties": { + "channelId": { + "title": "channel Id", + "description": "The Id of the channel that the broadcast was sent on. May be `null` if the context is being broadcast due to a call `fdc3.open` that passed context.", + "oneOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "context": { + "$ref": "../context/context.schema.json", + "title": "Context", + "description": "The context object that was broadcast." + }, + "originatingApp": { + "title": "Originating AppIdentifier", + "description": "Details of the application instance that broadcast the context", + "$ref": "api.schema.json#/definitions/AppIdentifier" + } + }, + "additionalProperties": false, + "required": [ + "channelId", "context" + ] + } + } +} \ No newline at end of file diff --git a/schemas/api/broadcastRequest.schema.json b/schemas/api/broadcastRequest.schema.json new file mode 100644 index 000000000..de85c7205 --- /dev/null +++ b/schemas/api/broadcastRequest.schema.json @@ -0,0 +1,52 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/broadcastRequest.schema.json", + "type": "object", + "title": "Broadcast Request", + "description": "A request to broadcast context on a channel.", + "allOf": [ + { + "$ref": "appRequest.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/BroadcastRequestType" + }, + "payload": { + "$ref": "#/$defs/BroadcastRequestPayload" + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "BroadcastRequestType": { + "title": "Broadcast Request Message Type", + "const": "broadcastRequest" + }, + "BroadcastRequestPayload": { + "title": "broadcast Request Payload", + "type": "object", + "properties": { + "channelId": { + "type": "string", + "title": "Channel Id", + "description": "The Id of the Channel that the broadcast was sent on" + }, + "context": { + "$ref": "../context/context.schema.json", + "title": "Context", + "description": "The context object that is to be broadcast." + } + }, + "additionalProperties": false, + "required": [ + "channelId", + "context" + ] + } + } +} \ No newline at end of file diff --git a/schemas/api/broadcastResponse.schema.json b/schemas/api/broadcastResponse.schema.json new file mode 100644 index 000000000..6b6a38583 --- /dev/null +++ b/schemas/api/broadcastResponse.schema.json @@ -0,0 +1,29 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/broadcastResponse.schema.json", + "type": "object", + "title": "Broadcast Response", + "description": "A response to a request to broadcast context on a channel.", + "allOf": [ + { + "$ref": "agentResponse.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/BroadcastResponseType" + }, + "payload": true, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "BroadcastResponseType": { + "title": "Broadcast Response Message Type", + "const": "broadcastResponse" + } + } +} \ No newline at end of file diff --git a/schemas/api/channelChangedEvent.schema.json b/schemas/api/channelChangedEvent.schema.json new file mode 100644 index 000000000..5181c20cf --- /dev/null +++ b/schemas/api/channelChangedEvent.schema.json @@ -0,0 +1,53 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/channelChangedEvent.schema.json", + "type": "object", + "title": "channelChanged Event", + "description": "An event message from the Desktop Agent to an app indicating that its current user channel has changed.", + "allOf": [ + { + "$ref": "agentEvent.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/ChannelChangedEventType" + }, + "payload": { + "$ref": "#/$defs/ChannelChangedEventPayload" + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "ChannelChangedEventType": { + "title": "ChannelChanged Event Message Type", + "const": "channelChangedEvent" + }, + "ChannelChangedEventPayload": { + "title": "channelChanged Event Payload", + "type": "object", + "properties": { + "newChannelId": { + "title": "New Channel Id", + "description": "The Id of the channel that the app was added to or `null` if it was removed from a channel.", + "oneOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "required": [ + "newChannelId" + ] + } + } +} \ No newline at end of file diff --git a/schemas/api/common.schema.json b/schemas/api/common.schema.json new file mode 100644 index 000000000..bc7961689 --- /dev/null +++ b/schemas/api/common.schema.json @@ -0,0 +1,69 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/common.schema.json", + "title": "Common definitions", + "type": "object", + "description": "Common definitions that are referenced in the API and Bridging wire protocol schemas", + "$defs": { + "ConnectionAttemptUuid": { + "title": "Connection Attempt UUID", + "type": "string", + "description": "Unique identifier for a for an attempt to connect to a Desktop Agent. A Unique UUID should be used in the first (WCP1Hello) message and should be quoted in all subsequent messages to link them to the same connection attempt." + }, + "RequestUuid": { + "title": "Request UUID", + "type": "string", + "description": "Unique identifier for a request or event message. Required in all message types" + }, + "ResponseUuid": { + "title": "Response UUID", + "type": "string", + "description": "Unique identifier for a response to a specific message and must always be accompanied by a RequestUuid." + }, + "EventUuid": { + "title": "Event UUID", + "type": "string", + "description": "Unique identifier for an event message sent from a Desktop Agent to an app." + }, + "ListenerUuid": { + "title": "Listener UUID", + "type": "string", + "description": "Unique identifier for a `listener` object returned by a Desktop Agent to an app in response to addContextListener, addIntentListener or one of the PrivateChannel event listeners and used to identify it in messages (e.g. when unsubscribing)." + }, + "Timestamp": { + "title": "Timestamp", + "type": "string", + "format": "date-time", + "description": "Timestamp at which the message was generated" + }, + "ErrorMessages": { + "oneOf": [ + { + "$ref": "api.schema.json#/definitions/ChannelError" + }, + { + "$ref": "api.schema.json#/definitions/OpenError" + }, + { + "$ref": "api.schema.json#/definitions/ResolveError" + }, + { + "$ref": "api.schema.json#/definitions/ResultError" + }, + { + "$ref": "api.schema.json#/definitions/BridgingError" + } + ] + }, + "PrivateChannelEventListenerTypes": { + "title": "Private Channel Event Listener Types", + "description": "Event listener type names for Private Channel events", + "type": "string", + "enum": [ + "onAddContextListener", + "onUnsubscribe", + "onDisconnect" + ] + } + } +} \ No newline at end of file diff --git a/schemas/api/contextListenerUnsubscribeRequest.schema.json b/schemas/api/contextListenerUnsubscribeRequest.schema.json new file mode 100644 index 000000000..d0f1c3abc --- /dev/null +++ b/schemas/api/contextListenerUnsubscribeRequest.schema.json @@ -0,0 +1,44 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/contextListenerUnsubscribeRequest.schema.json", + "type": "object", + "title": "ContextListenerUnsubscribe Request", + "description": "A request to unsubscribe a context listener.", + "allOf": [ + { + "$ref": "appRequest.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/ContextListenerUnsubscribeRequestType" + }, + "payload": { + "$ref": "#/$defs/ContextListenerUnsubscribeRequestPayload" + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "ContextListenerUnsubscribeRequestType": { + "title": "ContextListenerUnsubscribe Request Message Type", + "const": "contextListenerUnsubscribeRequest" + }, + "ContextListenerUnsubscribeRequestPayload": { + "title": "ContextListenerUnsubscribe Request Payload", + "type": "object", + "properties": { + "listenerUUID": { + "$ref": "common.schema.json#/$defs/ListenerUuid" + } + }, + "required": [ + "listenerUUID" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/contextListenerUnsubscribeResponse.schema.json b/schemas/api/contextListenerUnsubscribeResponse.schema.json new file mode 100644 index 000000000..c9bd341e1 --- /dev/null +++ b/schemas/api/contextListenerUnsubscribeResponse.schema.json @@ -0,0 +1,29 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/contextListenerUnsubscribeResponse.schema.json", + "type": "object", + "title": "ContextListenerUnsubscribe Response", + "description": "A response to a contextListenerUnsubscribe request.", + "allOf": [ + { + "$ref": "agentResponse.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/ContextListenerUnsubscribeResponseType" + }, + "payload": true, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "ContextListenerUnsubscribeResponseType": { + "title": "ContextListenerUnsubscribe Response Message Type", + "const": "contextListenerUnsubscribeResponse" + } + } +} \ No newline at end of file diff --git a/schemas/api/createPrivateChannelRequest.schema.json b/schemas/api/createPrivateChannelRequest.schema.json new file mode 100644 index 000000000..f64a9c6b5 --- /dev/null +++ b/schemas/api/createPrivateChannelRequest.schema.json @@ -0,0 +1,37 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/createPrivateChannelRequest.schema.json", + "type": "object", + "title": "CreatePrivateChannel Request", + "description": "Request to return a Channel with an auto-generated identity that is intended for private communication between applications.", + "allOf": [ + { + "$ref": "appRequest.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/CreatePrivateChannelRequestType" + }, + "payload": { + "$ref": "#/$defs/CreatePrivateChannelRequestPayload" + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "CreatePrivateChannelRequestType": { + "title": "CreatePrivateChannel Request Message Type", + "const": "createPrivateChannelRequest" + }, + "CreatePrivateChannelRequestPayload": { + "title": "CreatePrivateChannel Request Payload", + "type": "object", + "properties": {}, + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/createPrivateChannelResponse.schema.json b/schemas/api/createPrivateChannelResponse.schema.json new file mode 100644 index 000000000..357538c5d --- /dev/null +++ b/schemas/api/createPrivateChannelResponse.schema.json @@ -0,0 +1,64 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/createPrivateChannelResponse.schema.json", + "type": "object", + "title": "CreatePrivateChannel Response", + "description": "A response to a createPrivateChannel request.", + "allOf": [ + { + "$ref": "agentResponse.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/CreatePrivateChannelResponseType" + }, + "payload": { + "oneOf": [ + { + "$ref": "#/$defs/CreatePrivateChannelSuccessResponsePayload" + }, + { + "$ref": "#/$defs/CreatePrivateChannelErrorResponsePayload" + } + ] + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "CreatePrivateChannelResponseType": { + "title": "CreatePrivateChannel Response Message Type", + "const": "createPrivateChannelResponse" + }, + "CreatePrivateChannelSuccessResponsePayload": { + "title": "CreatePrivateChannel Response Payload", + "type": "object", + "properties": { + "privateChannel": { + "$ref": "api.schema.json#/definitions/Channel" + } + }, + "required": [ + "privateChannel" + ], + "additionalProperties": false + }, + "CreatePrivateChannelErrorResponsePayload": { + "title": "CreatePrivateChannel Error Response Payload", + "type": "object", + "properties": { + "error": { + "$ref": "api.schema.json#/definitions/ChannelError" + } + }, + "required": [ + "error" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/eventListenerUnsubscribeRequest.schema.json b/schemas/api/eventListenerUnsubscribeRequest.schema.json new file mode 100644 index 000000000..b3569b254 --- /dev/null +++ b/schemas/api/eventListenerUnsubscribeRequest.schema.json @@ -0,0 +1,44 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/eventListenerUnsubscribeRequest.schema.json", + "type": "object", + "title": "EventListenerUnsubscribe Request", + "description": "A request to unsubscribe an event listener.", + "allOf": [ + { + "$ref": "appRequest.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/EventListenerUnsubscribeRequestType" + }, + "payload": { + "$ref": "#/$defs/EventListenerUnsubscribeRequestPayload" + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "EventListenerUnsubscribeRequestType": { + "title": "EventListenerUnsubscribe Request Message Type", + "const": "eventListenerUnsubscribeRequest" + }, + "EventListenerUnsubscribeRequestPayload": { + "title": "EventListenerUnsubscribe Request Payload", + "type": "object", + "properties": { + "listenerUUID": { + "$ref": "common.schema.json#/$defs/ListenerUuid" + } + }, + "required": [ + "listenerUUID" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/eventListenerUnsubscribeResponse.schema.json b/schemas/api/eventListenerUnsubscribeResponse.schema.json new file mode 100644 index 000000000..465bf9d2a --- /dev/null +++ b/schemas/api/eventListenerUnsubscribeResponse.schema.json @@ -0,0 +1,29 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/eventListenerUnsubscribeResponse.schema.json", + "type": "object", + "title": "EventListenerUnsubscribe Response", + "description": "A response to an eventListenerUnsubscribe request.", + "allOf": [ + { + "$ref": "agentResponse.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/EventListenerUnsubscribeResponseType" + }, + "payload": true, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "EventListenerUnsubscribeResponseType": { + "title": "EventListenerUnsubscribe Response Message Type", + "const": "eventListenerUnsubscribeResponse" + } + } +} \ No newline at end of file diff --git a/schemas/api/fdc3UserInterfaceChannelSelected.schema.json b/schemas/api/fdc3UserInterfaceChannelSelected.schema.json new file mode 100644 index 000000000..c49ec9e56 --- /dev/null +++ b/schemas/api/fdc3UserInterfaceChannelSelected.schema.json @@ -0,0 +1,47 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/fdc3UserInterfaceChannelSelected.schema.json", + "title": "Fdc3 UserInterface Channel Selected", + "description": "Message from a channel selector UI to the DA proxy sent when the channel selection changes.", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/Fdc3UserInterfaceChannelSelectedBase" + }, + { + "$ref": "fdc3UserInterfaceMessage.schema.json" + } + ], + "$defs": { + "Fdc3UserInterfaceChannelSelectedBase": { + "type": "object", + "properties": { + "type": { + "title": "Fdc3 UserInterface ChannelSelected Message Type", + "const": "Fdc3UserInterfaceChannelSelected" + }, + "payload": { + "title": "Fdc3 UserInterface ChannelSelected Payload", + "type": "object", + "properties": { + "selected": { + "title": "Selected Channel", + "description": "The id of the channel that should be currently selected, or `null` if none should be selected", + "oneOf": [ + {"type": "string"}, {"type": "null"} + ] + } + }, + "additionalProperties": false, + "required": ["selected"] + } + }, + "required": [ + "type", + "payload" + ], + "additionalProperties": false + } + } +} + diff --git a/schemas/api/fdc3UserInterfaceChannels.schema.json b/schemas/api/fdc3UserInterfaceChannels.schema.json new file mode 100644 index 000000000..3999823d8 --- /dev/null +++ b/schemas/api/fdc3UserInterfaceChannels.schema.json @@ -0,0 +1,55 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/fdc3UserInterfaceChannels.schema.json", + "title": "Fdc3 UserInterface Channels", + "description": "Setup message sent by the DA proxy code in getAgent() to a channel selector UI in an iframe with the channel definitions and current channel selection.", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/Fdc3UserInterfaceChannelsBase" + }, + { + "$ref": "fdc3UserInterfaceMessage.schema.json" + } + ], + "$defs": { + "Fdc3UserInterfaceChannelsBase": { + "type": "object", + "properties": { + "type": { + "title": "Fdc3 UserInterface Channels Message Type", + "const": "Fdc3UserInterfaceChannels" + }, + "payload": { + "title": "Fdc3 UserInterface Channels Payload", + "type": "object", + "properties": { + "userChannels": { + "title": "User Channels", + "description": "User Channel definitions", + "type": "array", + "items": { + "$ref": "api.schema.json#/definitions/Channel" + } + }, + "selected": { + "title": "Selected Channel", + "description": "The id of the channel that should be currently selected, or `null` if none should be selected", + "oneOf": [ + {"type": "string"}, {"type": "null"} + ] + } + }, + "additionalProperties": false, + "required": ["userChannels", "selected"] + } + }, + "required": [ + "type", + "payload" + ], + "additionalProperties": false + } + } +} + diff --git a/schemas/api/fdc3UserInterfaceDrag.schema.json b/schemas/api/fdc3UserInterfaceDrag.schema.json new file mode 100644 index 000000000..7734f9f58 --- /dev/null +++ b/schemas/api/fdc3UserInterfaceDrag.schema.json @@ -0,0 +1,55 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/fdc3UserInterfaceDrag.schema.json", + "title": "Fdc3 UserInterface Drag", + "description": "Message from a UI iframe to the DA proxy (setup by `getAgent()`) indicating that the user is dragging the UI to a new location and providing the offset to apply to the location. The DA proxy implementation should limit the location to the current bounds of the window's viewport", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/Fdc3UserInterfaceDragBase" + }, + { + "$ref": "fdc3UserInterfaceMessage.schema.json" + } + ], + "$defs": { + "Fdc3UserInterfaceDragBase": { + "type": "object", + "properties": { + "type": { + "title": "Fdc3 UserInterface Drag Message Type", + "const": "Fdc3UserInterfaceDrag" + }, + "payload": { + "title": "Fdc3 UserInterface Drag Payload", + "type": "object", + "properties": { + "mouseOffsets": { + "title": "Mouse Offsets", + "description": "The offset to move the frame by", + "type": "object", + "properties": { + "x": { + "type": "integer" + }, + "y": { + "type": "integer" + } + }, + "required": ["x", "y"], + "additionalProperties": false + } + }, + "additionalProperties": false, + "required": ["mouseOffsets"] + } + }, + "required": [ + "type", + "payload" + ], + "additionalProperties": false + } + } +} + diff --git a/schemas/api/fdc3UserInterfaceHandshake.schema.json b/schemas/api/fdc3UserInterfaceHandshake.schema.json new file mode 100644 index 000000000..9b4fb181f --- /dev/null +++ b/schemas/api/fdc3UserInterfaceHandshake.schema.json @@ -0,0 +1,44 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/fdc3UserInterfaceHandshake.schema.json", + "title": "Fdc3 UserInterface Handshake", + "description": "Handshake message sent back to a user interface from the DA proxy code (setup by `getAgent()`) over the `MessagePort` provide in the preceding iFrameHello message, confirming that it is listening to the `MessagePort` for further communication.", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/Fdc3UserInterfaceHandshakeBase" + }, + { + "$ref": "fdc3UserInterfaceMessage.schema.json" + } + ], + "$defs": { + "Fdc3UserInterfaceHandshakeBase": { + "type": "object", + "properties": { + "type": { + "title": "Fdc3 UserInterface Handshake Message Type", + "const": "Fdc3UserInterfaceHandshake" + }, + "payload": { + "title": "Fdc3 UserInterface Handshake Payload", + "type": "object", + "properties": { + "fdc3Version": { + "title": "FDC3 version", + "type": "string", + "description": "The version of FDC3 API that the Desktop Agent will provide support for." + } + }, + "additionalProperties": false, + "required": ["fdc3Version"] + } + }, + "required": [ + "type", + "payload" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/fdc3UserInterfaceHello.schema.json b/schemas/api/fdc3UserInterfaceHello.schema.json new file mode 100644 index 000000000..bcb873538 --- /dev/null +++ b/schemas/api/fdc3UserInterfaceHello.schema.json @@ -0,0 +1,62 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/fdc3UserInterfaceHello.schema.json", + "title": "Fdc3 UserInterface Hello", + "description": "Hello message sent by a UI to the Desktop Agent proxy setup by `getAgent()` to indicate it is ready to communicate, containing initial CSS to set on the iframe, and including an appended `MessagePort` to be used for further communication.", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/Fdc3UserInterfaceHelloBase" + }, + { + "$ref": "fdc3UserInterfaceMessage.schema.json" + } + ], + "$defs": { + "Fdc3UserInterfaceHelloBase": { + "type": "object", + "properties": { + "type": { + "title": "Fdc3 UserInterface Hello Message Type", + "const": "Fdc3UserInterfaceHello" + }, + "payload": { + "title": "Fdc3 UserInterface Hello Payload", + "type": "object", + "properties": { + "implementationDetails": { + "title": "Implementation Details", + "type": "string", + "description": "Details about the UI implementation, such as vendor and version, for logging purposes." + }, + "initialCSS": { + "title": "Initial CSS", + "type": "object", + "description": "A constrained set of styling properties that should be set on the user interface before it is displayed. Note `position` cannot be specified and should always be set to `fixed`.", + "properties": { + "height": {"type": "string", "title": "height", "description": "The initial height of the iframe"}, + "width": {"type": "string", "title": "width", "description": "The initial width of the iframe"}, + "zIndex": {"type": "string", "title": "zIndex", "description": "The initial zindex to apply to the iframe"}, + "left": {"type": "string", "title": "left", "description": "The initial left property to apply to the iframe"}, + "top": {"type": "string", "title": "top", "description": "The initial top property to apply to the iframe"}, + "bottom": {"type": "string", "title": "bottom", "description": "The initial bottom property to apply to the iframe"}, + "right": {"type": "string", "title": "right", "description": "The initial right property to apply to the iframe"}, + "transition": {"type": "string", "title": "transition", "description": "The transition property to apply to the iframe"}, + "maxHeight": {"type": "string", "title": "maxHeight", "description": "The maximum height to apply to the iframe"}, + "maxWidth": {"type": "string", "title": "maxWidth", "description": "The maximum with to apply to the iframe"} + }, + "required": [] + } + }, + "additionalProperties": false, + "required": ["implementationDetails","initialCSS"] + } + }, + "required": [ + "type", + "payload" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/fdc3UserInterfaceMessage.schema.json b/schemas/api/fdc3UserInterfaceMessage.schema.json new file mode 100644 index 000000000..42c6e80c7 --- /dev/null +++ b/schemas/api/fdc3UserInterfaceMessage.schema.json @@ -0,0 +1,34 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/fdc3UserInterfaceMessage.schema.json", + "title": "Fdc3 UserInterface Message", + "type": "object", + "description": "A message used to communicate with user interface frames injected by `getAgent()` for displaying UI elements such as the intent resolver or channel selector. Used for messages sent in either direction.", + "properties": { + "type": { + "title": "Fdc3 UserInterface Message type", + "type": "string", + "enum": [ + "Fdc3UserInterfaceHello", + "Fdc3UserInterfaceHandshake", + "Fdc3UserInterfaceRestyle", + "Fdc3UserInterfaceDrag", + "Fdc3UserInterfaceResolve", + "Fdc3UserInterfaceResolveAction", + "Fdc3UserInterfaceChannels", + "Fdc3UserInterfaceChannelSelected" + ], + "description": "Identifies the type of the message to or from the user interface frame." + }, + "payload": { + "title": "Message payload", + "type": "object", + "description": "The message payload", + "additionalProperties": true + } + }, + "required": [ + "type" + ], + "additionalProperties": false +} \ No newline at end of file diff --git a/schemas/api/fdc3UserInterfaceResolve.schema.json b/schemas/api/fdc3UserInterfaceResolve.schema.json new file mode 100644 index 000000000..1a30076b0 --- /dev/null +++ b/schemas/api/fdc3UserInterfaceResolve.schema.json @@ -0,0 +1,53 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/fdc3UserInterfaceResolve.schema.json", + "title": "Fdc3 UserInterface Resolve", + "description": "Setup message sent by the DA proxy code in getAgent() to an intent resolver UI with the resolver data to setup the UI.", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/Fdc3UserInterfaceResolveBase" + }, + { + "$ref": "fdc3UserInterfaceMessage.schema.json" + } + ], + "$defs": { + "Fdc3UserInterfaceResolveBase": { + "type": "object", + "properties": { + "type": { + "title": "Fdc3 UserInterface Resolve Message Type", + "const": "Fdc3UserInterfaceResolve" + }, + "payload": { + "title": "Fdc3 UserInterface Resolve Payload", + "type": "object", + "properties": { + "context": { + "$ref": "../context/context.schema.json", + "title": "Context" + }, + "appIntents": { + "title": "Resolution options", + "type": "array", + "description": "An array of AppIntent objects defining the resolution options.", + "items": { + "$ref": "api.schema.json#/definitions/AppIntent" + }, + "additionalProperties": false + } + }, + "additionalProperties": false, + "required": ["context", "appIntents"] + } + }, + "required": [ + "type", + "payload" + ], + "additionalProperties": false + } + } +} + diff --git a/schemas/api/fdc3UserInterfaceResolveAction.schema.json b/schemas/api/fdc3UserInterfaceResolveAction.schema.json new file mode 100644 index 000000000..67daf031f --- /dev/null +++ b/schemas/api/fdc3UserInterfaceResolveAction.schema.json @@ -0,0 +1,85 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/fdc3UserInterfaceResolveAction.schema.json", + "title": "Fdc3 UserInterface Resolve Action", + "description": "Message from an intent resolver UI to DA proxy code in getAgent() reporting a user action.", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/Fdc3UserInterfaceResolveActionBase" + }, + { + "$ref": "fdc3UserInterfaceMessage.schema.json" + } + ], + "$defs": { + "Fdc3UserInterfaceResolveActionBase": { + "type": "object", + "properties": { + "type": { + "title": "Fdc3 UserInterface ResolveAction Message Type", + "const": "Fdc3UserInterfaceResolveAction" + }, + "payload": { + "oneOf": [ + { "$ref": "#/$defs/Fdc3UserInterfaceResolveActionPayload"}, + { "$ref": "#/$defs/Fdc3UserInterfaceResolveCancelPayload"} + ] + } + }, + "required": [ + "type", + "payload" + ], + "additionalProperties": false + }, + "Fdc3UserInterfaceResolveActionPayload": { + "title": "Fdc3 UserInterface Resolve Action Payload", + "type": "object", + "properties": { + "intent": { + "title": "Intent name", + "type": "string", + "description": "The intent resolved" + }, + "appIdentifier": { + "title": "AppIdentifier", + "description": "The App resolution option chosen", + "$ref": "api.schema.json#/definitions/AppIdentifier" + }, + "action": { + "anyOf": [ + { + "type": "string", + "const": "hover" + }, + { + "type": "string", + "const": "click" + } + ] + } + }, + "required": [ + "intent", + "appIdentifier", + "action" + ], + "additionalProperties": false + }, + "Fdc3UserInterfaceResolveCancelPayload": { + "title": "Fdc3 UserInterface Resolve Cancel Payload", + "type": "object", + "properties": { + "action": { + "type": "string", + "const": "cancel" + } + }, + "required": [ + "action" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/fdc3UserInterfaceRestyle.schema.json b/schemas/api/fdc3UserInterfaceRestyle.schema.json new file mode 100644 index 000000000..187ac1c7a --- /dev/null +++ b/schemas/api/fdc3UserInterfaceRestyle.schema.json @@ -0,0 +1,58 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/fdc3UserInterfaceRestyle.schema.json", + "title": "Fdc3 UserInterface Restyle", + "description": "Message from a UI frame to the DA proxy code (setup by `getAgent()`) with updated styling information to apply to it. Can be used to implement a pop-open or close interaction or other transition needed by a UI implementation.", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/Fdc3UserInterfaceRestyleBase" + }, + { + "$ref": "fdc3UserInterfaceMessage.schema.json" + } + ], + "$defs": { + "Fdc3UserInterfaceRestyleBase": { + "type": "object", + "properties": { + "type": { + "title": "Fdc3 UserInterface Restyle Message Type", + "const": "Fdc3UserInterfaceRestyle" + }, + "payload": { + "title": "Fdc3 UserInterface Restyle Payload", + "type": "object", + "properties": { + "updatedCSS": { + "title": "Updated CSS", + "type": "object", + "description": "A constrained set of styling properties that should be applied to the frame. Note `position` cannot be set, and should always be `fixed`.", + "properties": { + "height": {"type": "string", "title": "height", "description": "The updated height of the iframe"}, + "width": {"type": "string", "title": "width", "description": "The updated width of the iframe"}, + "zIndex": {"type": "string", "title": "zIndex", "description": "The updated zindex to apply to the iframe"}, + "left": {"type": "string", "title": "left", "description": "The initial left property to apply to the iframe"}, + "top": {"type": "string", "title": "top", "description": "The initial top property to apply to the iframe"}, + "bottom": {"type": "string", "title": "bottom", "description": "The initial bottom property to apply to the iframe"}, + "right": {"type": "string", "title": "right", "description": "The initial right property to apply to the iframe"}, + "transition": {"type": "string", "title": "transition", "description": "The updated transition property to apply to the iframe"}, + "maxHeight": {"type": "string", "title": "maxHeight", "description": "The updated maximum height to apply to the iframe"}, + "maxWidth": {"type": "string", "title": "maxWidth", "description": "The updated maximum with to apply to the iframe"} + }, + "required": [] + } + }, + "additionalProperties": false, + "required": ["updatedCSS"] + } + }, + "required": [ + "type", + "payload" + ], + "additionalProperties": false + } + } +} + diff --git a/schemas/api/findInstancesRequest.schema.json b/schemas/api/findInstancesRequest.schema.json new file mode 100644 index 000000000..3876dee37 --- /dev/null +++ b/schemas/api/findInstancesRequest.schema.json @@ -0,0 +1,42 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/findInstancesRequest.schema.json", + "type": "object", + "title": "FindInstances Request", + "description": "A request for details of instances of a particular app.", + "allOf": [ + { + "$ref": "appRequest.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/FindInstancesRequestType" + }, + "payload": { + "$ref": "#/$defs/FindInstancesRequestPayload" + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "FindInstancesRequestType": { + "title": "FindInstances Request Message Type", + "const": "findInstancesRequest" + }, + "FindInstancesRequestPayload": { + "type": "object", + "title": "FindInstances Request Payload", + "properties": { + "app": { + "$ref": "api.schema.json#/definitions/AppIdentifier" + } + }, + "required": ["app"], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/findInstancesResponse.schema.json b/schemas/api/findInstancesResponse.schema.json new file mode 100644 index 000000000..ec387c52a --- /dev/null +++ b/schemas/api/findInstancesResponse.schema.json @@ -0,0 +1,77 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/findInstancesResponse.schema.json", + "type": "object", + "title": "FindInstances Response", + "description": "A response to a findInstances request.", + "allOf": [ + { + "$ref": "agentResponse.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/FindInstancesResponseType" + }, + "payload": { + "oneOf": [ + { + "$ref": "#/$defs/FindInstancesSuccessResponsePayload" + }, + { + "$ref": "#/$defs/FindInstancesErrorResponsePayload" + } + ] + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "FindInstancesResponseType": { + "title": "FindInstances Response Message Type", + "const": "findInstancesResponse" + }, + "FindInstancesSuccessResponsePayload": { + "title": "FindInstances Response Message Payload", + "type": "object", + "description": "The message payload contains a flag indicating whether the API call was successful, plus any return values for the FDC3 API function called, or indicating that the request resulted in an error and including a standardized error message.", + "properties": { + "appIdentifiers": { + "type": "array", + "items": { + "$ref": "api.schema.json#/definitions/AppMetadata" + } + } + }, + "required": [ + "appIdentifiers" + ], + "additionalProperties": false + }, + "FindInstancesErrorResponsePayload": { + "title": "FindInstances Error Response Message Payload", + "type": "object", + "properties": { + "error": { + "title": "findInstances Errors", + "type": "string", + "oneOf": [ + { + "$ref": "api.schema.json#/definitions/ResolveError" + }, + { + "$ref": "api.schema.json#/definitions/BridgingError" + } + ] + } + }, + "required": [ + "error" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/findIntentRequest.schema.json b/schemas/api/findIntentRequest.schema.json new file mode 100644 index 000000000..3bdfc6550 --- /dev/null +++ b/schemas/api/findIntentRequest.schema.json @@ -0,0 +1,53 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/findIntentRequest.schema.json", + "type": "object", + "title": "FindIntent Request", + "description": "A request for details of apps available to resolve a particular intent and context pair.", + "allOf": [ + { + "$ref": "appRequest.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/FindIntentRequestType" + }, + "payload": { + "$ref": "#/$defs/FindIntentRequestPayload" + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "FindIntentRequestType": { + "title": "FindIntent Request Message Type", + "const": "findIntentRequest" + }, + "FindIntentRequestPayload": { + "title": "FindIntent Request Payload", + "type": "object", + "properties": { + "intent": { + "title": "Intent name", + "type": "string" + }, + "context": { + "title": "Context argument", + "$ref": "../context/context.schema.json" + }, + "resultType": { + "title": "Result type argument", + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "intent" + ] + } + } +} \ No newline at end of file diff --git a/schemas/api/findIntentResponse.schema.json b/schemas/api/findIntentResponse.schema.json new file mode 100644 index 000000000..0e8d7416d --- /dev/null +++ b/schemas/api/findIntentResponse.schema.json @@ -0,0 +1,72 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/findIntentResponse.schema.json", + "type": "object", + "title": "FindIntent Response", + "description": "A response to a findIntent request.", + "allOf": [ + { + "$ref": "agentResponse.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/FindIntentResponseType" + }, + "payload": { + "oneOf": [ + { + "$ref": "#/$defs/FindIntentSuccessResponsePayload" + }, + { + "$ref": "#/$defs/FindIntentErrorResponsePayload" + } + ] + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "FindIntentResponseType": { + "title": "FindIntent Response Message Type", + "const": "findIntentResponse" + }, + "FindIntentSuccessResponsePayload": { + "title": "FindIntent Response Payload", + "type": "object", + "properties": { + "appIntent": { + "$ref": "api.schema.json#/definitions/AppIntent" + } + }, + "required": [ + "appIntent" + ], + "additionalProperties": false + }, + "FindIntentErrorResponsePayload": { + "title": "FindIntent Response Error Payload", + "type": "object", + "properties": { + "error": { + "title": "findIntent Errors", + "oneOf": [ + { + "$ref": "api.schema.json#/definitions/ResolveError" + }, + { + "$ref": "api.schema.json#/definitions/BridgingError" + } + ] + } + }, + "required": [ + "error" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/findIntentsByContextRequest.schema.json b/schemas/api/findIntentsByContextRequest.schema.json new file mode 100644 index 000000000..0b18240d2 --- /dev/null +++ b/schemas/api/findIntentsByContextRequest.schema.json @@ -0,0 +1,48 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/findIntentsByContextRequest.schema.json", + "type": "object", + "title": "FindIntentsByContext Request", + "description": "A request for details of intents and apps available to resolve them for a particular context.", + "allOf": [ + { + "$ref": "appRequest.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/FindIntentsByContextRequestType" + }, + "payload": { + "$ref": "#/$defs/FindIntentsByContextRequestPayload" + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "FindIntentsByContextRequestType": { + "title": "FindIntentsByContext Request Message Type", + "const": "findIntentsByContextRequest" + }, + "FindIntentsByContextRequestPayload": { + "title": "FindIntentsByContext Request Payload", + "type": "object", + "properties": { + "context": { + "$ref": "../context/context.schema.json" + }, + "resultType": { + "title": "Result type argument", + "type": "string" + } + }, + "required": [ + "context" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/findIntentsByContextResponse.schema.json b/schemas/api/findIntentsByContextResponse.schema.json new file mode 100644 index 000000000..9ccf5cce1 --- /dev/null +++ b/schemas/api/findIntentsByContextResponse.schema.json @@ -0,0 +1,76 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/findIntentsByContextResponse.schema.json", + "type": "object", + "title": "FindIntentsByContext Response", + "description": "A response to a findIntentsByContext request.", + "allOf": [ + { + "$ref": "agentResponse.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/FindIntentsByContextResponseType" + }, + "payload": { + "oneOf": [ + { + "$ref": "#/$defs/FindIntentsByContextSuccessResponsePayload" + }, + { + "$ref": "#/$defs/FindIntentsByContextErrorResponsePayload" + } + ] + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "FindIntentsByContextResponseType": { + "title": "FindIntentsByContext Response Message Type", + "const": "findIntentsByContextResponse" + }, + "FindIntentsByContextSuccessResponsePayload": { + "title": "FindIntentsByContext Response Payload", + "type": "object", + "properties": { + "appIntents": { + "type": "array", + "items": { + "$ref": "api.schema.json#/definitions/AppIntent" + }, + "additionalProperties": false + } + }, + "required": [ + "appIntents" + ], + "additionalProperties": false + }, + "FindIntentsByContextErrorResponsePayload": { + "title": "FindIntentsByContext Error Response Payload", + "type": "object", + "properties": { + "error": { + "title": "FindIntentsByContext Error Message", + "oneOf": [ + { + "$ref": "api.schema.json#/definitions/ResolveError" + }, + { + "$ref": "api.schema.json#/definitions/BridgingError" + } + ] + } + }, + "required": [ + "error" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/getAppMetadataRequest.schema.json b/schemas/api/getAppMetadataRequest.schema.json new file mode 100644 index 000000000..eb51811c7 --- /dev/null +++ b/schemas/api/getAppMetadataRequest.schema.json @@ -0,0 +1,44 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/getAppMetadataRequest.schema.json", + "type": "object", + "title": "GetAppMetadata Request", + "description": "A request for metadata about an app.", + "allOf": [ + { + "$ref": "appRequest.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/GetAppMetadataRequestType" + }, + "payload": { + "$ref": "#/$defs/GetAppMetadataRequestPayload" + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "GetAppMetadataRequestType": { + "title": "GetAppMetadata Request Message Type", + "const": "getAppMetadataRequest" + }, + "GetAppMetadataRequestPayload": { + "title": "GetAppMetadata Request Payload", + "type": "object", + "properties": { + "app": { + "$ref": "api.schema.json#/definitions/AppIdentifier" + } + }, + "required": [ + "app" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/getAppMetadataResponse.schema.json b/schemas/api/getAppMetadataResponse.schema.json new file mode 100644 index 000000000..ac9d6c16e --- /dev/null +++ b/schemas/api/getAppMetadataResponse.schema.json @@ -0,0 +1,72 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/getAppMetadataResponse.schema.json", + "type": "object", + "title": "GetAppMetadata Response", + "description": "A response to a getAppMetadata request.", + "allOf": [ + { + "$ref": "agentResponse.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/GetAppMetadataResponseType" + }, + "payload": { + "oneOf": [ + { + "$ref": "#/$defs/GetAppMetadataSuccessResponsePayload" + }, + { + "$ref": "#/$defs/GetAppMetadataErrorResponsePayload" + } + ] + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "GetAppMetadataResponseType": { + "title": "GetAppMetadata Response Message Type", + "const": "getAppMetadataResponse" + }, + "GetAppMetadataSuccessResponsePayload": { + "title": "GetAppMetadata Response Payload", + "type": "object", + "properties": { + "appMetadata": { + "$ref": "api.schema.json#/definitions/AppMetadata" + } + }, + "required": [ + "appMetadata" + ], + "additionalProperties": false + }, + "GetAppMetadataErrorResponsePayload": { + "title": "GetAppMetadata Error Response Payload", + "type": "object", + "properties": { + "error": { + "title": "GetAppMetadata Error Message", + "oneOf": [ + { + "$ref": "api.schema.json#/definitions/ResolveError" + }, + { + "$ref": "api.schema.json#/definitions/BridgingError" + } + ] + } + }, + "required": [ + "error" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/getCurrentChannelRequest.schema.json b/schemas/api/getCurrentChannelRequest.schema.json new file mode 100644 index 000000000..bf8a803d0 --- /dev/null +++ b/schemas/api/getCurrentChannelRequest.schema.json @@ -0,0 +1,37 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/getCurrentChannelRequest.schema.json", + "type": "object", + "title": "GetCurrentChannel Request", + "description": "A request to return the Channel object for the current User channel membership. Returns `null` if the app is not joined to a channel.", + "allOf": [ + { + "$ref": "appRequest.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/GetCurrentChannelRequestType" + }, + "payload": { + "$ref": "#/$defs/GetCurrentChannelRequestPayload" + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "GetCurrentChannelRequestType": { + "title": "GetCurrentChannel Request Message Type", + "const": "getCurrentChannelRequest" + }, + "GetCurrentChannelRequestPayload": { + "title": "GetCurrentChannel Request Payload", + "type": "object", + "properties": {}, + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/getCurrentChannelResponse.schema.json b/schemas/api/getCurrentChannelResponse.schema.json new file mode 100644 index 000000000..312f3e174 --- /dev/null +++ b/schemas/api/getCurrentChannelResponse.schema.json @@ -0,0 +1,67 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/getCurrentChannelResponse.schema.json", + "type": "object", + "title": "GetCurrentChannel Response", + "description": "A response to a getCurrentChannel request.", + "allOf": [ + { + "$ref": "agentResponse.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/GetCurrentChannelResponseType" + }, + "payload": { + "oneOf": [ + { + "$ref": "#/$defs/GetCurrentChannelSuccessResponsePayload" + }, + { + "$ref": "#/$defs/GetCurrentChannelErrorResponsePayload" + } + ] + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "GetCurrentChannelResponseType": { + "title": "GetCurrentChannel Response Message Type", + "const": "getCurrentChannelResponse" + }, + "GetCurrentChannelSuccessResponsePayload": { + "title": "GetCurrentChannel Response Payload", + "type": "object", + "properties": { + "channel": { + "oneOf": [ + { "$ref": "api.schema.json#/definitions/Channel" }, + { "type": "null" } + ] + } + }, + "required": [ + "channel" + ], + "additionalProperties": false + }, + "GetCurrentChannelErrorResponsePayload": { + "title": "GetCurrentChannel Error Response Payload", + "type": "object", + "properties": { + "error": { + "$ref": "common.schema.json#/$defs/ErrorMessages" + } + }, + "required": [ + "error" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/getCurrentContextRequest.schema.json b/schemas/api/getCurrentContextRequest.schema.json new file mode 100644 index 000000000..508eb7631 --- /dev/null +++ b/schemas/api/getCurrentContextRequest.schema.json @@ -0,0 +1,56 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/getCurrentContextRequest.schema.json", + "type": "object", + "title": "GetCurrentContext Request", + "description": "A request to return the current context (either of a specified type or most recent broadcast) of a specified Channel. Returns `null` if no context (of the requested type if one was specified) is available in the channel.", + "allOf": [ + { + "$ref": "appRequest.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/GetCurrentContextRequestType" + }, + "payload": { + "$ref": "#/$defs/GetCurrentContextRequestPayload" + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "GetCurrentContextRequestType": { + "title": "GetCurrentContext Request Message Type", + "const": "getCurrentContextRequest" + }, + "GetCurrentContextRequestPayload": { + "title": "GetCurrentContext Request Payload", + "type": "object", + "properties": { + "channelId": { + "title": "Channel Id", + "description": "The id of the channel to return the current context of", + "type": "string" + }, + "contextType": { + "title": "Context type", + "description": "The type of context to return for OR `null` indicating that the most recently broadcast context on the channel should be returned.", + "oneOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + } + }, + "required": ["channelId", "contextType"], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/getCurrentContextResponse.schema.json b/schemas/api/getCurrentContextResponse.schema.json new file mode 100644 index 000000000..55fd4a44e --- /dev/null +++ b/schemas/api/getCurrentContextResponse.schema.json @@ -0,0 +1,69 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/getCurrentContextResponse.schema.json", + "type": "object", + "title": "GetCurrentContext Response", + "description": "A response to a getCurrentContext request.", + "allOf": [ + { + "$ref": "agentResponse.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/GetCurrentContextResponseType" + }, + "payload": { + "oneOf": [ + { + "$ref": "#/$defs/GetCurrentContextSuccessResponsePayload" + }, + { + "$ref": "#/$defs/GetCurrentContextErrorResponsePayload" + } + ] + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "GetCurrentContextResponseType": { + "title": "GetCurrentContext Response Message Type", + "const": "getCurrentContextResponse" + }, + "GetCurrentContextSuccessResponsePayload": { + "title": "GetCurrentContext Response Payload", + "type": "object", + "properties": { + "context": { + "title": "Current Context", + "description": "The most recently broadcast context object (of the specified type, if one was specified), or `null` if none was available in the channel", + "oneOf": [ + { "$ref": "../context/context.schema.json" }, + { "type": "null" } + ] + } + }, + "required": [ + "context" + ], + "additionalProperties": false + }, + "GetCurrentContextErrorResponsePayload": { + "title": "GetCurrentContext Error Response Payload", + "type": "object", + "properties": { + "error": { + "$ref": "api.schema.json#/definitions/ChannelError" + } + }, + "required": [ + "error" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/getInfoRequest.schema.json b/schemas/api/getInfoRequest.schema.json new file mode 100644 index 000000000..b200b0ee0 --- /dev/null +++ b/schemas/api/getInfoRequest.schema.json @@ -0,0 +1,37 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/getInfoRequest.schema.json", + "type": "object", + "title": "GetInfo Request", + "description": "Request to retrieve information about the FDC3 Desktop Agent implementation and the metadata of the calling application according to the desktop agent.", + "allOf": [ + { + "$ref": "appRequest.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/GetInfoRequestType" + }, + "payload": { + "$ref": "#/$defs/GetInfoRequestPayload" + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "GetInfoRequestType": { + "title": "GetInfo Request Message Type", + "const": "getInfoRequest" + }, + "GetInfoRequestPayload": { + "title": "GetInfo Request Payload", + "type": "object", + "properties": {}, + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/getInfoResponse.schema.json b/schemas/api/getInfoResponse.schema.json new file mode 100644 index 000000000..a10a7749d --- /dev/null +++ b/schemas/api/getInfoResponse.schema.json @@ -0,0 +1,64 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/getInfoResponse.schema.json", + "type": "object", + "title": "GetInfo Response", + "description": "A response to a getInfo request.", + "allOf": [ + { + "$ref": "agentResponse.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/GetInfoResponseType" + }, + "payload": { + "oneOf": [ + { + "$ref": "#/$defs/GetInfoSuccessResponsePayload" + }, + { + "$ref": "#/$defs/GetInfoErrorResponsePayload" + } + ] + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "GetInfoResponseType": { + "title": "GetInfo Response Message Type", + "const": "getInfoResponse" + }, + "GetInfoSuccessResponsePayload": { + "title": "GetInfo Response Payload", + "type": "object", + "properties": { + "implementationMetadata": { + "$ref": "api.schema.json#/definitions/ImplementationMetadata" + } + }, + "required": [ + "implementationMetadata" + ], + "additionalProperties": false + }, + "GetInfoErrorResponsePayload": { + "title": "GetInfo Error Response Payload", + "type": "object", + "properties": { + "error": { + "$ref": "common.schema.json#/$defs/ErrorMessages" + } + }, + "required": [ + "error" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/getOrCreateChannelRequest.schema.json b/schemas/api/getOrCreateChannelRequest.schema.json new file mode 100644 index 000000000..9b6354d87 --- /dev/null +++ b/schemas/api/getOrCreateChannelRequest.schema.json @@ -0,0 +1,44 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/getOrCreateChannelRequest.schema.json", + "type": "object", + "title": "GetOrCreateChannel Request", + "description": "Request to return a Channel with an auto-generated identity that is intended for private communication between applications.", + "allOf": [ + { + "$ref": "appRequest.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/GetOrCreateChannelRequestType" + }, + "payload": { + "$ref": "#/$defs/GetOrCreateChannelRequestPayload" + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "GetOrCreateChannelRequestType": { + "title": "GetOrCreateChannel Request Message Type", + "const": "getOrCreateChannelRequest" + }, + "GetOrCreateChannelRequestPayload": { + "title": "GetOrCreateChannel Request Payload", + "type": "object", + "properties": { + "channelId": { + "title": "Channel Id", + "description": "The id of the channel to return", + "type": "string" + } + }, + "additionalProperties": false, + "required": ["channelId"] + } + } +} \ No newline at end of file diff --git a/schemas/api/getOrCreateChannelResponse.schema.json b/schemas/api/getOrCreateChannelResponse.schema.json new file mode 100644 index 000000000..d887c8277 --- /dev/null +++ b/schemas/api/getOrCreateChannelResponse.schema.json @@ -0,0 +1,64 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/getOrCreateChannelResponse.schema.json", + "type": "object", + "title": "GetOrCreateChannel Response", + "description": "A response to a getOrCreateChannel request.", + "allOf": [ + { + "$ref": "agentResponse.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/GetOrCreateChannelResponseType" + }, + "payload": { + "oneOf": [ + { + "$ref": "#/$defs/GetOrCreateChannelSuccessResponsePayload" + }, + { + "$ref": "#/$defs/GetOrCreateChannelErrorResponsePayload" + } + ] + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "GetOrCreateChannelResponseType": { + "title": "GetOrCreateChannel Response Message Type", + "const": "getOrCreateChannelResponse" + }, + "GetOrCreateChannelSuccessResponsePayload": { + "title": "GetOrCreateChannel Response Payload", + "type": "object", + "properties": { + "channel": { + "$ref": "api.schema.json#/definitions/Channel" + } + }, + "required": [ + "channel" + ], + "additionalProperties": false + }, + "GetOrCreateChannelErrorResponsePayload": { + "title": "GetOrCreateChannel Error Response Payload", + "type": "object", + "properties": { + "error": { + "$ref": "api.schema.json#/definitions/ChannelError" + } + }, + "required": [ + "error" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/getUserChannelsRequest.schema.json b/schemas/api/getUserChannelsRequest.schema.json new file mode 100644 index 000000000..697c49a1d --- /dev/null +++ b/schemas/api/getUserChannelsRequest.schema.json @@ -0,0 +1,37 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/getUserChannelsRequest.schema.json", + "type": "object", + "title": "GetUserChannels Request", + "description": "Request to retrieve a list of the User Channels available for the app to join.", + "allOf": [ + { + "$ref": "appRequest.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/GetUserChannelsRequestType" + }, + "payload": { + "$ref": "#/$defs/GetUserChannelsRequestPayload" + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "GetUserChannelsRequestType": { + "title": "GetUserChannels Request Message Type", + "const": "getUserChannelsRequest" + }, + "GetUserChannelsRequestPayload": { + "title": "GetUserChannels Request Payload", + "type": "object", + "properties": {}, + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/getUserChannelsResponse.schema.json b/schemas/api/getUserChannelsResponse.schema.json new file mode 100644 index 000000000..ad352f21d --- /dev/null +++ b/schemas/api/getUserChannelsResponse.schema.json @@ -0,0 +1,67 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/getUserChannelsResponse.schema.json", + "type": "object", + "title": "GetUserChannels Response", + "description": "A response to a getUserChannels request.", + "allOf": [ + { + "$ref": "agentResponse.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/GetUserChannelsResponseType" + }, + "payload": { + "oneOf": [ + { + "$ref": "#/$defs/GetUserChannelsSuccessResponsePayload" + }, + { + "$ref": "#/$defs/GetUserChannelsErrorResponsePayload" + } + ] + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "GetUserChannelsResponseType": { + "title": "GetUserChannels Response Message Type", + "const": "getUserChannelsResponse" + }, + "GetUserChannelsSuccessResponsePayload": { + "title": "GetUserChannels Response Payload", + "type": "object", + "properties": { + "userChannels": { + "type": "array", + "items": { + "$ref": "api.schema.json#/definitions/Channel" + } + } + }, + "required": [ + "userChannels" + ], + "additionalProperties": false + }, + "GetUserChannelsErrorResponsePayload": { + "title": "GetUserChannels Error Response Payload", + "type": "object", + "properties": { + "error": { + "$ref": "api.schema.json#/definitions/ChannelError" + } + }, + "required": [ + "error" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/heartbeatAcknowledgmentRequest.schema.json b/schemas/api/heartbeatAcknowledgmentRequest.schema.json new file mode 100644 index 000000000..b500ab1b0 --- /dev/null +++ b/schemas/api/heartbeatAcknowledgmentRequest.schema.json @@ -0,0 +1,46 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/heartbeatAcknowledgementRequest.schema.json", + "type": "object", + "title": "HeartbeatAcknowledgement Request", + "description": "A request that serves as an acknowledgement of a heartbeat event from the Desktop Agent and indicates that an application window or frame is still alive.", + "allOf": [ + { + "$ref": "appRequest.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/HeartbeatAcknowledgementRequestType" + }, + "payload": { + "$ref": "#/$defs/HeartbeatAcknowledgementRequestPayload" + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "HeartbeatAcknowledgementRequestType": { + "title": "HeartbeatAcknowledgement Request Message Type", + "const": "heartbeatAcknowledgementRequest" + }, + "HeartbeatAcknowledgementRequestPayload": { + "title": "heartbeatAcknowledgement Request Payload", + "type": "object", + "properties": { + "heartbeatEventUuid": { + "title": "Heartbeat Event Uuid", + "type": "string", + "description": "The eventUuid value of the HeartbeatEvent that the acknowledgement being sent relates to." + } + }, + "additionalProperties": false, + "required": [ + "heartbeatEventUuid" + ] + } + } +} \ No newline at end of file diff --git a/schemas/api/heartbeatEvent.schema.json b/schemas/api/heartbeatEvent.schema.json new file mode 100644 index 000000000..e1bdd9704 --- /dev/null +++ b/schemas/api/heartbeatEvent.schema.json @@ -0,0 +1,38 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/heartbeatEvent.schema.json", + "type": "object", + "title": "Heartbeat Event", + "description": "A heartbeat message from the Desktop Agent to an app indicating that the Desktop Agent is alive and that the application should send a heartbeatResponseRequest to the agent in response.", + "allOf": [ + { + "$ref": "agentEvent.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/HeartbeatEventType" + }, + "payload": { + "$ref": "#/$defs/HeartbeatEventPayload" + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "HeartbeatEventType": { + "title": "Heartbeat Event Message Type", + "const": "heartbeatEvent" + }, + "HeartbeatEventPayload": { + "title": "heartbeat Event Payload", + "type": "object", + "properties": {}, + "additionalProperties": false, + "required": [] + } + } +} \ No newline at end of file diff --git a/schemas/api/intentEvent.schema.json b/schemas/api/intentEvent.schema.json new file mode 100644 index 000000000..f6523b8cf --- /dev/null +++ b/schemas/api/intentEvent.schema.json @@ -0,0 +1,61 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/intentEvent.schema.json", + "type": "object", + "title": "intent Event", + "description": "An event message from the Desktop Agent to an app indicating that it has been selected to resolve a raised intent and context.", + "allOf": [ + { + "$ref": "agentEvent.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/IntentEventType" + }, + "payload": { + "$ref": "#/$defs/IntentEventPayload" + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "IntentEventType": { + "title": "Intent Event Message Type", + "const": "intentEvent" + }, + "IntentEventPayload": { + "title": "Intent Event Payload", + "type": "object", + "properties": { + "intent": { + "title": "Intent", + "description": "The intent that was raised.", + "type": "string" + }, + "context": { + "$ref": "../context/context.schema.json", + "title": "Context", + "description": "The context object passed with the raised intent." + }, + "originatingApp": { + "title": "Originating AppIdentifier", + "description": "Details of the application instance that raised the intent", + "$ref": "api.schema.json#/definitions/AppIdentifier" + }, + "raiseIntentRequestUuid": { + "title": "raiseIntentRequest UUID", + "type": "string", + "description": "The requestUuid value of the raiseIntentRequest that the intentEvent being sent relates to." + } + }, + "additionalProperties": false, + "required": [ + "intent", "context", "raiseIntentRequestUuid" + ] + } + } +} \ No newline at end of file diff --git a/schemas/api/intentListenerUnsubscribeRequest.schema.json b/schemas/api/intentListenerUnsubscribeRequest.schema.json new file mode 100644 index 000000000..1de21f601 --- /dev/null +++ b/schemas/api/intentListenerUnsubscribeRequest.schema.json @@ -0,0 +1,44 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/intentListenerUnsubscribeRequest.schema.json", + "type": "object", + "title": "IntentListenerUnsubscribe Request", + "description": "A request to unsubscribe a context listener.", + "allOf": [ + { + "$ref": "appRequest.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/IntentListenerUnsubscribeRequestType" + }, + "payload": { + "$ref": "#/$defs/IntentListenerUnsubscribeRequestPayload" + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "IntentListenerUnsubscribeRequestType": { + "title": "IntentListenerUnsubscribe Request Message Type", + "const": "intentListenerUnsubscribeRequest" + }, + "IntentListenerUnsubscribeRequestPayload": { + "title": "IntentListenerUnsubscribe Request Payload", + "type": "object", + "properties": { + "listenerUUID": { + "$ref": "common.schema.json#/$defs/ListenerUuid" + } + }, + "required": [ + "listenerUUID" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/intentListenerUnsubscribeResponse.schema.json b/schemas/api/intentListenerUnsubscribeResponse.schema.json new file mode 100644 index 000000000..582ace791 --- /dev/null +++ b/schemas/api/intentListenerUnsubscribeResponse.schema.json @@ -0,0 +1,29 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/intentListenerUnsubscribeResponse.schema.json", + "type": "object", + "title": "IntentListenerUnsubscribe Response", + "description": "A response to a intentListenerUnsubscribe request.", + "allOf": [ + { + "$ref": "agentResponse.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/IntentListenerUnsubscribeResponseType" + }, + "payload": true, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "IntentListenerUnsubscribeResponseType": { + "title": "IntentListenerUnsubscribe Response Message Type", + "const": "intentListenerUnsubscribeResponse" + } + } +} \ No newline at end of file diff --git a/schemas/api/intentResultRequest.schema.json b/schemas/api/intentResultRequest.schema.json new file mode 100644 index 000000000..d95de797f --- /dev/null +++ b/schemas/api/intentResultRequest.schema.json @@ -0,0 +1,54 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/IntentResultRequest.schema.json", + "type": "object", + "title": "IntentResult Request", + "description": "A request to deliver a result for an intent (which may include a `void` result that just indicates that the handler has run, returning no result). The result is tied to the intentEvent it relates to by quoting the `eventUuid` of the intentEvent in its payload.", + "allOf": [ + { + "$ref": "appRequest.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/IntentResultRequestType" + }, + "payload": { + "$ref": "#/$defs/IntentResultRequestPayload" + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "IntentResultRequestType": { + "title": "IntentResult Request Message Type", + "const": "intentResultRequest" + }, + "IntentResultRequestPayload": { + "title": "IntentResult Request Payload", + "type": "object", + "properties": { + "intentEventUuid": { + "title": "IntentEvent UUID", + "type": "string", + "description": "The eventUuid value of the intentEvent that the result being sent relates to." + }, + "raiseIntentRequestUuid": { + "title": "raiseIntentRequest UUID", + "type": "string", + "description": "The requestUuid value of the raiseIntentRequest that the result being sent relates to." + }, + "intentResult": { + "$ref": "api.schema.json#/definitions/IntentResult" + } + }, + "required": [ + "intentEventUuid", "raiseIntentRequestUuid", "intentResult" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/intentResultResponse.schema.json b/schemas/api/intentResultResponse.schema.json new file mode 100644 index 000000000..ef520ba37 --- /dev/null +++ b/schemas/api/intentResultResponse.schema.json @@ -0,0 +1,29 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/IntentResultResponse.schema.json", + "type": "object", + "title": "IntentResult Response", + "description": "A response to a request to deliver an intent result.", + "allOf": [ + { + "$ref": "agentResponse.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/IntentResultResponseType" + }, + "payload": true, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "IntentResultResponseType": { + "title": "IntentResult Response Message Type", + "const": "intentResultResponse" + } + } +} \ No newline at end of file diff --git a/schemas/api/joinUserChannelRequest.schema.json b/schemas/api/joinUserChannelRequest.schema.json new file mode 100644 index 000000000..12f6a9249 --- /dev/null +++ b/schemas/api/joinUserChannelRequest.schema.json @@ -0,0 +1,44 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/joinUserChannelRequest.schema.json", + "type": "object", + "title": "JoinUserChannel Request", + "description": "Request to join the app to the specified User channel. On successfully joining a channel, client code should make subsequent requests to get the current context of that channel for all registered context listeners and then call their handlers with it.", + "allOf": [ + { + "$ref": "appRequest.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/JoinUserChannelRequestType" + }, + "payload": { + "$ref": "#/$defs/JoinUserChannelRequestPayload" + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "JoinUserChannelRequestType": { + "title": "JoinUserChannel Request Message Type", + "const": "joinUserChannelRequest" + }, + "JoinUserChannelRequestPayload": { + "title": "JoinUserChannel Request Payload", + "type": "object", + "properties": { + "channelId": { + "title": "Channel Id", + "description": "The id of the channel to join", + "type": "string" + } + }, + "additionalProperties": false, + "required": ["channelId"] + } + } +} \ No newline at end of file diff --git a/schemas/api/joinUserChannelResponse.schema.json b/schemas/api/joinUserChannelResponse.schema.json new file mode 100644 index 000000000..fe6aeedcb --- /dev/null +++ b/schemas/api/joinUserChannelResponse.schema.json @@ -0,0 +1,59 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/joinUserChannelResponse.schema.json", + "type": "object", + "title": "JoinUserChannel Response", + "description": "A response to a joinUserChannel request. On receipt of this response, client code should make subsequent requests to get the current context of that channel for all registered context listeners and then call their handlers with it.", + "allOf": [ + { + "$ref": "agentResponse.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/JoinUserChannelResponseType" + }, + "payload": { + "oneOf": [ + { + "$ref": "#/$defs/JoinUserChannelSuccessResponsePayload" + }, + { + "$ref": "#/$defs/JoinUserChannelErrorResponsePayload" + } + ] + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "JoinUserChannelResponseType": { + "title": "JoinUserChannel Response Message Type", + "const": "joinUserChannelResponse" + }, + "JoinUserChannelSuccessResponsePayload": { + "title": "JoinUserChannel Response Payload", + "type": "object", + "properties": { + + }, + "additionalProperties": false + }, + "JoinUserChannelErrorResponsePayload": { + "title": "JoinUserChannel Error Response Payload", + "type": "object", + "properties": { + "error": { + "$ref": "api.schema.json#/definitions/ChannelError" + } + }, + "required": [ + "error" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/leaveCurrentChannelRequest.schema.json b/schemas/api/leaveCurrentChannelRequest.schema.json new file mode 100644 index 000000000..d78488fc6 --- /dev/null +++ b/schemas/api/leaveCurrentChannelRequest.schema.json @@ -0,0 +1,37 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/leaveCurrentChannelRequest.schema.json", + "type": "object", + "title": "LeaveCurrentChannel Request", + "description": "Request to remove the app from any User channel membership.", + "allOf": [ + { + "$ref": "appRequest.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/LeaveCurrentChannelRequestType" + }, + "payload": { + "$ref": "#/$defs/LeaveCurrentChannelRequestPayload" + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "LeaveCurrentChannelRequestType": { + "title": "LeaveCurrentChannel Request Message Type", + "const": "leaveCurrentChannelRequest" + }, + "LeaveCurrentChannelRequestPayload": { + "title": "LeaveCurrentChannel Request Payload", + "type": "object", + "properties": {}, + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/leaveCurrentChannelResponse.schema.json b/schemas/api/leaveCurrentChannelResponse.schema.json new file mode 100644 index 000000000..9dc9d0938 --- /dev/null +++ b/schemas/api/leaveCurrentChannelResponse.schema.json @@ -0,0 +1,57 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/leaveCurrentChannelResponse.schema.json", + "type": "object", + "title": "LeaveCurrentChannel Response", + "description": "A response to a leaveCurrentChannel request.", + "allOf": [ + { + "$ref": "agentResponse.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/LeaveCurrentChannelResponseType" + }, + "payload": { + "oneOf": [ + { + "$ref": "#/$defs/LeaveCurrentChannelSuccessResponsePayload" + }, + { + "$ref": "#/$defs/LeaveCurrentChannelErrorResponsePayload" + } + ] + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "LeaveCurrentChannelResponseType": { + "title": "LeaveCurrentChannel Response Message Type", + "const": "leaveCurrentChannelResponse" + }, + "LeaveCurrentChannelSuccessResponsePayload": { + "title": "LeaveCurrentChannel Response Payload", + "type": "object", + "properties": {}, + "additionalProperties": false + }, + "LeaveCurrentChannelErrorResponsePayload": { + "title": "LeaveCurrentChannel Error Response Payload", + "type": "object", + "properties": { + "error": { + "$ref": "api.schema.json#/definitions/ChannelError" + } + }, + "required": [ + "error" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/openRequest.schema.json b/schemas/api/openRequest.schema.json new file mode 100644 index 000000000..042e786ae --- /dev/null +++ b/schemas/api/openRequest.schema.json @@ -0,0 +1,49 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/openRequest.schema.json", + "type": "object", + "title": "Open Request", + "description": "A request to open an application.", + "allOf": [ + { + "$ref": "appRequest.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/OpenRequestType" + }, + "payload": { + "$ref": "#/$defs/OpenRequestPayload" + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "OpenRequestType": { + "title": "Open Request Message Type", + "const": "openRequest" + }, + "OpenRequestPayload": { + "title": "Open Request Payload", + "type": "object", + "properties": { + "app": { + "$ref": "api.schema.json#/definitions/AppIdentifier" + }, + "context": { + "$ref": "../context/context.schema.json", + "title": "Context", + "description": "If a Context object is passed in, this object will be provided to the opened application via a contextListener. The Context argument is functionally equivalent to opening the target app with no context and broadcasting the context directly to it." + } + }, + "required": [ + "app" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/openResponse.schema.json b/schemas/api/openResponse.schema.json new file mode 100644 index 000000000..c5ea42bbb --- /dev/null +++ b/schemas/api/openResponse.schema.json @@ -0,0 +1,72 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/openResponse.schema.json", + "type": "object", + "title": "Open Response", + "description": "A response to a open request.", + "allOf": [ + { + "$ref": "agentResponse.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/OpenResponseType" + }, + "payload": { + "oneOf": [ + { + "$ref": "#/$defs/OpenSuccessResponsePayload" + }, + { + "$ref": "#/$defs/OpenErrorResponsePayload" + } + ] + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "OpenResponseType": { + "title": "Open Response Message Type", + "const": "openResponse" + }, + "OpenSuccessResponsePayload": { + "title": "Open Response Payload", + "type": "object", + "properties": { + "appIdentifier": { + "$ref": "api.schema.json#/definitions/AppIdentifier" + } + }, + "required": [ + "appIdentifier" + ], + "additionalProperties": false + }, + "OpenErrorResponsePayload": { + "title": "Open Error Response Payload", + "type": "object", + "properties": { + "error": { + "title": "Open Error Response Payload", + "oneOf": [ + { + "$ref": "api.schema.json#/definitions/OpenError" + }, + { + "$ref": "api.schema.json#/definitions/BridgingError" + } + ] + } + }, + "required": [ + "error" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/privateChannelAddEventListenerRequest.schema.json b/schemas/api/privateChannelAddEventListenerRequest.schema.json new file mode 100644 index 000000000..2c07afb86 --- /dev/null +++ b/schemas/api/privateChannelAddEventListenerRequest.schema.json @@ -0,0 +1,52 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/privateChannelAddEventListenerRequest.schema.json", + "type": "object", + "title": "PrivateChannelAddEventListener Request", + "description": "A request to add an event listener to a specific PrivateChannel.", + "allOf": [ + { + "$ref": "appRequest.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/PrivateChannelAddEventListenerRequestType" + }, + "payload": { + "$ref": "#/$defs/PrivateChannelAddEventListenerRequestPayload" + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "PrivateChannelAddEventListenerRequestType": { + "title": "PrivateChannelAddEventListener Request Message Type", + "const": "privateChannelAddEventListenerRequest" + }, + "PrivateChannelAddEventListenerRequestPayload": { + "title": "privateChannelAddEventListener Event Payload", + "type": "object", + "properties": { + "privateChannelId": { + "title": "Private Channel Id", + "description": "The Id of the PrivateChannel that the listener should be added to.", + "type": "string" + }, + "listenerType": { + "title": "Event listener type", + "description": "The type of PrivateChannel event that the listener should be applied to.", + "$ref": "common.schema.json#/$defs/PrivateChannelEventListenerTypes" + } + }, + "additionalProperties": false, + "required": [ + "privateChannelId", + "listenerType" + ] + } + } +} \ No newline at end of file diff --git a/schemas/api/privateChannelAddEventListenerResponse.schema.json b/schemas/api/privateChannelAddEventListenerResponse.schema.json new file mode 100644 index 000000000..45564b339 --- /dev/null +++ b/schemas/api/privateChannelAddEventListenerResponse.schema.json @@ -0,0 +1,63 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/privateChannelAddEventListenerResponse.schema.json", + "type": "object", + "title": "PrivateChannelAddEventListener Response", + "description": "A response to a privateChannelAddEventListener request.", + "allOf": [ + { + "$ref": "agentResponse.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/PrivateChannelAddEventListenerResponseType" + }, + "payload": { + "oneOf": [ + { + "$ref": "#/$defs/PrivateChannelAddEventListenerSuccessResponsePayload" + }, + { + "$ref": "#/$defs/PrivateChannelAddEventListenerErrorResponsePayload" + } + ] + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "PrivateChannelAddEventListenerResponseType": { + "title": "PrivateChannelAddEventListener Response Message Type", + "const": "privateChannelAddEventListenerResponse" + }, + "PrivateChannelAddEventListenerSuccessResponsePayload": { + "title": "PrivateChannelAddEventListener Response Payload", + "type": "object", + "properties": { + "listenerUUID": { + "$ref": "common.schema.json#/$defs/ListenerUuid" + } + }, + "required": [ + "listenerUUID" + ] + }, + "PrivateChannelAddEventListenerErrorResponsePayload": { + "title": "PrivateChannelAddEventListener Error Response Payload", + "type": "object", + "properties": { + "error": { + "$ref": "api.schema.json#/definitions/ChannelError" + } + }, + "required": [ + "error" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/privateChannelDisconnectRequest.schema.json b/schemas/api/privateChannelDisconnectRequest.schema.json new file mode 100644 index 000000000..0c0986764 --- /dev/null +++ b/schemas/api/privateChannelDisconnectRequest.schema.json @@ -0,0 +1,44 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/privateChannelDisconnectRequest.schema.json", + "type": "object", + "title": "PrivateChannelDisconnect Request", + "description": "Request that indicates that a participant will no longer interact with a specified `PrivateChannel`.", + "allOf": [ + { + "$ref": "appRequest.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/PrivateChannelDisconnectRequestType" + }, + "payload": { + "$ref": "#/$defs/PrivateChannelDisconnectRequestPayload" + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "PrivateChannelDisconnectRequestType": { + "title": "PrivateChannelDisconnect Request Message Type", + "const": "privateChannelDisconnectRequest" + }, + "PrivateChannelDisconnectRequestPayload": { + "title": "PrivateChannelDisconnect Request Payload", + "type": "object", + "properties": { + "channelId": { + "type": "string", + "title": "Channel Id", + "description": "The Id of the Channel that should be disconnected from" + } + }, + "required": ["channelId"], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/privateChannelDisconnectResponse.schema.json b/schemas/api/privateChannelDisconnectResponse.schema.json new file mode 100644 index 000000000..56eabb6e1 --- /dev/null +++ b/schemas/api/privateChannelDisconnectResponse.schema.json @@ -0,0 +1,57 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/privateChannelDisconnectResponse.schema.json", + "type": "object", + "title": "PrivateChannelDisconnect Response", + "description": "A response to a privateChannelDisconnect request.", + "allOf": [ + { + "$ref": "agentResponse.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/PrivateChannelDisconnectResponseType" + }, + "payload": { + "oneOf": [ + { + "$ref": "#/$defs/PrivateChannelDisconnectSuccessResponsePayload" + }, + { + "$ref": "#/$defs/PrivateChannelDisconnectErrorResponsePayload" + } + ] + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "PrivateChannelDisconnectResponseType": { + "title": "PrivateChannelDisconnect Response Message Type", + "const": "privateChannelDisconnectResponse" + }, + "PrivateChannelDisconnectSuccessResponsePayload": { + "title": "PrivateChannelDisconnect Response Payload", + "type": "object", + "properties": {}, + "additionalProperties": false + }, + "PrivateChannelDisconnectErrorResponsePayload": { + "title": "PrivateChannelDisconnect Error Response Payload", + "type": "object", + "properties": { + "error": { + "$ref": "api.schema.json#/definitions/ChannelError" + } + }, + "required": [ + "error" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/privateChannelOnAddContextListenerEvent.schema.json b/schemas/api/privateChannelOnAddContextListenerEvent.schema.json new file mode 100644 index 000000000..3b713bc9e --- /dev/null +++ b/schemas/api/privateChannelOnAddContextListenerEvent.schema.json @@ -0,0 +1,59 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/privateChannelOnAddContextListenerEvent.schema.json", + "type": "object", + "title": "privateChannelOnAddContextListener Event", + "description": "An event message from the Desktop Agent to an app indicating that another app has added a context listener to a specific PrivateChannel.", + "allOf": [ + { + "$ref": "agentEvent.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/PrivateChannelOnAddContextListenerEventType" + }, + "payload": { + "$ref": "#/$defs/PrivateChannelOnAddContextListenerEventPayload" + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "PrivateChannelOnAddContextListenerEventType": { + "title": "PrivateChannelOnAddContextListener Event Message Type", + "const": "privateChannelOnAddContextListenerEvent" + }, + "PrivateChannelOnAddContextListenerEventPayload": { + "title": "privateChannelOnAddContextListener Event Payload", + "type": "object", + "properties": { + "privateChannelId": { + "type": "string", + "title": "Private Channel Id", + "description": "The Id of the PrivateChannel that the listener was added to." + }, + "contextType": { + "title": "Context type", + "description": "The type of the context listener added to the channel by another app, or null if it will listen to all types.", + "oneOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "required": [ + "privateChannelId", + "contextType" + ] + } + } +} \ No newline at end of file diff --git a/schemas/api/privateChannelOnDisconnectEvent.schema.json b/schemas/api/privateChannelOnDisconnectEvent.schema.json new file mode 100644 index 000000000..9a0432ad7 --- /dev/null +++ b/schemas/api/privateChannelOnDisconnectEvent.schema.json @@ -0,0 +1,46 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/privateChannelOnDisconnectEvent.schema.json", + "type": "object", + "title": "privateChannelOnDisconnect Event", + "description": "An event message from the Desktop Agent to an app indicating that another app has disconnected from a specific PrivateChannel and will no longer interact with it.", + "allOf": [ + { + "$ref": "agentEvent.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/PrivateChannelOnDisconnectEventType" + }, + "payload": { + "$ref": "#/$defs/PrivateChannelOnDisconnectEventPayload" + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "PrivateChannelOnDisconnectEventType": { + "title": "PrivateChannelOnDisconnect Event Message Type", + "const": "privateChannelOnDisconnectEvent" + }, + "PrivateChannelOnDisconnectEventPayload": { + "title": "privateChannelOnDisconnect Event Payload", + "type": "object", + "properties": { + "privateChannelId": { + "type": "string", + "title": "Private Channel Id", + "description": "The Id of the PrivateChannel that the app has disconnected from." + } + }, + "additionalProperties": false, + "required": [ + "privateChannelId" + ] + } + } +} \ No newline at end of file diff --git a/schemas/api/privateChannelOnUnsubscribeEvent.schema.json b/schemas/api/privateChannelOnUnsubscribeEvent.schema.json new file mode 100644 index 000000000..2ae1781b7 --- /dev/null +++ b/schemas/api/privateChannelOnUnsubscribeEvent.schema.json @@ -0,0 +1,59 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/privateChannelOnUnsubscribeEvent.schema.json", + "type": "object", + "title": "PrivateChannelOnUnsubscribe Event", + "description": "An event message from the Desktop Agent to an app indicating that another app has unsubscribed a context listener from a specific PrivateChannel.", + "allOf": [ + { + "$ref": "agentEvent.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/PrivateChannelOnUnsubscribeEventType" + }, + "payload": { + "$ref": "#/$defs/PrivateChannelOnUnsubscribeEventPayload" + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "PrivateChannelOnUnsubscribeEventType": { + "title": "PrivateChannelOnUnsubscribe Event Message Type", + "const": "privateChannelOnUnsubscribeEvent" + }, + "PrivateChannelOnUnsubscribeEventPayload": { + "title": "privateChannelOnUnsubscribe Event Payload", + "type": "object", + "properties": { + "privateChannelId": { + "type": "string", + "title": "Private Channel Id", + "description": "The Id of the PrivateChannel that the listener was unsubscribed from." + }, + "contextType": { + "title": "Context type", + "description": "The type of the context listener unsubscribed from the channel by another app, or null if it was listening to all types.", + "oneOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "required": [ + "privateChannelId", + "contextType" + ] + } + } +} \ No newline at end of file diff --git a/schemas/api/privateChannelUnsubscribeEventListenerRequest.schema.json b/schemas/api/privateChannelUnsubscribeEventListenerRequest.schema.json new file mode 100644 index 000000000..658ebcce8 --- /dev/null +++ b/schemas/api/privateChannelUnsubscribeEventListenerRequest.schema.json @@ -0,0 +1,44 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/privateChannelUnsubscribeEventListenerRequest.schema.json", + "type": "object", + "title": "PrivateChannelUnsubscribeEventListener Request", + "description": "A request to unsubscribe a context listener.", + "allOf": [ + { + "$ref": "appRequest.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/PrivateChannelUnsubscribeEventListenerRequestType" + }, + "payload": { + "$ref": "#/$defs/PrivateChannelUnsubscribeEventListenerRequestPayload" + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "PrivateChannelUnsubscribeEventListenerRequestType": { + "title": "PrivateChannelUnsubscribeEventListener Request Message Type", + "const": "privateChannelUnsubscribeEventListenerRequest" + }, + "PrivateChannelUnsubscribeEventListenerRequestPayload": { + "title": "PrivateChannelUnsubscribeEventListener Request Payload", + "type": "object", + "properties": { + "listenerUUID": { + "$ref": "common.schema.json#/$defs/ListenerUuid" + } + }, + "required": [ + "listenerUUID" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/privateChannelUnsubscribeEventListenerResponse.schema.json b/schemas/api/privateChannelUnsubscribeEventListenerResponse.schema.json new file mode 100644 index 000000000..327a72c24 --- /dev/null +++ b/schemas/api/privateChannelUnsubscribeEventListenerResponse.schema.json @@ -0,0 +1,29 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/privateChannelUnsubscribeEventListenerResponse.schema.json", + "type": "object", + "title": "PrivateChannelUnsubscribeEventListener Response", + "description": "A response to a privateChannelUnsubscribeEventListener request.", + "allOf": [ + { + "$ref": "agentResponse.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/PrivateChannelUnsubscribeEventListenerResponseType" + }, + "payload": true, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "PrivateChannelUnsubscribeEventListenerResponseType": { + "title": "PrivateChannelUnsubscribeEventListener Response Message Type", + "const": "privateChannelUnsubscribeEventListenerResponse" + } + } +} \ No newline at end of file diff --git a/schemas/api/raiseIntentForContextRequest.schema.json b/schemas/api/raiseIntentForContextRequest.schema.json new file mode 100644 index 000000000..da56d04f4 --- /dev/null +++ b/schemas/api/raiseIntentForContextRequest.schema.json @@ -0,0 +1,47 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/raiseIntentForContextRequest.schema.json", + "type": "object", + "title": "RaiseIntentForContext Request", + "description": "A request to raise an unspecified intent for a specified context.", + "allOf": [ + { + "$ref": "appRequest.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/RaiseIntentForContextRequestType" + }, + "payload": { + "$ref": "#/$defs/RaiseIntentForContextRequestPayload" + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "RaiseIntentForContextRequestType": { + "title": "RaiseIntentForContext Request Message Type", + "const": "raiseIntentForContextRequest" + }, + "RaiseIntentForContextRequestPayload": { + "title": "RaiseIntentForContext Request Payload", + "type": "object", + "properties": { + "context": { + "$ref": "../context/context.schema.json" + }, + "app": { + "$ref": "api.schema.json#/definitions/AppIdentifier" + } + }, + "required": [ + "context" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/raiseIntentForContextResponse.schema.json b/schemas/api/raiseIntentForContextResponse.schema.json new file mode 100644 index 000000000..ef8b950a7 --- /dev/null +++ b/schemas/api/raiseIntentForContextResponse.schema.json @@ -0,0 +1,63 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/raiseIntentForContextResponse.schema.json", + "type": "object", + "title": "RaiseIntentForContext Response", + "description": "A response to a raiseIntentForContext request.", + "allOf": [ + { + "$ref": "agentResponse.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/RaiseIntentForContextResponseType" + }, + "payload": { + "title": "RaiseIntentForContext Response Payload", + "description": "There are 3 possible responses to a raiseIntentForContext request, each of which sets a single property in the payload: Success (`intentResolution`), Needs further resolution (`appIntents`) or Error (`error`).", + "oneOf": [ + { + "$ref": "raiseIntentResponse.schema.json#/$defs/RaiseIntentSuccessResponsePayload" + }, + { + "$ref": "#/$defs/RaiseIntentForContextNeedsResolutionResponsePayload" + }, + { + "$ref": "raiseIntentResponse.schema.json#/$defs/RaiseIntentErrorResponsePayload" + } + ] + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "RaiseIntentForContextResponseType": { + "title": "RaiseIntentForContext Response Message Type", + "const": "raiseIntentForContextResponse" + }, + "RaiseIntentForContextNeedsResolutionResponsePayload": { + "title": "RaiseIntentForContext NeedsResolution Response Payload", + "description": "Response to a raiseIntentForContext request that needs additional resolution (i.e. show an intent resolver UI)", + "type": "object", + "properties": { + "appIntents": { + "title": "AppIntents", + "description": "Used if a raiseIntentForContext request requires additional resolution (e.g. by showing an intent resolver) before it can be handled.", + "type": "array", + "items": { + "$ref": "api.schema.json#/definitions/AppIntent" + }, + "additionalProperties": false + } + }, + "required": [ + "appIntents" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/raiseIntentRequest.schema.json b/schemas/api/raiseIntentRequest.schema.json new file mode 100644 index 000000000..9833b2417 --- /dev/null +++ b/schemas/api/raiseIntentRequest.schema.json @@ -0,0 +1,50 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/raiseIntentRequest.schema.json", + "type": "object", + "title": "RaiseIntent Request", + "description": "A request to raise an intent for a context.", + "allOf": [ + { + "$ref": "appRequest.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/RaiseIntentRequestType" + }, + "payload": { + "$ref": "#/$defs/RaiseIntentRequestPayload" + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "RaiseIntentRequestType": { + "title": "RaiseIntent Request Message Type", + "const": "raiseIntentRequest" + }, + "RaiseIntentRequestPayload": { + "title": "RaiseIntent Request Payload", + "type": "object", + "properties": { + "intent": { + "type": "string" + }, + "context": { + "$ref": "../context/context.schema.json" + }, + "app": { + "$ref": "api.schema.json#/definitions/AppIdentifier" + } + }, + "required": [ + "intent", "context" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/raiseIntentResponse.schema.json b/schemas/api/raiseIntentResponse.schema.json new file mode 100644 index 000000000..26179f615 --- /dev/null +++ b/schemas/api/raiseIntentResponse.schema.json @@ -0,0 +1,97 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/raiseIntentResponse.schema.json", + "type": "object", + "title": "RaiseIntent Response", + "description": "A response to a raiseIntent request.", + "allOf": [ + { + "$ref": "agentResponse.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/RaiseIntentResponseType" + }, + "payload": { + "title": "RaiseIntent Response Payload", + "description": "There are 3 possible responses to a raiseIntent request, each of which sets a single property in the payload: Success (`intentResolution`), Needs further resolution (`appIntent`) or Error (`error`).", + "oneOf": [ + { + "$ref": "#/$defs/RaiseIntentSuccessResponsePayload" + }, + { + "$ref": "#/$defs/RaiseIntentNeedsResolutionResponsePayload" + }, + { + "$ref": "#/$defs/RaiseIntentErrorResponsePayload" + } + ] + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "RaiseIntentResponseType": { + "title": "RaiseIntent Response Message Type", + "const": "raiseIntentResponse" + }, + "RaiseIntentSuccessResponsePayload": { + "title": "RaiseIntent Success Response Payload", + "type": "object", + "properties": { + "intentResolution": { + "title": "Intent Resolution", + "description": "Used if the raiseIntent request was successfully resolved", + "$ref": "api.schema.json#/definitions/IntentResolution" + } + }, + "required": [ + "intentResolution" + ], + "additionalProperties": false + }, + "RaiseIntentNeedsResolutionResponsePayload": { + "title": "RaiseIntent NeedsResolution Response Payload", + "description": "Response to a raiseIntent request that needs additional resolution (i.e. show an intent resolver UI).", + "type": "object", + "properties": { + "appIntent": { + "title": "AppIntent", + "description": "Used if a raiseIntent request requires additional resolution (e.g. by showing an intent resolver) before it can be handled.", + "$ref": "api.schema.json#/definitions/AppIntent" + } + }, + "required": [ + "appIntent" + ], + "additionalProperties": false + }, + "RaiseIntentErrorResponsePayload": { + "title": "RaiseIntent Error Response Payload", + "description": "Used if a raiseIntent request resulted in an error", + "type": "object", + "properties": { + "error": { + "title": "RaiseIntent Error", + "description": "Should be set if the raiseIntent request returned an error.", + "oneOf": [ + { + "$ref": "api.schema.json#/definitions/ResolveError" + }, + { + "$ref": "api.schema.json#/definitions/BridgingError" + } + ] + } + }, + "required": [ + "error" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/api/raiseIntentResultResponse.schema.json b/schemas/api/raiseIntentResultResponse.schema.json new file mode 100644 index 000000000..4cde49972 --- /dev/null +++ b/schemas/api/raiseIntentResultResponse.schema.json @@ -0,0 +1,64 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/api/raiseIntentResultResponse.schema.json", + "type": "object", + "title": "RaiseIntentResult Response", + "description": "A secondary response to a request to raise an intent used to deliver the intent result. This message should quote the original requestUuid of the raiseIntentRequest message in its `meta.requestUuid` field.", + "allOf": [ + { + "$ref": "agentResponse.schema.json" + }, + { + "type": "object", + "properties": { + "type": { + "$ref": "#/$defs/RaiseIntentResultResponseType" + }, + "payload": { + "oneOf": [ + { + "$ref": "#/$defs/RaiseIntentResultSuccessResponsePayload" + }, + { + "$ref": "#/$defs/RaiseIntentResultErrorResponsePayload" + } + ] + }, + "meta": true + }, + "additionalProperties": false + } + ], + "$defs": { + "RaiseIntentResultResponseType": { + "title": "RaiseIntentResult Response Message Type", + "const": "raiseIntentResultResponse" + }, + "RaiseIntentResultSuccessResponsePayload": { + "title": "RaiseIntent Result Response Payload", + "type": "object", + "properties": { + "intentResult": { + "$ref": "api.schema.json#/definitions/IntentResult" + } + }, + "required": [ + "intentResult" + ], + "additionalProperties": false + }, + "RaiseIntentResultErrorResponsePayload": { + "title": "RaiseIntentResult Error Response Payload", + "type": "object", + "properties": { + "error": { + "$ref": "common.schema.json#/$defs/ErrorMessages" + } + }, + "required": [ + "error" + ], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/schemas/bridging/agentErrorResponse.schema.json b/schemas/bridging/agentErrorResponse.schema.json index 75a0051c8..67b22bc11 100644 --- a/schemas/bridging/agentErrorResponse.schema.json +++ b/schemas/bridging/agentErrorResponse.schema.json @@ -25,7 +25,7 @@ "description": "Error message payload containing an standardized error string.", "properties": { "error": { - "$ref": "common.schema.json#/$defs/ErrorMessages" + "$ref": "../api/common.schema.json#/$defs/ErrorMessages" } }, "unevaluatedProperties": false, diff --git a/schemas/bridging/agentRequest.schema.json b/schemas/bridging/agentRequest.schema.json index f9f3ad553..edf763ef9 100644 --- a/schemas/bridging/agentRequest.schema.json +++ b/schemas/bridging/agentRequest.schema.json @@ -43,10 +43,10 @@ "type": "object", "properties": { "requestUuid": { - "$ref": "common.schema.json#/$defs/RequestUuid" + "$ref": "../api/common.schema.json#/$defs/RequestUuid" }, "timestamp": { - "$ref": "common.schema.json#/$defs/Timestamp" + "$ref": "../api/common.schema.json#/$defs/Timestamp" }, "source": { "title": "Source identifier", diff --git a/schemas/bridging/agentResponse.schema.json b/schemas/bridging/agentResponse.schema.json index 8c795b59e..e2d1d3a73 100644 --- a/schemas/bridging/agentResponse.schema.json +++ b/schemas/bridging/agentResponse.schema.json @@ -37,13 +37,13 @@ "type": "object", "properties": { "requestUuid": { - "$ref": "common.schema.json#/$defs/RequestUuid" + "$ref": "../api/common.schema.json#/$defs/RequestUuid" }, "responseUuid": { - "$ref": "common.schema.json#/$defs/ResponseUuid" + "$ref": "../api/common.schema.json#/$defs/ResponseUuid" }, "timestamp": { - "$ref": "common.schema.json#/$defs/Timestamp" + "$ref": "../api/common.schema.json#/$defs/Timestamp" } }, "required": ["requestUuid", "responseUuid", "timestamp"], diff --git a/schemas/bridging/bridgeErrorResponse.schema.json b/schemas/bridging/bridgeErrorResponse.schema.json index bd6fd15c0..31a55eb52 100644 --- a/schemas/bridging/bridgeErrorResponse.schema.json +++ b/schemas/bridging/bridgeErrorResponse.schema.json @@ -16,7 +16,7 @@ "description": "The error message payload contains details of an error return to the app or agent that raised the original request.", "properties": { "error": { - "$ref": "common.schema.json#/$defs/ErrorMessages" + "$ref": "../api/common.schema.json#/$defs/ErrorMessages" } } }, @@ -33,13 +33,13 @@ "type": "object", "properties": { "requestUuid": { - "$ref": "common.schema.json#/$defs/RequestUuid" + "$ref": "../api/common.schema.json#/$defs/RequestUuid" }, "responseUuid": { - "$ref": "common.schema.json#/$defs/ResponseUuid" + "$ref": "../api/common.schema.json#/$defs/ResponseUuid" }, "timestamp": { - "$ref": "common.schema.json#/$defs/Timestamp" + "$ref": "../api/common.schema.json#/$defs/Timestamp" }, "errorSources": { "$ref": "common.schema.json#/$defs/BridgeResponseErrorSources" diff --git a/schemas/bridging/bridgeRequest.schema.json b/schemas/bridging/bridgeRequest.schema.json index 27d50f8d8..cb4bf0e6d 100644 --- a/schemas/bridging/bridgeRequest.schema.json +++ b/schemas/bridging/bridgeRequest.schema.json @@ -28,10 +28,10 @@ "type": "object", "properties": { "requestUuid": { - "$ref": "common.schema.json#/$defs/RequestUuid" + "$ref": "../api/common.schema.json#/$defs/RequestUuid" }, "timestamp": { - "$ref": "common.schema.json#/$defs/Timestamp" + "$ref": "../api/common.schema.json#/$defs/Timestamp" }, "source": { "title": "Bridge Source identifier", diff --git a/schemas/bridging/bridgeResponse.schema.json b/schemas/bridging/bridgeResponse.schema.json index 0e3a23bdf..b05c84fa1 100644 --- a/schemas/bridging/bridgeResponse.schema.json +++ b/schemas/bridging/bridgeResponse.schema.json @@ -28,13 +28,13 @@ "type": "object", "properties": { "requestUuid": { - "$ref": "common.schema.json#/$defs/RequestUuid" + "$ref": "../api/common.schema.json#/$defs/RequestUuid" }, "responseUuid": { - "$ref": "common.schema.json#/$defs/ResponseUuid" + "$ref": "../api/common.schema.json#/$defs/ResponseUuid" }, "timestamp": { - "$ref": "common.schema.json#/$defs/Timestamp" + "$ref": "../api/common.schema.json#/$defs/Timestamp" }, "sources": { "$ref": "common.schema.json#/$defs/BridgeResponseSources" diff --git a/schemas/bridging/broadcastAgentRequest.schema.json b/schemas/bridging/broadcastAgentRequest.schema.json index fb95b4fea..24aedc190 100644 --- a/schemas/bridging/broadcastAgentRequest.schema.json +++ b/schemas/bridging/broadcastAgentRequest.schema.json @@ -18,26 +18,10 @@ "description": "A request to broadcast context on a channel.", "properties": { "type": { - "title": "Broadcast Request Message Type", - "const": "broadcastRequest" + "$ref": "../api/broadcastRequest.schema.json#/$defs/BroadcastRequestType" }, "payload": { - "title": "broadcast Request Payload", - "type": "object", - "properties": { - "channelId": { - "type": "string", - "title": "Channel Id", - "description": "The Id of the Channel that the broadcast was sent on" - }, - "context": { - "$ref": "../context/context.schema.json", - "title": "Context", - "description": "The context object that was the payload of a broadcast message." - } - }, - "additionalProperties": false, - "required": ["channelId", "context"] + "$ref": "../api/broadcastRequest.schema.json#/$defs/BroadcastRequestPayload" }, "meta": { "type": "object", diff --git a/schemas/bridging/common.schema.json b/schemas/bridging/common.schema.json index edbcd2858..3420ff166 100644 --- a/schemas/bridging/common.schema.json +++ b/schemas/bridging/common.schema.json @@ -1,26 +1,10 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "https://fdc3.finos.org/schemas/next/bridging/common.schema.json", - "title": "Bridging Commons", + "$id": "https://fdc3.finos.org/schemas/next/api/common.schema.json", + "title": "Bridge Common definitions", "type": "object", - "description": "Common elements referenced by other schemas", + "description": "Common definitions that are referenced only in the Bridging wire protocol schemas", "$defs": { - "RequestUuid": { - "title": "Request UUID", - "type": "string", - "description": "UUID for the request" - }, - "ResponseUuid": { - "title": "Response UUID", - "type": "string", - "description": "UUID for this specific response message." - }, - "Timestamp": { - "title": "Timestamp", - "type": "string", - "format": "date-time", - "description": "Timestamp at which request was generated" - }, "RequestSource": { "title": "Source identifier", "description": "Field that represents the source application that a request or response was received from, or the source Desktop Agent if it issued the request or response itself.", @@ -94,25 +78,6 @@ ], "description": "Array of DesktopAgentIdentifiers for responses that were not returned to the bridge before the timeout or because an error occurred. May be omitted if all sources responded without errors. MUST include the `desktopAgent` field when returned by the bridge." }, - "ErrorMessages": { - "oneOf": [ - { - "$ref": "../api/api.schema.json#/definitions/ChannelError" - }, - { - "$ref": "../api/api.schema.json#/definitions/OpenError" - }, - { - "$ref": "../api/api.schema.json#/definitions/ResolveError" - }, - { - "$ref": "../api/api.schema.json#/definitions/ResultError" - }, - { - "$ref": "../api/api.schema.json#/definitions/BridgingError" - } - ] - }, "BridgeResponseErrorDetails": { "title": "Response Error Details", "type": "array", @@ -121,16 +86,6 @@ }, "description": "Array of error message strings for responses that were not returned to the bridge before the timeout or because an error occurred. Should be the same length as the `errorSources` array and ordered the same. May be omitted if all sources responded without errors." }, - "PrivateChannelEventListenerTypes": { - "title": "Private Channel Event Listener Types", - "description": "Event listener type names for Private Channel events", - "type": "string", - "enum": [ - "onAddContextListener", - "onUnsubscribe", - "onDisconnect" - ] - }, "DesktopAgentImplementationMetadata": { "description": "Includes the name assigned to the Desktop Agent by the Bridge.", "title": "DesktopAgentImplementationMetadata", diff --git a/schemas/bridging/connectionStep.schema.json b/schemas/bridging/connectionStep.schema.json index 3c3a377b0..03d558571 100644 --- a/schemas/bridging/connectionStep.schema.json +++ b/schemas/bridging/connectionStep.schema.json @@ -35,13 +35,13 @@ "type": "object", "properties": { "requestUuid": { - "$ref": "common.schema.json#/$defs/RequestUuid" + "$ref": "../api/common.schema.json#/$defs/RequestUuid" }, "timestamp": { - "$ref": "common.schema.json#/$defs/Timestamp" + "$ref": "../api/common.schema.json#/$defs/Timestamp" }, "responseUuid": { - "$ref": "common.schema.json#/$defs/ResponseUuid" + "$ref": "../api/common.schema.json#/$defs/ResponseUuid" } }, "required": ["timestamp"], diff --git a/schemas/bridging/connectionStep2Hello.schema.json b/schemas/bridging/connectionStep2Hello.schema.json index 0ac240f6c..82ada01e5 100644 --- a/schemas/bridging/connectionStep2Hello.schema.json +++ b/schemas/bridging/connectionStep2Hello.schema.json @@ -57,7 +57,7 @@ "type": "object", "properties": { "timestamp": { - "$ref": "common.schema.json#/$defs/Timestamp" + "$ref": "../api/common.schema.json#/$defs/Timestamp" } }, "additionalProperties": false, diff --git a/schemas/bridging/connectionStep3Handshake.schema.json b/schemas/bridging/connectionStep3Handshake.schema.json index 11c683d12..408a60f84 100644 --- a/schemas/bridging/connectionStep3Handshake.schema.json +++ b/schemas/bridging/connectionStep3Handshake.schema.json @@ -81,10 +81,10 @@ "type": "object", "properties": { "requestUuid": { - "$ref": "common.schema.json#/$defs/RequestUuid" + "$ref": "../api/common.schema.json#/$defs/RequestUuid" }, "timestamp": { - "$ref": "common.schema.json#/$defs/Timestamp" + "$ref": "../api/common.schema.json#/$defs/Timestamp" } }, "additionalProperties": false, diff --git a/schemas/bridging/connectionStep4AuthenticationFailed.schema.json b/schemas/bridging/connectionStep4AuthenticationFailed.schema.json index 6cae52eca..20b03d0c0 100644 --- a/schemas/bridging/connectionStep4AuthenticationFailed.schema.json +++ b/schemas/bridging/connectionStep4AuthenticationFailed.schema.json @@ -37,13 +37,13 @@ "type": "object", "properties": { "requestUuid": { - "$ref": "common.schema.json#/$defs/RequestUuid" + "$ref": "../api/common.schema.json#/$defs/RequestUuid" }, "responseUuid": { - "$ref": "common.schema.json#/$defs/ResponseUuid" + "$ref": "../api/common.schema.json#/$defs/ResponseUuid" }, "timestamp": { - "$ref": "common.schema.json#/$defs/Timestamp" + "$ref": "../api/common.schema.json#/$defs/Timestamp" } }, "additionalProperties": false, diff --git a/schemas/bridging/connectionStep6ConnectedAgentsUpdate.schema.json b/schemas/bridging/connectionStep6ConnectedAgentsUpdate.schema.json index df8782dd0..5693ec015 100644 --- a/schemas/bridging/connectionStep6ConnectedAgentsUpdate.schema.json +++ b/schemas/bridging/connectionStep6ConnectedAgentsUpdate.schema.json @@ -63,13 +63,13 @@ "type": "object", "properties": { "requestUuid": { - "$ref": "common.schema.json#/$defs/RequestUuid" + "$ref": "../api/common.schema.json#/$defs/RequestUuid" }, "responseUuid": { - "$ref": "common.schema.json#/$defs/ResponseUuid" + "$ref": "../api/common.schema.json#/$defs/ResponseUuid" }, "timestamp": { - "$ref": "common.schema.json#/$defs/Timestamp" + "$ref": "../api/common.schema.json#/$defs/Timestamp" } }, "additionalProperties": false, diff --git a/schemas/bridging/findInstancesAgentErrorResponse.schema.json b/schemas/bridging/findInstancesAgentErrorResponse.schema.json index 798840f59..b703c106b 100644 --- a/schemas/bridging/findInstancesAgentErrorResponse.schema.json +++ b/schemas/bridging/findInstancesAgentErrorResponse.schema.json @@ -18,23 +18,10 @@ "description": "A response to a findInstances request that contains an error.", "properties": { "type": { - "title": "FindInstances Response Message Type", - "const": "findInstancesResponse" + "$ref": "../api/findInstancesResponse.schema.json#/$defs/FindInstancesResponseType" }, "payload": { - "title": "FindInstances Error Response Payload", - "type": "object", - "properties": { - "error": { - "title": "FindInstances Error Message", - "oneOf": [ - { "$ref": "../api/api.schema.json#/definitions/ResolveError" }, - { "$ref": "../api/api.schema.json#/definitions/BridgingError" } - ] - } - }, - "required": ["error"], - "additionalProperties": false + "$ref": "../api/findInstancesResponse.schema.json#/$defs/FindInstancesErrorResponsePayload" }, "meta": { "title": "FindInstances Response Metadata", diff --git a/schemas/bridging/findInstancesAgentRequest.schema.json b/schemas/bridging/findInstancesAgentRequest.schema.json index 3ea08288f..4d9d1934a 100644 --- a/schemas/bridging/findInstancesAgentRequest.schema.json +++ b/schemas/bridging/findInstancesAgentRequest.schema.json @@ -18,19 +18,10 @@ "description": "A request for details of instances of a particular app", "properties":{ "type": { - "title": "FindInstances Request Message Type", - "const": "findInstancesRequest" + "$ref": "../api/findInstancesRequest.schema.json#/$defs/FindInstancesRequestType" }, "payload": { - "type": "object", - "title": "FindInstances Request Payload", - "properties": { - "app": { - "$ref": "../api/api.schema.json#/definitions/AppIdentifier" - } - }, - "required": ["app"], - "additionalProperties": false + "$ref": "../api/findInstancesRequest.schema.json#/$defs/FindInstancesRequestPayload" }, "meta": { "title": "FindInstances request metadata", diff --git a/schemas/bridging/findInstancesAgentResponse.schema.json b/schemas/bridging/findInstancesAgentResponse.schema.json index 67f3937c6..87518e93f 100644 --- a/schemas/bridging/findInstancesAgentResponse.schema.json +++ b/schemas/bridging/findInstancesAgentResponse.schema.json @@ -18,29 +18,14 @@ "description": "A response to a findInstances request.", "properties": { "type": { - "title": "FindInstances Response Message Type", - "const": "findInstancesResponse" + "$ref": "../api/findInstancesResponse.schema.json#/$defs/FindInstancesResponseType" }, "payload": { - "title": "FindInstances Response Payload", - "type": "object", - "properties": { - "appIdentifiers": { - "type": "array", - "items": { - "$ref": "../api/api.schema.json#/definitions/AppMetadata" - } - } - }, - "required": ["appIdentifiers"], - "additionalProperties": false + "$ref": "../api/findInstancesResponse.schema.json#/$defs/FindInstancesSuccessResponsePayload" }, - "meta": { - "title": "FindInstances Response Metadata", - "type": "object" - } + "meta": true }, "additionalProperties": false } } -} +} \ No newline at end of file diff --git a/schemas/bridging/findIntentAgentErrorResponse.schema.json b/schemas/bridging/findIntentAgentErrorResponse.schema.json index b8d89cd9b..7c2e3e895 100644 --- a/schemas/bridging/findIntentAgentErrorResponse.schema.json +++ b/schemas/bridging/findIntentAgentErrorResponse.schema.json @@ -18,23 +18,10 @@ "description": "A response to a findIntent request that contains an error.", "properties": { "type": { - "title": "FindIntent Response Message Type", - "const": "findIntentResponse" + "$ref": "../api/findIntentResponse.schema.json#/$defs/FindIntentResponseType" }, "payload": { - "title": "FindIntent Error Response Payload", - "type": "object", - "properties": { - "error": { - "title": "FindIntent Error Message", - "oneOf": [ - { "$ref": "../api/api.schema.json#/definitions/ResolveError" }, - { "$ref": "../api/api.schema.json#/definitions/BridgingError" } - ] - } - }, - "required": ["error"], - "additionalProperties": false + "$ref": "../api/findIntentResponse.schema.json#/$defs/FindIntentErrorResponsePayload" }, "meta": { "title": "FindIntent Response Metadata", diff --git a/schemas/bridging/findIntentAgentRequest.schema.json b/schemas/bridging/findIntentAgentRequest.schema.json index 59c3dd70e..770b3ef71 100644 --- a/schemas/bridging/findIntentAgentRequest.schema.json +++ b/schemas/bridging/findIntentAgentRequest.schema.json @@ -18,28 +18,10 @@ "description": "A request for details of apps available to resolve a particular intent and context pair.", "properties": { "type": { - "title": "FindIntent Request Message Type", - "const": "findIntentRequest" + "$ref": "../api/findIntentRequest.schema.json#/$defs/FindIntentRequestType" }, "payload": { - "title": "FindIntent Request Payload", - "type": "object", - "properties": { - "intent": { - "title": "Intent name", - "type": "string" - }, - "context": { - "title": "Context argument", - "$ref": "../context/context.schema.json" - }, - "resultType": { - "title": "Result type argument", - "type": "string" - } - }, - "required": ["intent"], - "additionalProperties": false + "$ref": "../api/findIntentRequest.schema.json#/$defs/FindIntentRequestPayload" }, "meta": { "title" : "FindIntent Request Metadata", diff --git a/schemas/bridging/findIntentAgentResponse.schema.json b/schemas/bridging/findIntentAgentResponse.schema.json index 8969469bf..9f3b4685d 100644 --- a/schemas/bridging/findIntentAgentResponse.schema.json +++ b/schemas/bridging/findIntentAgentResponse.schema.json @@ -18,19 +18,10 @@ "description": "A response to a findIntent request.", "properties": { "type": { - "title": "FindIntent Response Message Type", - "const": "findIntentResponse" + "$ref": "../api/findIntentResponse.schema.json#/$defs/FindIntentResponseType" }, "payload": { - "title": "FindIntent Response Payload", - "type": "object", - "properties": { - "appIntent": { - "$ref": "../api/api.schema.json#/definitions/AppIntent" - } - }, - "required": ["appIntent"], - "additionalProperties": false + "$ref": "../api/findIntentResponse.schema.json#/$defs/FindIntentSuccessResponsePayload" }, "meta": { "title": "FindIntent Response Metadata", diff --git a/schemas/bridging/findIntentsByContextAgentErrorResponse.schema.json b/schemas/bridging/findIntentsByContextAgentErrorResponse.schema.json index 0bd1646c5..8270d0355 100644 --- a/schemas/bridging/findIntentsByContextAgentErrorResponse.schema.json +++ b/schemas/bridging/findIntentsByContextAgentErrorResponse.schema.json @@ -18,23 +18,10 @@ "description": "A response to a findIntentsByContext request that contains an error.", "properties": { "type": { - "title": "FindIntentsByContext Response Message Type", - "const": "findIntentsByContextResponse" + "$ref": "../api/findIntentsByContextResponse.schema.json#/$defs/FindIntentsByContextResponseType" }, "payload": { - "title": "FindIntentsByContext Error Response Payload", - "type": "object", - "properties": { - "error": { - "title": "FindIntentsByContext Error Message", - "oneOf": [ - { "$ref": "../api/api.schema.json#/definitions/ResolveError" }, - { "$ref": "../api/api.schema.json#/definitions/BridgingError" } - ] - } - }, - "additionalProperties": false, - "required": ["error"] + "$ref": "../api/findIntentsByContextResponse.schema.json#/$defs/FindIntentsByContextErrorResponsePayload" }, "meta": { "title": "FindIntentsByContext Response Metadata", diff --git a/schemas/bridging/findIntentsByContextAgentRequest.schema.json b/schemas/bridging/findIntentsByContextAgentRequest.schema.json index b88bc215c..5dacbb41f 100644 --- a/schemas/bridging/findIntentsByContextAgentRequest.schema.json +++ b/schemas/bridging/findIntentsByContextAgentRequest.schema.json @@ -18,23 +18,10 @@ "description": "A request for details of intents and apps available to resolve them for a particular context.", "properties": { "type": { - "title": "FindIntentsByContext Request Message Type", - "const": "findIntentsByContextRequest" + "$ref": "../api/findIntentsByContextRequest.schema.json#/$defs/FindIntentsByContextRequestType" }, "payload": { - "title": "FindIntentsByContext Request Payload", - "type": "object", - "properties": { - "context": { - "$ref": "../context/context.schema.json" - }, - "resultType": { - "title": "Result type argument", - "type": "string" - } - }, - "required": ["context"], - "additionalProperties": false + "$ref": "../api/findIntentsByContextRequest.schema.json#/$defs/FindIntentsByContextRequestPayload" }, "meta": { "title": "FindIntentsByContext Request Metadata", diff --git a/schemas/bridging/findIntentsByContextAgentResponse.schema.json b/schemas/bridging/findIntentsByContextAgentResponse.schema.json index 7f909d419..99f5f04a1 100644 --- a/schemas/bridging/findIntentsByContextAgentResponse.schema.json +++ b/schemas/bridging/findIntentsByContextAgentResponse.schema.json @@ -18,23 +18,10 @@ "description": "A response to a findIntentsByContext request.", "properties": { "type": { - "title": "FindIntentsByContext Response Message Type", - "const": "findIntentsByContextResponse" + "$ref": "../api/findIntentsByContextResponse.schema.json#/$defs/FindIntentsByContextResponseType" }, "payload": { - "title": "FindIntentsByContext Response Payload", - "type": "object", - "properties": { - "appIntents": { - "type": "array", - "items": { - "$ref": "../api/api.schema.json#/definitions/AppIntent" - }, - "additionalProperties": false - } - }, - "additionalProperties": false, - "required": ["appIntents"] + "$ref": "../api/findIntentsByContextResponse.schema.json#/$defs/FindIntentsByContextSuccessResponsePayload" }, "meta": { "title": "FindIntentsByContext Response Metadata", diff --git a/schemas/bridging/getAppMetadataAgentErrorResponse.schema.json b/schemas/bridging/getAppMetadataAgentErrorResponse.schema.json index 57cad8b2c..03cb59ab0 100644 --- a/schemas/bridging/getAppMetadataAgentErrorResponse.schema.json +++ b/schemas/bridging/getAppMetadataAgentErrorResponse.schema.json @@ -18,23 +18,10 @@ "description": "A response to a getAppMetadata request that contains an error.", "properties": { "type": { - "title": "GetAppMetadata Response Message Type", - "const": "getAppMetadataResponse" + "$ref": "../api/getAppMetadataResponse.schema.json#/$defs/GetAppMetadataResponseType" }, "payload": { - "title": "GetAppMetadata Error Response Payload", - "type": "object", - "properties": { - "error": { - "title": "GetAppMetadata Error Message", - "oneOf": [ - { "$ref": "../api/api.schema.json#/definitions/ResolveError" }, - { "$ref": "../api/api.schema.json#/definitions/BridgingError" } - ] - } - }, - "required": ["error"], - "additionalProperties": false + "$ref": "../api/getAppMetadataResponse.schema.json#/$defs/GetAppMetadataErrorResponsePayload" }, "meta": { "title": "GetAppMetadata Response Metadata", diff --git a/schemas/bridging/getAppMetadataAgentRequest.schema.json b/schemas/bridging/getAppMetadataAgentRequest.schema.json index 6a6fd59ec..76f2476b7 100644 --- a/schemas/bridging/getAppMetadataAgentRequest.schema.json +++ b/schemas/bridging/getAppMetadataAgentRequest.schema.json @@ -18,19 +18,22 @@ "description": "A request for metadata about an app", "properties": { "type": { - "title": "GetAppMetadata Request Message Type", - "const": "getAppMetadataRequest" + "$ref": "../api/getAppMetadataRequest.schema.json#/$defs/GetAppMetadataRequestType" }, "payload": { - "title": "GetAppMetadata Request Payload", "type": "object", - "properties": { - "app": { - "$ref": "common.schema.json#/$defs/AppDestination" - } - }, - "required": ["app"], - "additionalProperties": false + "allOf": [{ + "properties": { + "app": { + "$ref": "common.schema.json#/$defs/AppDestination" + } + }, + "required": [ + "app" + ] + },{ + "$ref": "../api/getAppMetadataRequest.schema.json#/$defs/GetAppMetadataRequestPayload" + }] }, "meta": { "title" : "GetAppMetadata Request Metadata", diff --git a/schemas/bridging/getAppMetadataAgentResponse.schema.json b/schemas/bridging/getAppMetadataAgentResponse.schema.json index 65aad070c..549b0e97d 100644 --- a/schemas/bridging/getAppMetadataAgentResponse.schema.json +++ b/schemas/bridging/getAppMetadataAgentResponse.schema.json @@ -18,19 +18,10 @@ "description": "A response to a getAppMetadata request.", "properties": { "type": { - "title": "GetAppMetadata Response Message Type", - "const": "getAppMetadataResponse" + "$ref": "../api/getAppMetadataResponse.schema.json#/$defs/GetAppMetadataResponseType" }, "payload": { - "title": "GetAppMetadata Response Payload", - "type": "object", - "properties": { - "appMetadata": { - "$ref": "../api/api.schema.json#/definitions/AppMetadata" - } - }, - "required": ["appMetadata"], - "additionalProperties": false + "$ref": "../api/getAppMetadataResponse.schema.json#/$defs/GetAppMetadataSuccessResponsePayload" }, "meta": { "title": "GetAppMetadata Response Metadata", diff --git a/schemas/bridging/openAgentErrorResponse.schema.json b/schemas/bridging/openAgentErrorResponse.schema.json index 6041edcb5..5be7ccf24 100644 --- a/schemas/bridging/openAgentErrorResponse.schema.json +++ b/schemas/bridging/openAgentErrorResponse.schema.json @@ -18,23 +18,10 @@ "description": "A response to an open request that contains an error", "properties": { "type": { - "title": "Open Response Message Type", - "const": "openResponse" + "$ref": "../api/openResponse.schema.json#/$defs/OpenResponseType" }, "payload": { - "title": "Open Error Response Payload", - "type": "object", - "properties": { - "error": { - "title": "Open Error Message", - "oneOf": [ - { "$ref": "../api/api.schema.json#/definitions/OpenError" }, - { "$ref": "../api/api.schema.json#/definitions/BridgingError" } - ] - } - }, - "required": ["error"], - "additionalProperties": false + "$ref": "../api/openResponse.schema.json#/$defs/OpenErrorResponsePayload" }, "meta": { "title": "Open Response Metadata", diff --git a/schemas/bridging/openAgentRequest.schema.json b/schemas/bridging/openAgentRequest.schema.json index 3b20d30e6..ef308dfce 100644 --- a/schemas/bridging/openAgentRequest.schema.json +++ b/schemas/bridging/openAgentRequest.schema.json @@ -18,8 +18,7 @@ "description": "A request to open an application", "properties": { "type": { - "title": "Open Request Message Type", - "const": "openRequest" + "$ref": "../api/openRequest.schema.json#/$defs/OpenRequestType" }, "payload": { "title": "Open Request Payload", diff --git a/schemas/bridging/openAgentResponse.schema.json b/schemas/bridging/openAgentResponse.schema.json index 5c714f260..c7116178d 100644 --- a/schemas/bridging/openAgentResponse.schema.json +++ b/schemas/bridging/openAgentResponse.schema.json @@ -18,19 +18,10 @@ "description": "A response to an open request", "properties": { "type": { - "title": "Open Response Message Type", - "const": "openResponse" + "$ref": "../api/openResponse.schema.json#/$defs/OpenResponseType" }, "payload": { - "title": "Open Response Payload", - "type": "object", - "properties": { - "appIdentifier": { - "$ref": "../api/api.schema.json#/definitions/AppIdentifier" - } - }, - "required": ["appIdentifier"], - "additionalProperties": false + "$ref": "../api/openResponse.schema.json#/$defs/OpenSuccessResponsePayload" }, "meta": { "title": "Open Response Metadata", diff --git a/schemas/bridging/privateChannelEventListenerAddedAgentRequest.schema.json b/schemas/bridging/privateChannelEventListenerAddedAgentRequest.schema.json index b7fa3a7e8..396a2a316 100644 --- a/schemas/bridging/privateChannelEventListenerAddedAgentRequest.schema.json +++ b/schemas/bridging/privateChannelEventListenerAddedAgentRequest.schema.json @@ -31,7 +31,7 @@ "description": "The id of the PrivateChannel that the event listener was added to." }, "listenerType": { - "$ref": "common.schema.json#/$defs/PrivateChannelEventListenerTypes" + "$ref": "../api/common.schema.json#/$defs/PrivateChannelEventListenerTypes" } }, "additionalProperties": false, diff --git a/schemas/bridging/privateChannelEventListenerRemovedAgentRequest.schema.json b/schemas/bridging/privateChannelEventListenerRemovedAgentRequest.schema.json index 1f0394a25..2e1ce39ca 100644 --- a/schemas/bridging/privateChannelEventListenerRemovedAgentRequest.schema.json +++ b/schemas/bridging/privateChannelEventListenerRemovedAgentRequest.schema.json @@ -31,7 +31,7 @@ "description": "The id of the PrivateChannel that the event listener was removed from." }, "listenerType": { - "$ref": "common.schema.json#/$defs/PrivateChannelEventListenerTypes" + "$ref": "../api/common.schema.json#/$defs/PrivateChannelEventListenerTypes" } }, "additionalProperties": false, diff --git a/schemas/bridging/raiseIntentAgentErrorResponse.schema.json b/schemas/bridging/raiseIntentAgentErrorResponse.schema.json index c7dd9dcfb..9dea12a59 100644 --- a/schemas/bridging/raiseIntentAgentErrorResponse.schema.json +++ b/schemas/bridging/raiseIntentAgentErrorResponse.schema.json @@ -18,23 +18,10 @@ "description": "A response to a request to raise an intent that contains an error.", "properties": { "type": { - "title": "RaiseIntent Response Message type", - "const": "raiseIntentResponse" + "$ref": "../api/raiseIntentResponse.schema.json#/$defs/RaiseIntentResponseType" }, "payload": { - "title": "RaiseIntent Error Response Payload", - "type": "object", - "properties": { - "error": { - "title": "RaiseIntent Error Message", - "oneOf": [ - { "$ref": "../api/api.schema.json#/definitions/ResolveError" }, - { "$ref": "../api/api.schema.json#/definitions/BridgingError" } - ] - } - }, - "required": ["error"], - "additionalProperties": false + "$ref": "../api/raiseIntentResponse.schema.json#/$defs/RaiseIntentErrorResponsePayload" }, "meta": { "title": "RaiseIntent Response Metadata", diff --git a/schemas/bridging/raiseIntentAgentRequest.schema.json b/schemas/bridging/raiseIntentAgentRequest.schema.json index 4a9921859..a6ceca451 100644 --- a/schemas/bridging/raiseIntentAgentRequest.schema.json +++ b/schemas/bridging/raiseIntentAgentRequest.schema.json @@ -18,8 +18,7 @@ "description": "A request to raise an intent.", "properties": { "type": { - "title": "RaiseIntent Request Message type", - "const": "raiseIntentRequest" + "$ref": "../api/raiseIntentRequest.schema.json#/$defs/RaiseIntentRequestType" }, "payload": { "title": "RaiseIntent Request Payload", diff --git a/schemas/bridging/raiseIntentAgentResponse.schema.json b/schemas/bridging/raiseIntentAgentResponse.schema.json index 30c0ec397..8ad8c8b23 100644 --- a/schemas/bridging/raiseIntentAgentResponse.schema.json +++ b/schemas/bridging/raiseIntentAgentResponse.schema.json @@ -18,19 +18,10 @@ "description": "A response to a request to raise an intent.", "properties": { "type": { - "title": "RaiseIntent Response Message type", - "const": "raiseIntentResponse" + "$ref": "../api/raiseIntentResponse.schema.json#/$defs/RaiseIntentResponseType" }, "payload": { - "title": "RaiseIntent Response Payload", - "type": "object", - "properties": { - "intentResolution": { - "$ref": "../api/api.schema.json#/definitions/IntentResolution" - } - }, - "required": ["intentResolution"], - "additionalProperties": false + "$ref": "../api/raiseIntentResponse.schema.json#/$defs/RaiseIntentSuccessResponsePayload" }, "meta": { "title": "RaiseIntent Response Metadata", diff --git a/schemas/bridging/raiseIntentResultAgentResponse.schema.json b/schemas/bridging/raiseIntentResultAgentResponse.schema.json index e5b8b36c7..f97331b2e 100644 --- a/schemas/bridging/raiseIntentResultAgentResponse.schema.json +++ b/schemas/bridging/raiseIntentResultAgentResponse.schema.json @@ -18,49 +18,10 @@ "description": "A secondary response to a request to raise an intent used to deliver the intent result", "properties": { "type": { - "title": "RaiseIntent Result Response Message type", - "const": "raiseIntentResultResponse" + "$ref": "../api/raiseIntentResultResponse.schema.json#/$defs/RaiseIntentResultResponseType" }, "payload": { - "title": "RaiseIntent Result Response Payload", - "type": "object", - "properties": { - "intentResult": { - "title": "IntentResult", - "anyOf": [ - { - "type": "object", - "title": "IntentResult Context", - "properties": { - "context": { - "$ref": "../context/context.schema.json" - } - }, - "required": ["context"], - "additionalProperties": false - }, - { - "type": "object", - "title": "IntentResult Channel", - "properties": { - "channel": { - "$ref": "../api/api.schema.json#/definitions/Channel" - } - }, - "required": ["channel"], - "additionalProperties": false - }, - { - "type": "object", - "title": "IntentResult Void", - "properties": {}, - "additionalProperties": false - } - ] - } - }, - "required": ["intentResult"], - "additionalProperties": false + "$ref": "../api/raiseIntentResultResponse.schema.json#/$defs/RaiseIntentResultSuccessResponsePayload" }, "meta": { "title": "RaiseIntent Result Response Metadata", @@ -70,4 +31,4 @@ "additionalProperties": false } } -} +} \ No newline at end of file diff --git a/src/api/BrowserTypes.ts b/src/api/BrowserTypes.ts new file mode 100644 index 000000000..36c6ff536 --- /dev/null +++ b/src/api/BrowserTypes.ts @@ -0,0 +1,5863 @@ +// To parse this data: +// +// import { Convert, AddContextListenerRequest, AddContextListenerResponse, AddEventListenerRequest, AddEventListenerResponse, AddIntentListenerRequest, AddIntentListenerResponse, AgentEventMessage, AgentResponseMessage, AppRequestMessage, BroadcastEvent, BroadcastRequest, BroadcastResponse, ChannelChangedEvent, ContextListenerUnsubscribeRequest, ContextListenerUnsubscribeResponse, CreatePrivateChannelRequest, CreatePrivateChannelResponse, EventListenerUnsubscribeRequest, EventListenerUnsubscribeResponse, Fdc3UserInterfaceChannels, Fdc3UserInterfaceChannelSelected, Fdc3UserInterfaceDrag, Fdc3UserInterfaceHandshake, Fdc3UserInterfaceHello, Fdc3UserInterfaceMessage, Fdc3UserInterfaceResolve, Fdc3UserInterfaceResolveAction, Fdc3UserInterfaceRestyle, FindInstancesRequest, FindInstancesResponse, FindIntentRequest, FindIntentResponse, FindIntentsByContextRequest, FindIntentsByContextResponse, GetAppMetadataRequest, GetAppMetadataResponse, GetCurrentChannelRequest, GetCurrentChannelResponse, GetCurrentContextRequest, GetCurrentContextResponse, GetInfoRequest, GetInfoResponse, GetOrCreateChannelRequest, GetOrCreateChannelResponse, GetUserChannelsRequest, GetUserChannelsResponse, HeartbeatAcknowledgementRequest, HeartbeatEvent, IntentEvent, IntentListenerUnsubscribeRequest, IntentListenerUnsubscribeResponse, IntentResultRequest, IntentResultResponse, JoinUserChannelRequest, JoinUserChannelResponse, LeaveCurrentChannelRequest, LeaveCurrentChannelResponse, OpenRequest, OpenResponse, PrivateChannelAddEventListenerRequest, PrivateChannelAddEventListenerResponse, PrivateChannelDisconnectRequest, PrivateChannelDisconnectResponse, PrivateChannelOnAddContextListenerEvent, PrivateChannelOnDisconnectEvent, PrivateChannelOnUnsubscribeEvent, PrivateChannelUnsubscribeEventListenerRequest, PrivateChannelUnsubscribeEventListenerResponse, RaiseIntentForContextRequest, RaiseIntentForContextResponse, RaiseIntentRequest, RaiseIntentResponse, RaiseIntentResultResponse, WebConnectionProtocol1Hello, WebConnectionProtocol2LoadURL, WebConnectionProtocol3Handshake, WebConnectionProtocol4ValidateAppIdentity, WebConnectionProtocol5ValidateAppIdentityFailedResponse, WebConnectionProtocol5ValidateAppIdentitySuccessResponse, WebConnectionProtocol6Goodbye, WebConnectionProtocolMessage } from "./file"; +// +// const addContextListenerRequest = Convert.toAddContextListenerRequest(json); +// const addContextListenerResponse = Convert.toAddContextListenerResponse(json); +// const addEventListenerRequest = Convert.toAddEventListenerRequest(json); +// const addEventListenerResponse = Convert.toAddEventListenerResponse(json); +// const addIntentListenerRequest = Convert.toAddIntentListenerRequest(json); +// const addIntentListenerResponse = Convert.toAddIntentListenerResponse(json); +// const agentEventMessage = Convert.toAgentEventMessage(json); +// const agentResponseMessage = Convert.toAgentResponseMessage(json); +// const appRequestMessage = Convert.toAppRequestMessage(json); +// const broadcastEvent = Convert.toBroadcastEvent(json); +// const broadcastRequest = Convert.toBroadcastRequest(json); +// const broadcastResponse = Convert.toBroadcastResponse(json); +// const channelChangedEvent = Convert.toChannelChangedEvent(json); +// const contextListenerUnsubscribeRequest = Convert.toContextListenerUnsubscribeRequest(json); +// const contextListenerUnsubscribeResponse = Convert.toContextListenerUnsubscribeResponse(json); +// const createPrivateChannelRequest = Convert.toCreatePrivateChannelRequest(json); +// const createPrivateChannelResponse = Convert.toCreatePrivateChannelResponse(json); +// const eventListenerUnsubscribeRequest = Convert.toEventListenerUnsubscribeRequest(json); +// const eventListenerUnsubscribeResponse = Convert.toEventListenerUnsubscribeResponse(json); +// const fdc3UserInterfaceChannels = Convert.toFdc3UserInterfaceChannels(json); +// const fdc3UserInterfaceChannelSelected = Convert.toFdc3UserInterfaceChannelSelected(json); +// const fdc3UserInterfaceDrag = Convert.toFdc3UserInterfaceDrag(json); +// const fdc3UserInterfaceHandshake = Convert.toFdc3UserInterfaceHandshake(json); +// const fdc3UserInterfaceHello = Convert.toFdc3UserInterfaceHello(json); +// const fdc3UserInterfaceMessage = Convert.toFdc3UserInterfaceMessage(json); +// const fdc3UserInterfaceResolve = Convert.toFdc3UserInterfaceResolve(json); +// const fdc3UserInterfaceResolveAction = Convert.toFdc3UserInterfaceResolveAction(json); +// const fdc3UserInterfaceRestyle = Convert.toFdc3UserInterfaceRestyle(json); +// const findInstancesRequest = Convert.toFindInstancesRequest(json); +// const findInstancesResponse = Convert.toFindInstancesResponse(json); +// const findIntentRequest = Convert.toFindIntentRequest(json); +// const findIntentResponse = Convert.toFindIntentResponse(json); +// const findIntentsByContextRequest = Convert.toFindIntentsByContextRequest(json); +// const findIntentsByContextResponse = Convert.toFindIntentsByContextResponse(json); +// const getAppMetadataRequest = Convert.toGetAppMetadataRequest(json); +// const getAppMetadataResponse = Convert.toGetAppMetadataResponse(json); +// const getCurrentChannelRequest = Convert.toGetCurrentChannelRequest(json); +// const getCurrentChannelResponse = Convert.toGetCurrentChannelResponse(json); +// const getCurrentContextRequest = Convert.toGetCurrentContextRequest(json); +// const getCurrentContextResponse = Convert.toGetCurrentContextResponse(json); +// const getInfoRequest = Convert.toGetInfoRequest(json); +// const getInfoResponse = Convert.toGetInfoResponse(json); +// const getOrCreateChannelRequest = Convert.toGetOrCreateChannelRequest(json); +// const getOrCreateChannelResponse = Convert.toGetOrCreateChannelResponse(json); +// const getUserChannelsRequest = Convert.toGetUserChannelsRequest(json); +// const getUserChannelsResponse = Convert.toGetUserChannelsResponse(json); +// const heartbeatAcknowledgementRequest = Convert.toHeartbeatAcknowledgementRequest(json); +// const heartbeatEvent = Convert.toHeartbeatEvent(json); +// const intentEvent = Convert.toIntentEvent(json); +// const intentListenerUnsubscribeRequest = Convert.toIntentListenerUnsubscribeRequest(json); +// const intentListenerUnsubscribeResponse = Convert.toIntentListenerUnsubscribeResponse(json); +// const intentResultRequest = Convert.toIntentResultRequest(json); +// const intentResultResponse = Convert.toIntentResultResponse(json); +// const joinUserChannelRequest = Convert.toJoinUserChannelRequest(json); +// const joinUserChannelResponse = Convert.toJoinUserChannelResponse(json); +// const leaveCurrentChannelRequest = Convert.toLeaveCurrentChannelRequest(json); +// const leaveCurrentChannelResponse = Convert.toLeaveCurrentChannelResponse(json); +// const openRequest = Convert.toOpenRequest(json); +// const openResponse = Convert.toOpenResponse(json); +// const privateChannelAddEventListenerRequest = Convert.toPrivateChannelAddEventListenerRequest(json); +// const privateChannelAddEventListenerResponse = Convert.toPrivateChannelAddEventListenerResponse(json); +// const privateChannelDisconnectRequest = Convert.toPrivateChannelDisconnectRequest(json); +// const privateChannelDisconnectResponse = Convert.toPrivateChannelDisconnectResponse(json); +// const privateChannelOnAddContextListenerEvent = Convert.toPrivateChannelOnAddContextListenerEvent(json); +// const privateChannelOnDisconnectEvent = Convert.toPrivateChannelOnDisconnectEvent(json); +// const privateChannelOnUnsubscribeEvent = Convert.toPrivateChannelOnUnsubscribeEvent(json); +// const privateChannelUnsubscribeEventListenerRequest = Convert.toPrivateChannelUnsubscribeEventListenerRequest(json); +// const privateChannelUnsubscribeEventListenerResponse = Convert.toPrivateChannelUnsubscribeEventListenerResponse(json); +// const raiseIntentForContextRequest = Convert.toRaiseIntentForContextRequest(json); +// const raiseIntentForContextResponse = Convert.toRaiseIntentForContextResponse(json); +// const raiseIntentRequest = Convert.toRaiseIntentRequest(json); +// const raiseIntentResponse = Convert.toRaiseIntentResponse(json); +// const raiseIntentResultResponse = Convert.toRaiseIntentResultResponse(json); +// const webConnectionProtocol1Hello = Convert.toWebConnectionProtocol1Hello(json); +// const webConnectionProtocol2LoadURL = Convert.toWebConnectionProtocol2LoadURL(json); +// const webConnectionProtocol3Handshake = Convert.toWebConnectionProtocol3Handshake(json); +// const webConnectionProtocol4ValidateAppIdentity = Convert.toWebConnectionProtocol4ValidateAppIdentity(json); +// const webConnectionProtocol5ValidateAppIdentityFailedResponse = Convert.toWebConnectionProtocol5ValidateAppIdentityFailedResponse(json); +// const webConnectionProtocol5ValidateAppIdentitySuccessResponse = Convert.toWebConnectionProtocol5ValidateAppIdentitySuccessResponse(json); +// const webConnectionProtocol6Goodbye = Convert.toWebConnectionProtocol6Goodbye(json); +// const webConnectionProtocolMessage = Convert.toWebConnectionProtocolMessage(json); +// +// These functions will throw an error if the JSON doesn't +// match the expected interface, even if the JSON is valid. + +/** + * A request to add a context listener to a specified Channel OR to the current user + * channel. Where the listener is added to the current user channel (channelId == null), and + * this app has already been added to a user channel, client code should make a subsequent + * request to get the current context of that channel for this listener and then call its + * handler with it. + * + * A request message from an FDC3-enabled app to a Desktop Agent. + */ +export interface AddContextListenerRequest { + /** + * Metadata for a request message sent by an FDC3-enabled app to a Desktop Agent. + */ + meta: AddContextListenerRequestMeta; + /** + * The message payload typically contains the arguments to FDC3 API functions. + */ + payload: AddContextListenerRequestPayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + type: "addContextListenerRequest"; +} + +/** + * Metadata for a request message sent by an FDC3-enabled app to a Desktop Agent. + */ +export interface AddContextListenerRequestMeta { + requestUuid: string; + /** + * Field that represents the source application that a request or response was received + * from. Please note that this may be set by an app or Desktop Agent proxy for debugging + * purposes but a Desktop Agent should make its own determination of the source of a message + * to avoid spoofing. + */ + source?: AppIdentifier; + timestamp: Date; +} + +/** + * Field that represents the source application that a request or response was received + * from. Please note that this may be set by an app or Desktop Agent proxy for debugging + * purposes but a Desktop Agent should make its own determination of the source of a message + * to avoid spoofing. + * + * Identifies an application, or instance of an application, and is used to target FDC3 API + * calls, such as `fdc3.open` or `fdc3.raiseIntent` at specific applications or application + * instances. + * + * Will always include at least an `appId` field, which uniquely identifies a specific app. + * + * If the `instanceId` field is set then the `AppMetadata` object represents a specific + * instance of the application that may be addressed using that Id. + * + * Field that represents the source application that the request being responded to was + * received from, for debugging purposes. + * + * Details of the application instance that broadcast the context + * + * The App resolution option chosen + * + * Details of the application instance that raised the intent + * + * Identifier for the app instance that was selected (or started) to resolve the intent. + * `source.instanceId` MUST be set, indicating the specific app instance that + * received the intent. + */ +export interface AppIdentifier { + /** + * The unique application identifier located within a specific application directory + * instance. An example of an appId might be 'app@sub.root' + */ + appId: string; + /** + * The Desktop Agent that the app is available on. Used in Desktop Agent Bridging to + * identify the Desktop Agent to target. + */ + desktopAgent?: string; + /** + * An optional instance identifier, indicating that this object represents a specific + * instance of the application described. + */ + instanceId?: string; + [property: string]: any; +} + +/** + * The message payload typically contains the arguments to FDC3 API functions. + */ +export interface AddContextListenerRequestPayload { + /** + * The id of the channel to add the listener to or `null` indicating that it should listen + * to the current user channel (at the time of broadcast). + */ + channelId: null | string; + /** + * The type of context to listen for OR `null` indicating that it should listen to all + * context types. + */ + contextType: null | string; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + +/** + * A response to a addContextListener request. Where the listener was added to the current + * user channel (channelId == null), and this app has already been added to a user channel, + * client code should make a subsequent request to get the current context of that channel + * for this listener and then call its handler with it. + * + * A message from a Desktop Agent to an FDC3-enabled app responding to an API call. If the + * payload contains an `error` property, the request was unsuccessful. + */ +export interface AddContextListenerResponse { + /** + * Metadata for messages sent by a Desktop Agent to an App in response to an API call + */ + meta: AddContextListenerResponseMeta; + /** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ + payload: AddContextListenerResponsePayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + type: "addContextListenerResponse"; +} + +/** + * Metadata for messages sent by a Desktop Agent to an App in response to an API call + */ +export interface AddContextListenerResponseMeta { + requestUuid: string; + responseUuid: string; + /** + * Field that represents the source application that the request being responded to was + * received from, for debugging purposes. + */ + source?: AppIdentifier; + timestamp: Date; +} + +/** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ +export interface AddContextListenerResponsePayload { + error?: PurpleError; + listenerUUID?: string; +} + +/** + * Constants representing the errors that can be encountered when calling the `open` method + * on the DesktopAgent object (`fdc3`). + * + * Constants representing the errors that can be encountered when calling the `findIntent`, + * `findIntentsByContext`, `raiseIntent` or `raiseIntentForContext` methods on the + * DesktopAgent (`fdc3`). + */ +export type PurpleError = "AccessDenied" | "CreationFailed" | "MalformedContext" | "NoChannelFound"; + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + +/** + * A request to add an event listener for a specified event type to the DesktopAgent. + * + * A request message from an FDC3-enabled app to a Desktop Agent. + */ +export interface AddEventListenerRequest { + /** + * Metadata for a request message sent by an FDC3-enabled app to a Desktop Agent. + */ + meta: AddContextListenerRequestMeta; + /** + * The message payload typically contains the arguments to FDC3 API functions. + */ + payload: AddEventListenerRequestPayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + type: "addEventListenerRequest"; +} + +/** + * The message payload typically contains the arguments to FDC3 API functions. + */ +export interface AddEventListenerRequestPayload { + /** + * The type of the event to be listened to or `null` to listen to all event types. + */ + type: "USER_CHANNEL_CHANGED" | null; +} + +/** + * The type of a (non-context and non-intent) event that may be received via the FDC3 API's + * addEventListener function. + */ + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + +/** + * A response to an addEventListener request. + * + * A message from a Desktop Agent to an FDC3-enabled app responding to an API call. If the + * payload contains an `error` property, the request was unsuccessful. + */ +export interface AddEventListenerResponse { + /** + * Metadata for messages sent by a Desktop Agent to an App in response to an API call + */ + meta: AddContextListenerResponseMeta; + /** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ + payload: AddEventListenerResponsePayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + type: "addEventListenerResponse"; +} + +/** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ +export interface AddEventListenerResponsePayload { + error?: ResponsePayloadError; + listenerUUID?: string; +} + +/** + * Constants representing the errors that can be encountered when calling the `open` method + * on the DesktopAgent object (`fdc3`). + * + * Constants representing the errors that can be encountered when calling the `findIntent`, + * `findIntentsByContext`, `raiseIntent` or `raiseIntentForContext` methods on the + * DesktopAgent (`fdc3`). + */ +export type ResponsePayloadError = "AccessDenied" | "CreationFailed" | "MalformedContext" | "NoChannelFound" | "AppNotFound" | "AppTimeout" | "DesktopAgentNotFound" | "ErrorOnLaunch" | "ResolverUnavailable" | "IntentDeliveryFailed" | "NoAppsFound" | "ResolverTimeout" | "TargetAppUnavailable" | "TargetInstanceUnavailable" | "UserCancelledResolution" | "IntentHandlerRejected" | "NoResultReturned" | "AgentDisconnected" | "NotConnectedToBridge" | "ResponseToBridgeTimedOut" | "MalformedMessage"; + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + +/** + * A request to add an Intent listener for a specified intent type. + * + * A request message from an FDC3-enabled app to a Desktop Agent. + */ +export interface AddIntentListenerRequest { + /** + * Metadata for a request message sent by an FDC3-enabled app to a Desktop Agent. + */ + meta: AddContextListenerRequestMeta; + /** + * The message payload typically contains the arguments to FDC3 API functions. + */ + payload: AddIntentListenerRequestPayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + type: "addIntentListenerRequest"; +} + +/** + * The message payload typically contains the arguments to FDC3 API functions. + */ +export interface AddIntentListenerRequestPayload { + /** + * The name of the intent to listen for. + */ + intent: string; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + +/** + * A response to a addIntentListener request. + * + * A message from a Desktop Agent to an FDC3-enabled app responding to an API call. If the + * payload contains an `error` property, the request was unsuccessful. + */ +export interface AddIntentListenerResponse { + /** + * Metadata for messages sent by a Desktop Agent to an App in response to an API call + */ + meta: AddContextListenerResponseMeta; + /** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ + payload: AddIntentListenerResponsePayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + type: "addIntentListenerResponse"; +} + +/** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ +export interface AddIntentListenerResponsePayload { + error?: FluffyError; + listenerUUID?: string; + [property: string]: any; +} + +/** + * Constants representing the errors that can be encountered when calling the `open` method + * on the DesktopAgent object (`fdc3`). + * + * Constants representing the errors that can be encountered when calling the `findIntent`, + * `findIntentsByContext`, `raiseIntent` or `raiseIntentForContext` methods on the + * DesktopAgent (`fdc3`). + */ +export type FluffyError = "MalformedContext" | "DesktopAgentNotFound" | "ResolverUnavailable" | "IntentDeliveryFailed" | "NoAppsFound" | "ResolverTimeout" | "TargetAppUnavailable" | "TargetInstanceUnavailable" | "UserCancelledResolution"; + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + +/** + * A message from a Desktop Agent to an FDC3-enabled app representing an event. + */ +export interface AgentEventMessage { + /** + * Metadata for messages sent by a Desktop Agent to an App notifying it of an event. + */ + meta: AgentEventMessageMeta; + /** + * The message payload contains details of the event that the app is being notified about. + */ + payload: { [key: string]: any }; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + type: EventMessageType; +} + +/** + * Metadata for messages sent by a Desktop Agent to an App notifying it of an event. + */ +export interface AgentEventMessageMeta { + eventUuid: string; + timestamp: Date; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ +export type EventMessageType = "addEventListenerEvent" | "broadcastEvent" | "channelChangedEvent" | "heartbeatEvent" | "intentEvent" | "privateChannelOnAddContextListenerEvent" | "privateChannelOnDisconnectEvent" | "privateChannelOnUnsubscribeEvent"; + +/** + * A message from a Desktop Agent to an FDC3-enabled app responding to an API call. If the + * payload contains an `error` property, the request was unsuccessful. + */ +export interface AgentResponseMessage { + /** + * Metadata for messages sent by a Desktop Agent to an App in response to an API call + */ + meta: AgentResponseMessageMeta; + /** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ + payload: AgentResponseMessageResponsePayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + type: ResponseMessageType; +} + +/** + * Metadata for messages sent by a Desktop Agent to an App in response to an API call + */ +export interface AgentResponseMessageMeta { + requestUuid: string; + responseUuid: string; + /** + * Field that represents the source application that the request being responded to was + * received from, for debugging purposes. + */ + source?: AppIdentifier; + timestamp: Date; +} + +/** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ +export interface AgentResponseMessageResponsePayload { + error?: ResponsePayloadError; + [property: string]: any; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ +export type ResponseMessageType = "addContextListenerResponse" | "addEventListenerResponse" | "addIntentListenerResponse" | "broadcastResponse" | "contextListenerUnsubscribeResponse" | "createPrivateChannelResponse" | "eventListenerUnsubscribeResponse" | "findInstancesResponse" | "findIntentResponse" | "findIntentsByContextResponse" | "getAppMetadataResponse" | "getCurrentChannelResponse" | "getCurrentContextResponse" | "getInfoResponse" | "getOrCreateChannelResponse" | "getUserChannelsResponse" | "intentListenerUnsubscribeResponse" | "intentResultResponse" | "joinUserChannelResponse" | "leaveCurrentChannelResponse" | "openResponse" | "privateChannelAddEventListenerResponse" | "privateChannelDisconnectResponse" | "privateChannelUnsubscribeEventListenerResponse" | "raiseIntentForContextResponse" | "raiseIntentResponse" | "raiseIntentResultResponse"; + +/** + * A request message from an FDC3-enabled app to a Desktop Agent. + */ +export interface AppRequestMessage { + /** + * Metadata for a request message sent by an FDC3-enabled app to a Desktop Agent. + */ + meta: AppRequestMessageMeta; + /** + * The message payload typically contains the arguments to FDC3 API functions. + */ + payload: { [key: string]: any }; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + type: RequestMessageType; +} + +/** + * Metadata for a request message sent by an FDC3-enabled app to a Desktop Agent. + */ +export interface AppRequestMessageMeta { + requestUuid: string; + /** + * Field that represents the source application that a request or response was received + * from. Please note that this may be set by an app or Desktop Agent proxy for debugging + * purposes but a Desktop Agent should make its own determination of the source of a message + * to avoid spoofing. + */ + source?: AppIdentifier; + timestamp: Date; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ +export type RequestMessageType = "addContextListenerRequest" | "addEventListenerRequest" | "addIntentListenerRequest" | "broadcastRequest" | "contextListenerUnsubscribeRequest" | "createPrivateChannelRequest" | "eventListenerUnsubscribeRequest" | "findInstancesRequest" | "findIntentRequest" | "findIntentsByContextRequest" | "getAppMetadataRequest" | "getCurrentChannelRequest" | "getCurrentContextRequest" | "getInfoRequest" | "getOrCreateChannelRequest" | "getUserChannelsRequest" | "heartbeatAcknowledgementRequest" | "intentListenerUnsubscribeRequest" | "intentResultRequest" | "joinUserChannelRequest" | "leaveCurrentChannelRequest" | "openRequest" | "privateChannelAddEventListenerRequest" | "privateChannelDisconnectRequest" | "privateChannelUnsubscribeEventListenerRequest" | "raiseIntentForContextRequest" | "raiseIntentRequest"; + +/** + * An event message from the Desktop Agent to an app indicating that context has been + * broadcast on a channel it is listening to, or specifically to this app instance if it was + * launched via `fdc3.open` and context was passed. + * + * A message from a Desktop Agent to an FDC3-enabled app representing an event. + */ +export interface BroadcastEvent { + /** + * Metadata for messages sent by a Desktop Agent to an App notifying it of an event. + */ + meta: BroadcastEventMeta; + /** + * The message payload contains details of the event that the app is being notified about. + */ + payload: BroadcastEventPayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + type: "broadcastEvent"; +} + +/** + * Metadata for messages sent by a Desktop Agent to an App notifying it of an event. + */ +export interface BroadcastEventMeta { + eventUuid: string; + timestamp: Date; +} + +/** + * The message payload contains details of the event that the app is being notified about. + */ +export interface BroadcastEventPayload { + /** + * The Id of the channel that the broadcast was sent on. May be `null` if the context is + * being broadcast due to a call `fdc3.open` that passed context. + */ + channelId: null | string; + /** + * The context object that was broadcast. + */ + context: Context; + /** + * Details of the application instance that broadcast the context + */ + originatingApp?: AppIdentifier; +} + +/** + * The context object that was broadcast. + * + * The context object that is to be broadcast. + * + * The context object passed with the raised intent. + * + * If a Context object is passed in, this object will be provided to the opened application + * via a contextListener. The Context argument is functionally equivalent to opening the + * target app with no context and broadcasting the context directly to it. + * + * The `fdc3.context` type defines the basic contract or "shape" for all data exchanged by + * FDC3 operations. As such, it is not really meant to be used on its own, but is imported + * by more specific type definitions (standardized or custom) to provide the structure and + * properties shared by all FDC3 context data types. + * + * The key element of FDC3 context types is their mandatory `type` property, which is used + * to identify what type of data the object represents, and what shape it has. + * + * The FDC3 context type, and all derived types, define the minimum set of fields a context + * data object of a particular type can be expected to have, but this can always be extended + * with custom fields as appropriate. + */ +export interface Context { + /** + * Context data objects may include a set of equivalent key-value pairs that can be used to + * help applications identify and look up the context type they receive in their own domain. + * The idea behind this design is that applications can provide as many equivalent + * identifiers to a target application as possible, e.g. an instrument may be represented by + * an ISIN, CUSIP or Bloomberg identifier. + * + * Identifiers do not make sense for all types of data, so the `id` property is therefore + * optional, but some derived types may choose to require at least one identifier. + * Identifier values SHOULD always be of type string. + */ + id?: { [key: string]: any }; + /** + * Context data objects may include a name property that can be used for more information, + * or display purposes. Some derived types may require the name object as mandatory, + * depending on use case. + */ + name?: string; + /** + * The type property is the only _required_ part of the FDC3 context data schema. The FDC3 + * [API](https://fdc3.finos.org/docs/api/spec) relies on the `type` property being present + * to route shared context data appropriately. + * + * FDC3 [Intents](https://fdc3.finos.org/docs/intents/spec) also register the context data + * types they support in an FDC3 [App + * Directory](https://fdc3.finos.org/docs/app-directory/overview), used for intent discovery + * and routing. + * + * Standardized FDC3 context types have well-known `type` properties prefixed with the + * `fdc3` namespace, e.g. `fdc3.instrument`. For non-standard types, e.g. those defined and + * used by a particular organization, the convention is to prefix them with an + * organization-specific namespace, e.g. `blackrock.fund`. + * + * See the [Context Data Specification](https://fdc3.finos.org/docs/context/spec) for more + * information about context data types. + */ + type: string; + [property: string]: any; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + +/** + * A request to broadcast context on a channel. + * + * A request message from an FDC3-enabled app to a Desktop Agent. + */ +export interface BroadcastRequest { + /** + * Metadata for a request message sent by an FDC3-enabled app to a Desktop Agent. + */ + meta: AddContextListenerRequestMeta; + /** + * The message payload typically contains the arguments to FDC3 API functions. + */ + payload: BroadcastRequestPayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + type: "broadcastRequest"; +} + +/** + * The message payload typically contains the arguments to FDC3 API functions. + */ +export interface BroadcastRequestPayload { + /** + * The Id of the Channel that the broadcast was sent on + */ + channelId: string; + /** + * The context object that is to be broadcast. + */ + context: Context; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + +/** + * A response to a request to broadcast context on a channel. + * + * A message from a Desktop Agent to an FDC3-enabled app responding to an API call. If the + * payload contains an `error` property, the request was unsuccessful. + */ +export interface BroadcastResponse { + /** + * Metadata for messages sent by a Desktop Agent to an App in response to an API call + */ + meta: AddContextListenerResponseMeta; + /** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ + payload: BroadcastResponseResponsePayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + type: "broadcastResponse"; +} + +/** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ +export interface BroadcastResponseResponsePayload { + error?: ResponsePayloadError; + [property: string]: any; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + +/** + * An event message from the Desktop Agent to an app indicating that its current user + * channel has changed. + * + * A message from a Desktop Agent to an FDC3-enabled app representing an event. + */ +export interface ChannelChangedEvent { + /** + * Metadata for messages sent by a Desktop Agent to an App notifying it of an event. + */ + meta: BroadcastEventMeta; + /** + * The message payload contains details of the event that the app is being notified about. + */ + payload: ChannelChangedEventPayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + type: "channelChangedEvent"; +} + +/** + * The message payload contains details of the event that the app is being notified about. + */ +export interface ChannelChangedEventPayload { + /** + * The Id of the channel that the app was added to or `null` if it was removed from a + * channel. + */ + newChannelId: null | string; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + +/** + * A request to unsubscribe a context listener. + * + * A request message from an FDC3-enabled app to a Desktop Agent. + */ +export interface ContextListenerUnsubscribeRequest { + /** + * Metadata for a request message sent by an FDC3-enabled app to a Desktop Agent. + */ + meta: AddContextListenerRequestMeta; + /** + * The message payload typically contains the arguments to FDC3 API functions. + */ + payload: ContextListenerUnsubscribeRequestPayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + type: "contextListenerUnsubscribeRequest"; +} + +/** + * The message payload typically contains the arguments to FDC3 API functions. + */ +export interface ContextListenerUnsubscribeRequestPayload { + listenerUUID: string; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + +/** + * A response to a contextListenerUnsubscribe request. + * + * A message from a Desktop Agent to an FDC3-enabled app responding to an API call. If the + * payload contains an `error` property, the request was unsuccessful. + */ +export interface ContextListenerUnsubscribeResponse { + /** + * Metadata for messages sent by a Desktop Agent to an App in response to an API call + */ + meta: AddContextListenerResponseMeta; + /** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ + payload: BroadcastResponseResponsePayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + type: "contextListenerUnsubscribeResponse"; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + +/** + * Request to return a Channel with an auto-generated identity that is intended for private + * communication between applications. + * + * A request message from an FDC3-enabled app to a Desktop Agent. + */ +export interface CreatePrivateChannelRequest { + /** + * Metadata for a request message sent by an FDC3-enabled app to a Desktop Agent. + */ + meta: AddContextListenerRequestMeta; + /** + * The message payload typically contains the arguments to FDC3 API functions. + */ + payload: CreatePrivateChannelRequestPayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + type: "createPrivateChannelRequest"; +} + +/** + * The message payload typically contains the arguments to FDC3 API functions. + */ +export interface CreatePrivateChannelRequestPayload { +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + +/** + * A response to a createPrivateChannel request. + * + * A message from a Desktop Agent to an FDC3-enabled app responding to an API call. If the + * payload contains an `error` property, the request was unsuccessful. + */ +export interface CreatePrivateChannelResponse { + /** + * Metadata for messages sent by a Desktop Agent to an App in response to an API call + */ + meta: AddContextListenerResponseMeta; + /** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ + payload: CreatePrivateChannelResponsePayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + type: "createPrivateChannelResponse"; +} + +/** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ +export interface CreatePrivateChannelResponsePayload { + error?: PurpleError; + privateChannel?: Channel; +} + +/** + * Represents a context channel that applications can use to send and receive + * context data. + * + * Please note that There are differences in behavior when you interact with a + * User channel via the `DesktopAgent` interface and the `Channel` interface. + * Specifically, when 'joining' a User channel or adding a context listener + * when already joined to a channel via the `DesktopAgent` interface, existing + * context (matching the type of the context listener) on the channel is + * received by the context listener immediately. Whereas, when a context + * listener is added via the Channel interface, context is not received + * automatically, but may be retrieved manually via the `getCurrentContext()` + * function. + */ +export interface Channel { + /** + * Channels may be visualized and selectable by users. DisplayMetadata may be used to + * provide hints on how to see them. + * For App channels, displayMetadata would typically not be present. + */ + displayMetadata?: DisplayMetadata; + /** + * Constant that uniquely identifies this channel. + */ + id: string; + /** + * Uniquely defines each channel type. + * Can be "user", "app" or "private". + */ + type: Type; +} + +/** + * Channels may be visualized and selectable by users. DisplayMetadata may be used to + * provide hints on how to see them. + * For App channels, displayMetadata would typically not be present. + * + * A system channel will be global enough to have a presence across many apps. This gives us + * some hints + * to render them in a standard way. It is assumed it may have other properties too, but if + * it has these, + * this is their meaning. + */ +export interface DisplayMetadata { + /** + * The color that should be associated within this channel when displaying this channel in a + * UI, e.g: `0xFF0000`. + */ + color?: string; + /** + * A URL of an image that can be used to display this channel + */ + glyph?: string; + /** + * A user-readable name for this channel, e.g: `"Red"` + */ + name?: string; +} + +/** + * Uniquely defines each channel type. + * Can be "user", "app" or "private". + */ +export type Type = "app" | "private" | "user"; + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + +/** + * A request to unsubscribe an event listener. + * + * A request message from an FDC3-enabled app to a Desktop Agent. + */ +export interface EventListenerUnsubscribeRequest { + /** + * Metadata for a request message sent by an FDC3-enabled app to a Desktop Agent. + */ + meta: AddContextListenerRequestMeta; + /** + * The message payload typically contains the arguments to FDC3 API functions. + */ + payload: EventListenerUnsubscribeRequestPayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + type: "eventListenerUnsubscribeRequest"; +} + +/** + * The message payload typically contains the arguments to FDC3 API functions. + */ +export interface EventListenerUnsubscribeRequestPayload { + listenerUUID: string; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + +/** + * A response to an eventListenerUnsubscribe request. + * + * A message from a Desktop Agent to an FDC3-enabled app responding to an API call. If the + * payload contains an `error` property, the request was unsuccessful. + */ +export interface EventListenerUnsubscribeResponse { + /** + * Metadata for messages sent by a Desktop Agent to an App in response to an API call + */ + meta: AddContextListenerResponseMeta; + /** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ + payload: BroadcastResponseResponsePayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + type: "eventListenerUnsubscribeResponse"; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + +/** + * Setup message sent by the DA proxy code in getAgent() to a channel selector UI in an + * iframe with the channel definitions and current channel selection. + * + * A message used to communicate with user interface frames injected by `getAgent()` for + * displaying UI elements such as the intent resolver or channel selector. Used for messages + * sent in either direction. + */ +export interface Fdc3UserInterfaceChannels { + /** + * The message payload + */ + payload: Fdc3UserInterfaceChannelsPayload; + /** + * Identifies the type of the message to or from the user interface frame. + */ + type: "Fdc3UserInterfaceChannels"; +} + +/** + * The message payload + */ +export interface Fdc3UserInterfaceChannelsPayload { + /** + * The id of the channel that should be currently selected, or `null` if none should be + * selected + */ + selected: null | string; + /** + * User Channel definitions + */ + userChannels: Channel[]; +} + +/** + * Identifies the type of the message to or from the user interface frame. + */ + +/** + * Message from a channel selector UI to the DA proxy sent when the channel selection + * changes. + * + * A message used to communicate with user interface frames injected by `getAgent()` for + * displaying UI elements such as the intent resolver or channel selector. Used for messages + * sent in either direction. + */ +export interface Fdc3UserInterfaceChannelSelected { + /** + * The message payload + */ + payload: Fdc3UserInterfaceChannelSelectedPayload; + /** + * Identifies the type of the message to or from the user interface frame. + */ + type: "Fdc3UserInterfaceChannelSelected"; +} + +/** + * The message payload + */ +export interface Fdc3UserInterfaceChannelSelectedPayload { + /** + * The id of the channel that should be currently selected, or `null` if none should be + * selected + */ + selected: null | string; +} + +/** + * Identifies the type of the message to or from the user interface frame. + */ + +/** + * Message from a UI iframe to the DA proxy (setup by `getAgent()`) indicating that the user + * is dragging the UI to a new location and providing the offset to apply to the location. + * The DA proxy implementation should limit the location to the current bounds of the + * window's viewport + * + * A message used to communicate with user interface frames injected by `getAgent()` for + * displaying UI elements such as the intent resolver or channel selector. Used for messages + * sent in either direction. + */ +export interface Fdc3UserInterfaceDrag { + /** + * The message payload + */ + payload: Fdc3UserInterfaceDragPayload; + /** + * Identifies the type of the message to or from the user interface frame. + */ + type: "Fdc3UserInterfaceDrag"; +} + +/** + * The message payload + */ +export interface Fdc3UserInterfaceDragPayload { + /** + * The offset to move the frame by + */ + mouseOffsets: MouseOffsets; +} + +/** + * The offset to move the frame by + */ +export interface MouseOffsets { + x: number; + y: number; +} + +/** + * Identifies the type of the message to or from the user interface frame. + */ + +/** + * Handshake message sent back to a user interface from the DA proxy code (setup by + * `getAgent()`) over the `MessagePort` provide in the preceding iFrameHello message, + * confirming that it is listening to the `MessagePort` for further communication. + * + * A message used to communicate with user interface frames injected by `getAgent()` for + * displaying UI elements such as the intent resolver or channel selector. Used for messages + * sent in either direction. + */ +export interface Fdc3UserInterfaceHandshake { + /** + * The message payload + */ + payload: Fdc3UserInterfaceHandshakePayload; + /** + * Identifies the type of the message to or from the user interface frame. + */ + type: "Fdc3UserInterfaceHandshake"; +} + +/** + * The message payload + */ +export interface Fdc3UserInterfaceHandshakePayload { + /** + * The version of FDC3 API that the Desktop Agent will provide support for. + */ + fdc3Version: string; +} + +/** + * Identifies the type of the message to or from the user interface frame. + */ + +/** + * Hello message sent by a UI to the Desktop Agent proxy setup by `getAgent()` to indicate + * it is ready to communicate, containing initial CSS to set on the iframe, and including an + * appended `MessagePort` to be used for further communication. + * + * A message used to communicate with user interface frames injected by `getAgent()` for + * displaying UI elements such as the intent resolver or channel selector. Used for messages + * sent in either direction. + */ +export interface Fdc3UserInterfaceHello { + /** + * The message payload + */ + payload: Fdc3UserInterfaceHelloPayload; + /** + * Identifies the type of the message to or from the user interface frame. + */ + type: "Fdc3UserInterfaceHello"; +} + +/** + * The message payload + */ +export interface Fdc3UserInterfaceHelloPayload { + /** + * Details about the UI implementation, such as vendor and version, for logging purposes. + */ + implementationDetails: string; + /** + * A constrained set of styling properties that should be set on the user interface before + * it is displayed. Note `position` cannot be specified and should always be set to `fixed`. + */ + initialCSS: InitialCSS; +} + +/** + * A constrained set of styling properties that should be set on the user interface before + * it is displayed. Note `position` cannot be specified and should always be set to `fixed`. + */ +export interface InitialCSS { + /** + * The initial bottom property to apply to the iframe + */ + bottom?: string; + /** + * The initial height of the iframe + */ + height?: string; + /** + * The initial left property to apply to the iframe + */ + left?: string; + /** + * The maximum height to apply to the iframe + */ + maxHeight?: string; + /** + * The maximum with to apply to the iframe + */ + maxWidth?: string; + /** + * The initial right property to apply to the iframe + */ + right?: string; + /** + * The initial top property to apply to the iframe + */ + top?: string; + /** + * The transition property to apply to the iframe + */ + transition?: string; + /** + * The initial width of the iframe + */ + width?: string; + /** + * The initial zindex to apply to the iframe + */ + zIndex?: string; + [property: string]: any; +} + +/** + * Identifies the type of the message to or from the user interface frame. + */ + +/** + * A message used to communicate with user interface frames injected by `getAgent()` for + * displaying UI elements such as the intent resolver or channel selector. Used for messages + * sent in either direction. + */ +export interface Fdc3UserInterfaceMessage { + /** + * The message payload + */ + payload?: { [key: string]: any }; + /** + * Identifies the type of the message to or from the user interface frame. + */ + type: Fdc3UserInterfaceMessageType; +} + +/** + * Identifies the type of the message to or from the user interface frame. + */ +export type Fdc3UserInterfaceMessageType = "Fdc3UserInterfaceHello" | "Fdc3UserInterfaceHandshake" | "Fdc3UserInterfaceRestyle" | "Fdc3UserInterfaceDrag" | "Fdc3UserInterfaceResolve" | "Fdc3UserInterfaceResolveAction" | "Fdc3UserInterfaceChannels" | "Fdc3UserInterfaceChannelSelected"; + +/** + * Setup message sent by the DA proxy code in getAgent() to an intent resolver UI with the + * resolver data to setup the UI. + * + * A message used to communicate with user interface frames injected by `getAgent()` for + * displaying UI elements such as the intent resolver or channel selector. Used for messages + * sent in either direction. + */ +export interface Fdc3UserInterfaceResolve { + /** + * The message payload + */ + payload: Fdc3UserInterfaceResolvePayload; + /** + * Identifies the type of the message to or from the user interface frame. + */ + type: "Fdc3UserInterfaceResolve"; +} + +/** + * The message payload + */ +export interface Fdc3UserInterfaceResolvePayload { + /** + * An array of AppIntent objects defining the resolution options. + */ + appIntents: AppIntent[]; + context: Context; +} + +/** + * An interface that relates an intent to apps + * + * Used if a raiseIntent request requires additional resolution (e.g. by showing an intent + * resolver) before it can be handled. + */ +export interface AppIntent { + /** + * Details of applications that can resolve the intent. + */ + apps: AppMetadata[]; + /** + * Details of the intent whose relationship to resolving applications is being described. + */ + intent: IntentMetadata; +} + +/** + * Extends an `AppIdentifier`, describing an application or instance of an application, with + * additional descriptive metadata that is usually provided by an FDC3 App Directory that + * the desktop agent connects to. + * + * The additional information from an app directory can aid in rendering UI elements, such + * as a launcher menu or resolver UI. This includes a title, description, tooltip and icon + * and screenshot URLs. + * + * Note that as `AppMetadata` instances are also `AppIdentifiers` they may be passed to the + * `app` argument of `fdc3.open`, `fdc3.raiseIntent` etc. + * + * The calling application instance's own metadata, according to the Desktop Agent (MUST + * include at least the `appId` and `instanceId`). + */ +export interface AppMetadata { + /** + * The unique application identifier located within a specific application directory + * instance. An example of an appId might be 'app@sub.root' + */ + appId: string; + /** + * A longer, multi-paragraph description for the application that could include markup + */ + description?: string; + /** + * The Desktop Agent that the app is available on. Used in Desktop Agent Bridging to + * identify the Desktop Agent to target. + */ + desktopAgent?: string; + /** + * A list of icon URLs for the application that can be used to render UI elements + */ + icons?: Icon[]; + /** + * An optional instance identifier, indicating that this object represents a specific + * instance of the application described. + */ + instanceId?: string; + /** + * An optional set of, implementation specific, metadata fields that can be used to + * disambiguate instances, such as a window title or screen position. Must only be set if + * `instanceId` is set. + */ + instanceMetadata?: { [key: string]: any }; + /** + * The 'friendly' app name. + * This field was used with the `open` and `raiseIntent` calls in FDC3 <2.0, which now + * require an `AppIdentifier` wth `appId` set. + * Note that for display purposes the `title` field should be used, if set, in preference to + * this field. + */ + name?: string; + /** + * The type of output returned for any intent specified during resolution. May express a + * particular context type (e.g. "fdc3.instrument"), channel (e.g. "channel") or a channel + * that will receive a specified type (e.g. "channel"). + */ + resultType?: null | string; + /** + * Images representing the app in common usage scenarios that can be used to render UI + * elements + */ + screenshots?: Image[]; + /** + * A more user-friendly application title that can be used to render UI elements + */ + title?: string; + /** + * A tooltip for the application that can be used to render UI elements + */ + tooltip?: string; + /** + * The Version of the application. + */ + version?: string; +} + +/** + * SPDX-License-Identifier: Apache-2.0 + * Copyright FINOS FDC3 contributors - see NOTICE file + */ +export interface Icon { + /** + * The icon dimension, formatted as `x`. + */ + size?: string; + /** + * The icon url + */ + src: string; + /** + * Icon media type. If not present the Desktop Agent may use the src file extension. + */ + type?: string; +} + +/** + * SPDX-License-Identifier: Apache-2.0 + * Copyright FINOS FDC3 contributors - see NOTICE file + */ +export interface Image { + /** + * Caption for the image. + */ + label?: string; + /** + * The image dimension, formatted as `x`. + */ + size?: string; + /** + * The image url. + */ + src: string; + /** + * Image media type. If not present the Desktop Agent may use the src file extension. + */ + type?: string; +} + +/** + * Details of the intent whose relationship to resolving applications is being described. + * + * Intent descriptor + */ +export interface IntentMetadata { + /** + * Display name for the intent. + */ + displayName?: string; + /** + * The unique name of the intent that can be invoked by the raiseIntent call + */ + name: string; +} + +/** + * Identifies the type of the message to or from the user interface frame. + */ + +/** + * Message from an intent resolver UI to DA proxy code in getAgent() reporting a user + * action. + * + * A message used to communicate with user interface frames injected by `getAgent()` for + * displaying UI elements such as the intent resolver or channel selector. Used for messages + * sent in either direction. + */ +export interface Fdc3UserInterfaceResolveAction { + /** + * The message payload + */ + payload: Fdc3UserInterfaceResolveActionPayload; + /** + * Identifies the type of the message to or from the user interface frame. + */ + type: "Fdc3UserInterfaceResolveAction"; +} + +/** + * The message payload + */ +export interface Fdc3UserInterfaceResolveActionPayload { + action: Action; + /** + * The App resolution option chosen + */ + appIdentifier?: AppIdentifier; + /** + * The intent resolved + */ + intent?: string; +} + +export type Action = "hover" | "click" | "cancel"; + +/** + * Identifies the type of the message to or from the user interface frame. + */ + +/** + * Message from a UI frame to the DA proxy code (setup by `getAgent()`) with updated styling + * information to apply to it. Can be used to implement a pop-open or close interaction or + * other transition needed by a UI implementation. + * + * A message used to communicate with user interface frames injected by `getAgent()` for + * displaying UI elements such as the intent resolver or channel selector. Used for messages + * sent in either direction. + */ +export interface Fdc3UserInterfaceRestyle { + /** + * The message payload + */ + payload: Fdc3UserInterfaceRestylePayload; + /** + * Identifies the type of the message to or from the user interface frame. + */ + type: "Fdc3UserInterfaceRestyle"; +} + +/** + * The message payload + */ +export interface Fdc3UserInterfaceRestylePayload { + /** + * A constrained set of styling properties that should be applied to the frame. Note + * `position` cannot be set, and should always be `fixed`. + */ + updatedCSS: UpdatedCSS; +} + +/** + * A constrained set of styling properties that should be applied to the frame. Note + * `position` cannot be set, and should always be `fixed`. + */ +export interface UpdatedCSS { + /** + * The initial bottom property to apply to the iframe + */ + bottom?: string; + /** + * The updated height of the iframe + */ + height?: string; + /** + * The initial left property to apply to the iframe + */ + left?: string; + /** + * The updated maximum height to apply to the iframe + */ + maxHeight?: string; + /** + * The updated maximum with to apply to the iframe + */ + maxWidth?: string; + /** + * The initial right property to apply to the iframe + */ + right?: string; + /** + * The initial top property to apply to the iframe + */ + top?: string; + /** + * The updated transition property to apply to the iframe + */ + transition?: string; + /** + * The updated width of the iframe + */ + width?: string; + /** + * The updated zindex to apply to the iframe + */ + zIndex?: string; + [property: string]: any; +} + +/** + * Identifies the type of the message to or from the user interface frame. + */ + +/** + * A request for details of instances of a particular app. + * + * A request message from an FDC3-enabled app to a Desktop Agent. + */ +export interface FindInstancesRequest { + /** + * Metadata for a request message sent by an FDC3-enabled app to a Desktop Agent. + */ + meta: AddContextListenerRequestMeta; + /** + * The message payload typically contains the arguments to FDC3 API functions. + */ + payload: FindInstancesRequestPayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + type: "findInstancesRequest"; +} + +/** + * The message payload typically contains the arguments to FDC3 API functions. + */ +export interface FindInstancesRequestPayload { + app: AppIdentifier; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + +/** + * A response to a findInstances request. + * + * A message from a Desktop Agent to an FDC3-enabled app responding to an API call. If the + * payload contains an `error` property, the request was unsuccessful. + */ +export interface FindInstancesResponse { + /** + * Metadata for messages sent by a Desktop Agent to an App in response to an API call + */ + meta: AddContextListenerResponseMeta; + /** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ + payload: FindInstancesResponsePayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + type: "findInstancesResponse"; +} + +/** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + * + * The message payload contains a flag indicating whether the API call was successful, plus + * any return values for the FDC3 API function called, or indicating that the request + * resulted in an error and including a standardized error message. + */ +export interface FindInstancesResponsePayload { + error?: FindInstancesErrors; + appIdentifiers?: AppMetadata[]; +} + +/** + * Constants representing the errors that can be encountered when calling the `open` method + * on the DesktopAgent object (`fdc3`). + * + * Constants representing the errors that can be encountered when calling the `findIntent`, + * `findIntentsByContext`, `raiseIntent` or `raiseIntentForContext` methods on the + * DesktopAgent (`fdc3`). + * + * Unique identifier for a request or event message. Required in all message types + * + * Unique identifier for a response to a specific message and must always be accompanied by + * a RequestUuid. + * + * Unique identifier for a `listener` object returned by a Desktop Agent to an app in + * response to addContextListener, addIntentListener or one of the PrivateChannel event + * listeners and used to identify it in messages (e.g. when unsubscribing). + * + * Unique identifier for an event message sent from a Desktop Agent to an app. + * + * Unique identifier for a for an attempt to connect to a Desktop Agent. A Unique UUID + * should be used in the first (WCP1Hello) message and should be quoted in all subsequent + * messages to link them to the same connection attempt. + * + * Should be set if the raiseIntent request returned an error. + */ +export type FindInstancesErrors = "MalformedContext" | "DesktopAgentNotFound" | "ResolverUnavailable" | "IntentDeliveryFailed" | "NoAppsFound" | "ResolverTimeout" | "TargetAppUnavailable" | "TargetInstanceUnavailable" | "UserCancelledResolution" | "AgentDisconnected" | "NotConnectedToBridge" | "ResponseToBridgeTimedOut" | "MalformedMessage"; + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + +/** + * A request for details of apps available to resolve a particular intent and context pair. + * + * A request message from an FDC3-enabled app to a Desktop Agent. + */ +export interface FindIntentRequest { + /** + * Metadata for a request message sent by an FDC3-enabled app to a Desktop Agent. + */ + meta: AddContextListenerRequestMeta; + /** + * The message payload typically contains the arguments to FDC3 API functions. + */ + payload: FindIntentRequestPayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + type: "findIntentRequest"; +} + +/** + * The message payload typically contains the arguments to FDC3 API functions. + */ +export interface FindIntentRequestPayload { + context?: Context; + intent: string; + resultType?: string; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + +/** + * A response to a findIntent request. + * + * A message from a Desktop Agent to an FDC3-enabled app responding to an API call. If the + * payload contains an `error` property, the request was unsuccessful. + */ +export interface FindIntentResponse { + /** + * Metadata for messages sent by a Desktop Agent to an App in response to an API call + */ + meta: AddContextListenerResponseMeta; + /** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ + payload: FindIntentResponsePayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + type: "findIntentResponse"; +} + +/** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ +export interface FindIntentResponsePayload { + error?: FindInstancesErrors; + appIntent?: AppIntent; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + +/** + * A request for details of intents and apps available to resolve them for a particular + * context. + * + * A request message from an FDC3-enabled app to a Desktop Agent. + */ +export interface FindIntentsByContextRequest { + /** + * Metadata for a request message sent by an FDC3-enabled app to a Desktop Agent. + */ + meta: AddContextListenerRequestMeta; + /** + * The message payload typically contains the arguments to FDC3 API functions. + */ + payload: FindIntentsByContextRequestPayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + type: "findIntentsByContextRequest"; +} + +/** + * The message payload typically contains the arguments to FDC3 API functions. + */ +export interface FindIntentsByContextRequestPayload { + context: Context; + resultType?: string; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + +/** + * A response to a findIntentsByContext request. + * + * A message from a Desktop Agent to an FDC3-enabled app responding to an API call. If the + * payload contains an `error` property, the request was unsuccessful. + */ +export interface FindIntentsByContextResponse { + /** + * Metadata for messages sent by a Desktop Agent to an App in response to an API call + */ + meta: AddContextListenerResponseMeta; + /** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ + payload: FindIntentsByContextResponsePayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + type: "findIntentsByContextResponse"; +} + +/** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ +export interface FindIntentsByContextResponsePayload { + error?: FindInstancesErrors; + appIntents?: AppIntent[]; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + +/** + * A request for metadata about an app. + * + * A request message from an FDC3-enabled app to a Desktop Agent. + */ +export interface GetAppMetadataRequest { + /** + * Metadata for a request message sent by an FDC3-enabled app to a Desktop Agent. + */ + meta: AddContextListenerRequestMeta; + /** + * The message payload typically contains the arguments to FDC3 API functions. + */ + payload: GetAppMetadataRequestPayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + type: "getAppMetadataRequest"; +} + +/** + * The message payload typically contains the arguments to FDC3 API functions. + */ +export interface GetAppMetadataRequestPayload { + app: AppIdentifier; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + +/** + * A response to a getAppMetadata request. + * + * A message from a Desktop Agent to an FDC3-enabled app responding to an API call. If the + * payload contains an `error` property, the request was unsuccessful. + */ +export interface GetAppMetadataResponse { + /** + * Metadata for messages sent by a Desktop Agent to an App in response to an API call + */ + meta: AddContextListenerResponseMeta; + /** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ + payload: GetAppMetadataResponsePayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + type: "getAppMetadataResponse"; +} + +/** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ +export interface GetAppMetadataResponsePayload { + error?: FindInstancesErrors; + appMetadata?: AppMetadata; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + +/** + * A request to return the Channel object for the current User channel membership. Returns + * `null` if the app is not joined to a channel. + * + * A request message from an FDC3-enabled app to a Desktop Agent. + */ +export interface GetCurrentChannelRequest { + /** + * Metadata for a request message sent by an FDC3-enabled app to a Desktop Agent. + */ + meta: AddContextListenerRequestMeta; + /** + * The message payload typically contains the arguments to FDC3 API functions. + */ + payload: GetCurrentChannelRequestPayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + type: "getCurrentChannelRequest"; +} + +/** + * The message payload typically contains the arguments to FDC3 API functions. + */ +export interface GetCurrentChannelRequestPayload { +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + +/** + * A response to a getCurrentChannel request. + * + * A message from a Desktop Agent to an FDC3-enabled app responding to an API call. If the + * payload contains an `error` property, the request was unsuccessful. + */ +export interface GetCurrentChannelResponse { + /** + * Metadata for messages sent by a Desktop Agent to an App in response to an API call + */ + meta: AddContextListenerResponseMeta; + /** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ + payload: GetCurrentChannelResponsePayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + type: "getCurrentChannelResponse"; +} + +/** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ +export interface GetCurrentChannelResponsePayload { + error?: ResponsePayloadError; + channel?: Channel | null; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + +/** + * A request to return the current context (either of a specified type or most recent + * broadcast) of a specified Channel. Returns `null` if no context (of the requested type if + * one was specified) is available in the channel. + * + * A request message from an FDC3-enabled app to a Desktop Agent. + */ +export interface GetCurrentContextRequest { + /** + * Metadata for a request message sent by an FDC3-enabled app to a Desktop Agent. + */ + meta: AddContextListenerRequestMeta; + /** + * The message payload typically contains the arguments to FDC3 API functions. + */ + payload: GetCurrentContextRequestPayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + type: "getCurrentContextRequest"; +} + +/** + * The message payload typically contains the arguments to FDC3 API functions. + */ +export interface GetCurrentContextRequestPayload { + /** + * The id of the channel to return the current context of + */ + channelId: string; + /** + * The type of context to return for OR `null` indicating that the most recently broadcast + * context on the channel should be returned. + */ + contextType: null | string; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + +/** + * A response to a getCurrentContext request. + * + * A message from a Desktop Agent to an FDC3-enabled app responding to an API call. If the + * payload contains an `error` property, the request was unsuccessful. + */ +export interface GetCurrentContextResponse { + /** + * Metadata for messages sent by a Desktop Agent to an App in response to an API call + */ + meta: AddContextListenerResponseMeta; + /** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ + payload: GetCurrentContextResponsePayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + type: "getCurrentContextResponse"; +} + +/** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ +export interface GetCurrentContextResponsePayload { + error?: PurpleError; + /** + * The most recently broadcast context object (of the specified type, if one was specified), + * or `null` if none was available in the channel + */ + context?: null | Context; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + +/** + * Request to retrieve information about the FDC3 Desktop Agent implementation and the + * metadata of the calling application according to the desktop agent. + * + * A request message from an FDC3-enabled app to a Desktop Agent. + */ +export interface GetInfoRequest { + /** + * Metadata for a request message sent by an FDC3-enabled app to a Desktop Agent. + */ + meta: AddContextListenerRequestMeta; + /** + * The message payload typically contains the arguments to FDC3 API functions. + */ + payload: GetInfoRequestPayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + type: "getInfoRequest"; +} + +/** + * The message payload typically contains the arguments to FDC3 API functions. + */ +export interface GetInfoRequestPayload { +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + +/** + * A response to a getInfo request. + * + * A message from a Desktop Agent to an FDC3-enabled app responding to an API call. If the + * payload contains an `error` property, the request was unsuccessful. + */ +export interface GetInfoResponse { + /** + * Metadata for messages sent by a Desktop Agent to an App in response to an API call + */ + meta: AddContextListenerResponseMeta; + /** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ + payload: GetInfoResponsePayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + type: "getInfoResponse"; +} + +/** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ +export interface GetInfoResponsePayload { + error?: ResponsePayloadError; + implementationMetadata?: ImplementationMetadata; +} + +/** + * Implementation metadata for the Desktop Agent, which includes an appMetadata element + * containing a copy of the app's own metadata + * + * Includes Metadata for the current application. + * + * Metadata relating to the FDC3 Desktop Agent implementation and its provider. + */ +export interface ImplementationMetadata { + /** + * The calling application instance's own metadata, according to the Desktop Agent (MUST + * include at least the `appId` and `instanceId`). + */ + appMetadata: AppMetadata; + /** + * The version number of the FDC3 specification that the implementation provides. + * The string must be a numeric semver version, e.g. 1.2 or 1.2.1. + */ + fdc3Version: string; + /** + * Metadata indicating whether the Desktop Agent implements optional features of + * the Desktop Agent API. + */ + optionalFeatures: OptionalFeatures; + /** + * The name of the provider of the Desktop Agent implementation (e.g. Finsemble, Glue42, + * OpenFin etc.). + */ + provider: string; + /** + * The version of the provider of the Desktop Agent implementation (e.g. 5.3.0). + */ + providerVersion?: string; +} + +/** + * Metadata indicating whether the Desktop Agent implements optional features of + * the Desktop Agent API. + */ +export interface OptionalFeatures { + /** + * Used to indicate whether the experimental Desktop Agent Bridging + * feature is implemented by the Desktop Agent. + */ + DesktopAgentBridging: boolean; + /** + * Used to indicate whether the exposure of 'originating app metadata' for + * context and intent messages is supported by the Desktop Agent. + */ + OriginatingAppMetadata: boolean; + /** + * Used to indicate whether the optional `fdc3.joinUserChannel`, + * `fdc3.getCurrentChannel` and `fdc3.leaveCurrentChannel` are implemented by + * the Desktop Agent. + */ + UserChannelMembershipAPIs: boolean; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + +/** + * Request to return a Channel with an auto-generated identity that is intended for private + * communication between applications. + * + * A request message from an FDC3-enabled app to a Desktop Agent. + */ +export interface GetOrCreateChannelRequest { + /** + * Metadata for a request message sent by an FDC3-enabled app to a Desktop Agent. + */ + meta: AddContextListenerRequestMeta; + /** + * The message payload typically contains the arguments to FDC3 API functions. + */ + payload: GetOrCreateChannelRequestPayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + type: "getOrCreateChannelRequest"; +} + +/** + * The message payload typically contains the arguments to FDC3 API functions. + */ +export interface GetOrCreateChannelRequestPayload { + /** + * The id of the channel to return + */ + channelId: string; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + +/** + * A response to a getOrCreateChannel request. + * + * A message from a Desktop Agent to an FDC3-enabled app responding to an API call. If the + * payload contains an `error` property, the request was unsuccessful. + */ +export interface GetOrCreateChannelResponse { + /** + * Metadata for messages sent by a Desktop Agent to an App in response to an API call + */ + meta: AddContextListenerResponseMeta; + /** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ + payload: GetOrCreateChannelResponsePayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + type: "getOrCreateChannelResponse"; +} + +/** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ +export interface GetOrCreateChannelResponsePayload { + error?: PurpleError; + channel?: Channel; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + +/** + * Request to retrieve a list of the User Channels available for the app to join. + * + * A request message from an FDC3-enabled app to a Desktop Agent. + */ +export interface GetUserChannelsRequest { + /** + * Metadata for a request message sent by an FDC3-enabled app to a Desktop Agent. + */ + meta: AddContextListenerRequestMeta; + /** + * The message payload typically contains the arguments to FDC3 API functions. + */ + payload: GetUserChannelsRequestPayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + type: "getUserChannelsRequest"; +} + +/** + * The message payload typically contains the arguments to FDC3 API functions. + */ +export interface GetUserChannelsRequestPayload { +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + +/** + * A response to a getUserChannels request. + * + * A message from a Desktop Agent to an FDC3-enabled app responding to an API call. If the + * payload contains an `error` property, the request was unsuccessful. + */ +export interface GetUserChannelsResponse { + /** + * Metadata for messages sent by a Desktop Agent to an App in response to an API call + */ + meta: AddContextListenerResponseMeta; + /** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ + payload: GetUserChannelsResponsePayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + type: "getUserChannelsResponse"; +} + +/** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ +export interface GetUserChannelsResponsePayload { + error?: PurpleError; + userChannels?: Channel[]; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + +/** + * A request that serves as an acknowledgement of a heartbeat event from the Desktop Agent + * and indicates that an application window or frame is still alive. + * + * A request message from an FDC3-enabled app to a Desktop Agent. + */ +export interface HeartbeatAcknowledgementRequest { + /** + * Metadata for a request message sent by an FDC3-enabled app to a Desktop Agent. + */ + meta: AddContextListenerRequestMeta; + /** + * The message payload typically contains the arguments to FDC3 API functions. + */ + payload: HeartbeatAcknowledgementRequestPayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + type: "heartbeatAcknowledgementRequest"; +} + +/** + * The message payload typically contains the arguments to FDC3 API functions. + */ +export interface HeartbeatAcknowledgementRequestPayload { + /** + * The eventUuid value of the HeartbeatEvent that the acknowledgement being sent relates to. + */ + heartbeatEventUuid: string; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + +/** + * A heartbeat message from the Desktop Agent to an app indicating that the Desktop Agent is + * alive and that the application should send a heartbeatResponseRequest to the agent in + * response. + * + * A message from a Desktop Agent to an FDC3-enabled app representing an event. + */ +export interface HeartbeatEvent { + /** + * Metadata for messages sent by a Desktop Agent to an App notifying it of an event. + */ + meta: BroadcastEventMeta; + /** + * The message payload contains details of the event that the app is being notified about. + */ + payload: HeartbeatEventPayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + type: "heartbeatEvent"; +} + +/** + * The message payload contains details of the event that the app is being notified about. + */ +export interface HeartbeatEventPayload { +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + +/** + * An event message from the Desktop Agent to an app indicating that it has been selected to + * resolve a raised intent and context. + * + * A message from a Desktop Agent to an FDC3-enabled app representing an event. + */ +export interface IntentEvent { + /** + * Metadata for messages sent by a Desktop Agent to an App notifying it of an event. + */ + meta: BroadcastEventMeta; + /** + * The message payload contains details of the event that the app is being notified about. + */ + payload: IntentEventPayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + type: "intentEvent"; +} + +/** + * The message payload contains details of the event that the app is being notified about. + */ +export interface IntentEventPayload { + /** + * The context object passed with the raised intent. + */ + context: Context; + /** + * The intent that was raised. + */ + intent: string; + /** + * Details of the application instance that raised the intent + */ + originatingApp?: AppIdentifier; + /** + * The requestUuid value of the raiseIntentRequest that the intentEvent being sent relates + * to. + */ + raiseIntentRequestUuid: string; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + +/** + * A request to unsubscribe a context listener. + * + * A request message from an FDC3-enabled app to a Desktop Agent. + */ +export interface IntentListenerUnsubscribeRequest { + /** + * Metadata for a request message sent by an FDC3-enabled app to a Desktop Agent. + */ + meta: AddContextListenerRequestMeta; + /** + * The message payload typically contains the arguments to FDC3 API functions. + */ + payload: IntentListenerUnsubscribeRequestPayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + type: "intentListenerUnsubscribeRequest"; +} + +/** + * The message payload typically contains the arguments to FDC3 API functions. + */ +export interface IntentListenerUnsubscribeRequestPayload { + listenerUUID: string; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + +/** + * A response to a intentListenerUnsubscribe request. + * + * A message from a Desktop Agent to an FDC3-enabled app responding to an API call. If the + * payload contains an `error` property, the request was unsuccessful. + */ +export interface IntentListenerUnsubscribeResponse { + /** + * Metadata for messages sent by a Desktop Agent to an App in response to an API call + */ + meta: AddContextListenerResponseMeta; + /** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ + payload: BroadcastResponseResponsePayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + type: "intentListenerUnsubscribeResponse"; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + +/** + * A request to deliver a result for an intent (which may include a `void` result that just + * indicates that the handler has run, returning no result). The result is tied to the + * intentEvent it relates to by quoting the `eventUuid` of the intentEvent in its payload. + * + * A request message from an FDC3-enabled app to a Desktop Agent. + */ +export interface IntentResultRequest { + /** + * Metadata for a request message sent by an FDC3-enabled app to a Desktop Agent. + */ + meta: AddContextListenerRequestMeta; + /** + * The message payload typically contains the arguments to FDC3 API functions. + */ + payload: IntentResultRequestPayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + type: "intentResultRequest"; +} + +/** + * The message payload typically contains the arguments to FDC3 API functions. + */ +export interface IntentResultRequestPayload { + /** + * The eventUuid value of the intentEvent that the result being sent relates to. + */ + intentEventUuid: string; + intentResult: IntentResult; + /** + * The requestUuid value of the raiseIntentRequest that the result being sent relates to. + */ + raiseIntentRequestUuid: string; +} + +export interface IntentResult { + context?: Context; + channel?: Channel; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + +/** + * A response to a request to deliver an intent result. + * + * A message from a Desktop Agent to an FDC3-enabled app responding to an API call. If the + * payload contains an `error` property, the request was unsuccessful. + */ +export interface IntentResultResponse { + /** + * Metadata for messages sent by a Desktop Agent to an App in response to an API call + */ + meta: AddContextListenerResponseMeta; + /** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ + payload: BroadcastResponseResponsePayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + type: "intentResultResponse"; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + +/** + * Request to join the app to the specified User channel. On successfully joining a channel, + * client code should make subsequent requests to get the current context of that channel + * for all registered context listeners and then call their handlers with it. + * + * A request message from an FDC3-enabled app to a Desktop Agent. + */ +export interface JoinUserChannelRequest { + /** + * Metadata for a request message sent by an FDC3-enabled app to a Desktop Agent. + */ + meta: AddContextListenerRequestMeta; + /** + * The message payload typically contains the arguments to FDC3 API functions. + */ + payload: JoinUserChannelRequestPayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + type: "joinUserChannelRequest"; +} + +/** + * The message payload typically contains the arguments to FDC3 API functions. + */ +export interface JoinUserChannelRequestPayload { + /** + * The id of the channel to join + */ + channelId: string; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + +/** + * A response to a joinUserChannel request. On receipt of this response, client code should + * make subsequent requests to get the current context of that channel for all registered + * context listeners and then call their handlers with it. + * + * A message from a Desktop Agent to an FDC3-enabled app responding to an API call. If the + * payload contains an `error` property, the request was unsuccessful. + */ +export interface JoinUserChannelResponse { + /** + * Metadata for messages sent by a Desktop Agent to an App in response to an API call + */ + meta: AddContextListenerResponseMeta; + /** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ + payload: JoinUserChannelResponsePayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + type: "joinUserChannelResponse"; +} + +/** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ +export interface JoinUserChannelResponsePayload { + error?: PurpleError; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + +/** + * Request to remove the app from any User channel membership. + * + * A request message from an FDC3-enabled app to a Desktop Agent. + */ +export interface LeaveCurrentChannelRequest { + /** + * Metadata for a request message sent by an FDC3-enabled app to a Desktop Agent. + */ + meta: AddContextListenerRequestMeta; + /** + * The message payload typically contains the arguments to FDC3 API functions. + */ + payload: LeaveCurrentChannelRequestPayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + type: "leaveCurrentChannelRequest"; +} + +/** + * The message payload typically contains the arguments to FDC3 API functions. + */ +export interface LeaveCurrentChannelRequestPayload { +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + +/** + * A response to a leaveCurrentChannel request. + * + * A message from a Desktop Agent to an FDC3-enabled app responding to an API call. If the + * payload contains an `error` property, the request was unsuccessful. + */ +export interface LeaveCurrentChannelResponse { + /** + * Metadata for messages sent by a Desktop Agent to an App in response to an API call + */ + meta: AddContextListenerResponseMeta; + /** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ + payload: LeaveCurrentChannelResponsePayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + type: "leaveCurrentChannelResponse"; +} + +/** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ +export interface LeaveCurrentChannelResponsePayload { + error?: PurpleError; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + +/** + * A request to open an application. + * + * A request message from an FDC3-enabled app to a Desktop Agent. + */ +export interface OpenRequest { + /** + * Metadata for a request message sent by an FDC3-enabled app to a Desktop Agent. + */ + meta: AddContextListenerRequestMeta; + /** + * The message payload typically contains the arguments to FDC3 API functions. + */ + payload: OpenRequestPayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + type: "openRequest"; +} + +/** + * The message payload typically contains the arguments to FDC3 API functions. + */ +export interface OpenRequestPayload { + app: AppIdentifier; + /** + * If a Context object is passed in, this object will be provided to the opened application + * via a contextListener. The Context argument is functionally equivalent to opening the + * target app with no context and broadcasting the context directly to it. + */ + context?: Context; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + +/** + * A response to a open request. + * + * A message from a Desktop Agent to an FDC3-enabled app responding to an API call. If the + * payload contains an `error` property, the request was unsuccessful. + */ +export interface OpenResponse { + /** + * Metadata for messages sent by a Desktop Agent to an App in response to an API call + */ + meta: AddContextListenerResponseMeta; + /** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ + payload: OpenResponsePayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + type: "openResponse"; +} + +/** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ +export interface OpenResponsePayload { + error?: OpenErrorResponsePayload; + appIdentifier?: AppIdentifier; +} + +/** + * Constants representing the errors that can be encountered when calling the `open` method + * on the DesktopAgent object (`fdc3`). + * + * Constants representing the errors that can be encountered when calling the `findIntent`, + * `findIntentsByContext`, `raiseIntent` or `raiseIntentForContext` methods on the + * DesktopAgent (`fdc3`). + */ +export type OpenErrorResponsePayload = "MalformedContext" | "AppNotFound" | "AppTimeout" | "DesktopAgentNotFound" | "ErrorOnLaunch" | "ResolverUnavailable" | "AgentDisconnected" | "NotConnectedToBridge" | "ResponseToBridgeTimedOut" | "MalformedMessage"; + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + +/** + * A request to add an event listener to a specific PrivateChannel. + * + * A request message from an FDC3-enabled app to a Desktop Agent. + */ +export interface PrivateChannelAddEventListenerRequest { + /** + * Metadata for a request message sent by an FDC3-enabled app to a Desktop Agent. + */ + meta: AddContextListenerRequestMeta; + /** + * The message payload typically contains the arguments to FDC3 API functions. + */ + payload: TPayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + type: "privateChannelAddEventListenerRequest"; +} + +/** + * The message payload typically contains the arguments to FDC3 API functions. + */ +export interface TPayload { + /** + * The type of PrivateChannel event that the listener should be applied to. + */ + listenerType: PrivateChannelEventListenerTypes; + /** + * The Id of the PrivateChannel that the listener should be added to. + */ + privateChannelId: string; +} + +/** + * The type of PrivateChannel event that the listener should be applied to. + * + * Event listener type names for Private Channel events + */ +export type PrivateChannelEventListenerTypes = "onAddContextListener" | "onUnsubscribe" | "onDisconnect"; + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + +/** + * A response to a privateChannelAddEventListener request. + * + * A message from a Desktop Agent to an FDC3-enabled app responding to an API call. If the + * payload contains an `error` property, the request was unsuccessful. + */ +export interface PrivateChannelAddEventListenerResponse { + /** + * Metadata for messages sent by a Desktop Agent to an App in response to an API call + */ + meta: AddContextListenerResponseMeta; + /** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ + payload: PrivateChannelAddEventListenerResponsePayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + type: "privateChannelAddEventListenerResponse"; +} + +/** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ +export interface PrivateChannelAddEventListenerResponsePayload { + error?: PurpleError; + listenerUUID?: string; + [property: string]: any; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + +/** + * Request that indicates that a participant will no longer interact with a specified + * `PrivateChannel`. + * + * A request message from an FDC3-enabled app to a Desktop Agent. + */ +export interface PrivateChannelDisconnectRequest { + /** + * Metadata for a request message sent by an FDC3-enabled app to a Desktop Agent. + */ + meta: AddContextListenerRequestMeta; + /** + * The message payload typically contains the arguments to FDC3 API functions. + */ + payload: PrivateChannelDisconnectRequestPayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + type: "privateChannelDisconnectRequest"; +} + +/** + * The message payload typically contains the arguments to FDC3 API functions. + */ +export interface PrivateChannelDisconnectRequestPayload { + /** + * The Id of the Channel that should be disconnected from + */ + channelId: string; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + +/** + * A response to a privateChannelDisconnect request. + * + * A message from a Desktop Agent to an FDC3-enabled app responding to an API call. If the + * payload contains an `error` property, the request was unsuccessful. + */ +export interface PrivateChannelDisconnectResponse { + /** + * Metadata for messages sent by a Desktop Agent to an App in response to an API call + */ + meta: AddContextListenerResponseMeta; + /** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ + payload: PrivateChannelDisconnectResponsePayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + type: "privateChannelDisconnectResponse"; +} + +/** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ +export interface PrivateChannelDisconnectResponsePayload { + error?: PurpleError; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + +/** + * An event message from the Desktop Agent to an app indicating that another app has added a + * context listener to a specific PrivateChannel. + * + * A message from a Desktop Agent to an FDC3-enabled app representing an event. + */ +export interface PrivateChannelOnAddContextListenerEvent { + /** + * Metadata for messages sent by a Desktop Agent to an App notifying it of an event. + */ + meta: BroadcastEventMeta; + /** + * The message payload contains details of the event that the app is being notified about. + */ + payload: PrivateChannelOnAddContextListenerEventPayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + type: "privateChannelOnAddContextListenerEvent"; +} + +/** + * The message payload contains details of the event that the app is being notified about. + */ +export interface PrivateChannelOnAddContextListenerEventPayload { + /** + * The type of the context listener added to the channel by another app, or null if it will + * listen to all types. + */ + contextType: null | string; + /** + * The Id of the PrivateChannel that the listener was added to. + */ + privateChannelId: string; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + +/** + * An event message from the Desktop Agent to an app indicating that another app has + * disconnected from a specific PrivateChannel and will no longer interact with it. + * + * A message from a Desktop Agent to an FDC3-enabled app representing an event. + */ +export interface PrivateChannelOnDisconnectEvent { + /** + * Metadata for messages sent by a Desktop Agent to an App notifying it of an event. + */ + meta: BroadcastEventMeta; + /** + * The message payload contains details of the event that the app is being notified about. + */ + payload: PrivateChannelOnDisconnectEventPayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + type: "privateChannelOnDisconnectEvent"; +} + +/** + * The message payload contains details of the event that the app is being notified about. + */ +export interface PrivateChannelOnDisconnectEventPayload { + /** + * The Id of the PrivateChannel that the app has disconnected from. + */ + privateChannelId: string; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + +/** + * An event message from the Desktop Agent to an app indicating that another app has + * unsubscribed a context listener from a specific PrivateChannel. + * + * A message from a Desktop Agent to an FDC3-enabled app representing an event. + */ +export interface PrivateChannelOnUnsubscribeEvent { + /** + * Metadata for messages sent by a Desktop Agent to an App notifying it of an event. + */ + meta: BroadcastEventMeta; + /** + * The message payload contains details of the event that the app is being notified about. + */ + payload: PrivateChannelOnUnsubscribeEventPayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + type: "privateChannelOnUnsubscribeEvent"; +} + +/** + * The message payload contains details of the event that the app is being notified about. + */ +export interface PrivateChannelOnUnsubscribeEventPayload { + /** + * The type of the context listener unsubscribed from the channel by another app, or null if + * it was listening to all types. + */ + contextType: null | string; + /** + * The Id of the PrivateChannel that the listener was unsubscribed from. + */ + privateChannelId: string; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + +/** + * A request to unsubscribe a context listener. + * + * A request message from an FDC3-enabled app to a Desktop Agent. + */ +export interface PrivateChannelUnsubscribeEventListenerRequest { + /** + * Metadata for a request message sent by an FDC3-enabled app to a Desktop Agent. + */ + meta: AddContextListenerRequestMeta; + /** + * The message payload typically contains the arguments to FDC3 API functions. + */ + payload: PrivateChannelUnsubscribeEventListenerRequestPayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + type: "privateChannelUnsubscribeEventListenerRequest"; +} + +/** + * The message payload typically contains the arguments to FDC3 API functions. + */ +export interface PrivateChannelUnsubscribeEventListenerRequestPayload { + listenerUUID: string; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + +/** + * A response to a privateChannelUnsubscribeEventListener request. + * + * A message from a Desktop Agent to an FDC3-enabled app responding to an API call. If the + * payload contains an `error` property, the request was unsuccessful. + */ +export interface PrivateChannelUnsubscribeEventListenerResponse { + /** + * Metadata for messages sent by a Desktop Agent to an App in response to an API call + */ + meta: AddContextListenerResponseMeta; + /** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ + payload: BroadcastResponseResponsePayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + type: "privateChannelUnsubscribeEventListenerResponse"; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + +/** + * A request to raise an unspecified intent for a specified context. + * + * A request message from an FDC3-enabled app to a Desktop Agent. + */ +export interface RaiseIntentForContextRequest { + /** + * Metadata for a request message sent by an FDC3-enabled app to a Desktop Agent. + */ + meta: AddContextListenerRequestMeta; + /** + * The message payload typically contains the arguments to FDC3 API functions. + */ + payload: RaiseIntentForContextRequestPayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + type: "raiseIntentForContextRequest"; +} + +/** + * The message payload typically contains the arguments to FDC3 API functions. + */ +export interface RaiseIntentForContextRequestPayload { + app?: AppIdentifier; + context: Context; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + +/** + * A response to a raiseIntentForContext request. + * + * A message from a Desktop Agent to an FDC3-enabled app responding to an API call. If the + * payload contains an `error` property, the request was unsuccessful. + */ +export interface RaiseIntentForContextResponse { + /** + * Metadata for messages sent by a Desktop Agent to an App in response to an API call + */ + meta: AddContextListenerResponseMeta; + /** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + * + * There are 3 possible responses to a raiseIntentForContext request, each of which sets a + * single property in the payload: Success (`intentResolution`), Needs further resolution + * (`appIntents`) or Error (`error`). + */ + payload: RaiseIntentForContextResponsePayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + type: "raiseIntentForContextResponse"; +} + +/** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + * + * There are 3 possible responses to a raiseIntentForContext request, each of which sets a + * single property in the payload: Success (`intentResolution`), Needs further resolution + * (`appIntents`) or Error (`error`). + * + * Response to a raiseIntentForContext request that needs additional resolution (i.e. show + * an intent resolver UI) + * + * Used if a raiseIntent request resulted in an error + */ +export interface RaiseIntentForContextResponsePayload { + /** + * Should be set if the raiseIntent request returned an error. + */ + error?: FindInstancesErrors; + /** + * Used if the raiseIntent request was successfully resolved + */ + intentResolution?: IntentResolution; + /** + * Used if a raiseIntentForContext request requires additional resolution (e.g. by showing + * an intent resolver) before it can be handled. + */ + appIntents?: AppIntent[]; +} + +/** + * Used if the raiseIntent request was successfully resolved + * + * IntentResolution provides a standard format for data returned upon resolving an intent. + * + * ```javascript + * //resolve a "Chain" type intent + * let resolution = await agent.raiseIntent("intentName", context); + * + * //resolve a "Client-Service" type intent with a data response or a Channel + * let resolution = await agent.raiseIntent("intentName", context); + * try { + * const result = await resolution.getResult(); + * if (result && result.broadcast) { + * console.log(`${resolution.source} returned a channel with id ${result.id}`); + * } else if (result){ + * console.log(`${resolution.source} returned data: ${JSON.stringify(result)}`); + * } else { + * console.error(`${resolution.source} didn't return data` + * } + * } catch(error) { + * console.error(`${resolution.source} returned an error: ${error}`); + * } + * + * // Use metadata about the resolving app instance to target a further intent + * await agent.raiseIntent("intentName", context, resolution.source); + * ``` + */ +export interface IntentResolution { + /** + * The intent that was raised. May be used to determine which intent the user + * chose in response to `fdc3.raiseIntentForContext()`. + */ + intent: string; + /** + * Identifier for the app instance that was selected (or started) to resolve the intent. + * `source.instanceId` MUST be set, indicating the specific app instance that + * received the intent. + */ + source: AppIdentifier; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + +/** + * A request to raise an intent for a context. + * + * A request message from an FDC3-enabled app to a Desktop Agent. + */ +export interface RaiseIntentRequest { + /** + * Metadata for a request message sent by an FDC3-enabled app to a Desktop Agent. + */ + meta: AddContextListenerRequestMeta; + /** + * The message payload typically contains the arguments to FDC3 API functions. + */ + payload: RaiseIntentRequestPayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + type: "raiseIntentRequest"; +} + +/** + * The message payload typically contains the arguments to FDC3 API functions. + */ +export interface RaiseIntentRequestPayload { + app?: AppIdentifier; + context: Context; + intent: string; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Request' appended. + */ + +/** + * A response to a raiseIntent request. + * + * A message from a Desktop Agent to an FDC3-enabled app responding to an API call. If the + * payload contains an `error` property, the request was unsuccessful. + */ +export interface RaiseIntentResponse { + /** + * Metadata for messages sent by a Desktop Agent to an App in response to an API call + */ + meta: AddContextListenerResponseMeta; + /** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + * + * There are 3 possible responses to a raiseIntent request, each of which sets a single + * property in the payload: Success (`intentResolution`), Needs further resolution + * (`appIntent`) or Error (`error`). + */ + payload: RaiseIntentResponsePayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + type: "raiseIntentResponse"; +} + +/** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + * + * There are 3 possible responses to a raiseIntent request, each of which sets a single + * property in the payload: Success (`intentResolution`), Needs further resolution + * (`appIntent`) or Error (`error`). + * + * Response to a raiseIntent request that needs additional resolution (i.e. show an intent + * resolver UI). + * + * Used if a raiseIntent request resulted in an error + */ +export interface RaiseIntentResponsePayload { + /** + * Should be set if the raiseIntent request returned an error. + */ + error?: FindInstancesErrors; + /** + * Used if the raiseIntent request was successfully resolved + */ + intentResolution?: IntentResolution; + /** + * Used if a raiseIntent request requires additional resolution (e.g. by showing an intent + * resolver) before it can be handled. + */ + appIntent?: AppIntent; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + +/** + * A secondary response to a request to raise an intent used to deliver the intent result. + * This message should quote the original requestUuid of the raiseIntentRequest message in + * its `meta.requestUuid` field. + * + * A message from a Desktop Agent to an FDC3-enabled app responding to an API call. If the + * payload contains an `error` property, the request was unsuccessful. + */ +export interface RaiseIntentResultResponse { + /** + * Metadata for messages sent by a Desktop Agent to an App in response to an API call + */ + meta: AddContextListenerResponseMeta; + /** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ + payload: RaiseIntentResultResponsePayload; + /** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + type: "raiseIntentResultResponse"; +} + +/** + * A payload for a response to an API call that will contain any return values or an `error` + * property containing a standardized error message indicating that the request was + * unsuccessful. + */ +export interface RaiseIntentResultResponsePayload { + error?: ResponsePayloadError; + intentResult?: IntentResult; +} + +/** + * Identifies the type of the message and it is typically set to the FDC3 function name that + * the message relates to, e.g. 'findIntent', with 'Response' appended. + */ + +/** + * Hello message sent by an application to a parent window or frame when attempting to + * establish connectivity to a Desktop Agent + * + * A message used during the connection flow for an application to a Desktop Agent in a + * browser window. Used for messages sent in either direction. + */ +export interface WebConnectionProtocol1Hello { + /** + * Metadata for this connection step message + */ + meta: WebConnectionProtocol1HelloMeta; + /** + * The message payload, containing data pertaining to this connection step. + */ + payload: WebConnectionProtocol1HelloPayload; + /** + * Identifies the type of the connection step message. + */ + type: "WCP1Hello"; +} + +/** + * Metadata for this connection step message + * + * Metadata for a disconnection step message + */ +export interface WebConnectionProtocol1HelloMeta { + connectionAttemptUuid: string; + timestamp: Date; +} + +/** + * The message payload, containing data pertaining to this connection step. + */ +export interface WebConnectionProtocol1HelloPayload { + /** + * The current URL of the page attempting to connect. This may differ from the identityUrl, + * but the origins MUST match. + */ + actualUrl: string; + /** + * A flag that may be used to indicate that a channel selector user interface is or is not + * required. Set to `false` if the app includes its own interface for selecting channels or + * does not work with user channels. + */ + channelSelector?: boolean; + /** + * The version of FDC3 API that the app supports. + */ + fdc3Version: string; + /** + * URL to use for the identity of the application. Desktop Agents MUST validate that the + * origin of the message matches the URL, but MAY implement custom comparison logic. + */ + identityUrl: string; + /** + * A flag that may be used to indicate that an intent resolver is or is not required. Set to + * `false` if no intents, or only targeted intents, are raised. + */ + intentResolver?: boolean; + [property: string]: any; +} + +/** + * Identifies the type of the connection step message. + */ + +/** + * Response from a Desktop Agent to an application requesting access to it indicating that + * it should load a specified URL into a hidden iframe in order to establish connectivity to + * a Desktop Agent + * + * A message used during the connection flow for an application to a Desktop Agent in a + * browser window. Used for messages sent in either direction. + */ +export interface WebConnectionProtocol2LoadURL { + /** + * Metadata for this connection step message + */ + meta: WebConnectionProtocol1HelloMeta; + /** + * The message payload, containing data pertaining to this connection step. + */ + payload: WebConnectionProtocol2LoadURLPayload; + /** + * Identifies the type of the connection step message. + */ + type: "WCP2LoadUrl"; +} + +/** + * The message payload, containing data pertaining to this connection step. + */ +export interface WebConnectionProtocol2LoadURLPayload { + /** + * A URL which can be used to establish communication with the Desktop Agent, via loading + * the URL into an iframe and restarting the Web Connection protocol with the iframe as the + * target + */ + iframeUrl: string; + [property: string]: any; +} + +/** + * Identifies the type of the connection step message. + */ + +/** + * Handshake message sent by the Desktop Agent to the app (with a MessagePort appended) that + * should be used for subsequent communication steps. + * + * A message used during the connection flow for an application to a Desktop Agent in a + * browser window. Used for messages sent in either direction. + */ +export interface WebConnectionProtocol3Handshake { + /** + * Metadata for this connection step message + */ + meta: WebConnectionProtocol1HelloMeta; + /** + * The message payload, containing data pertaining to this connection step. + */ + payload: WebConnectionProtocol3HandshakePayload; + /** + * Identifies the type of the connection step message. + */ + type: "WCP3Handshake"; +} + +/** + * The message payload, containing data pertaining to this connection step. + */ +export interface WebConnectionProtocol3HandshakePayload { + /** + * Indicates whether a channel selector user interface is required and the URL to use to do + * so. Set to `true` to use the default or `false` to disable the channel selector (as the + * Desktop Agent will handle it another way). + */ + channelSelectorUrl: boolean | string; + /** + * The version of FDC3 API that the Desktop Agent will provide support for. + */ + fdc3Version: string; + /** + * Indicates whether an intent resolver user interface is required and the URL to use to do + * so. Set to `true` to use the default or `false` to disable the intent resolver (as the + * Desktop Agent will handle it another way). + */ + intentResolverUrl: boolean | string; +} + +/** + * Identifies the type of the connection step message. + */ + +/** + * Identity Validation request from an app attempting to connect to a Desktop Agent. + * + * A message used during the connection flow for an application to a Desktop Agent in a + * browser window. Used for messages sent in either direction. + */ +export interface WebConnectionProtocol4ValidateAppIdentity { + /** + * Metadata for this connection step message + */ + meta: WebConnectionProtocol1HelloMeta; + /** + * The message payload, containing data pertaining to this connection step. + */ + payload: WebConnectionProtocol4ValidateAppIdentityPayload; + /** + * Identifies the type of the connection step message. + */ + type: "WCP4ValidateAppIdentity"; +} + +/** + * The message payload, containing data pertaining to this connection step. + */ +export interface WebConnectionProtocol4ValidateAppIdentityPayload { + /** + * The current URL of the page attempting to connect. This may differ from the identityUrl, + * but the origins MUST match. + */ + actualUrl: string; + /** + * URL to use for the identity of the application. Desktop Agents MUST validate that the + * origin of the message matches the URL, but MAY implement custom comparison logic. + */ + identityUrl: string; + /** + * If an application has previously connected to the desktop agent, it may specify its prior + * instance id and associated instance UUID to request the same same instance Id be assigned. + */ + instanceId?: string; + /** + * Instance UUID associated with the requested instanceId. + */ + instanceUuid?: string; +} + +/** + * Identifies the type of the connection step message. + */ + +/** + * Message sent by the Desktop Agent to an app if their identity validation fails. + * + * A message used during the connection flow for an application to a Desktop Agent in a + * browser window. Used for messages sent in either direction. + */ +export interface WebConnectionProtocol5ValidateAppIdentityFailedResponse { + /** + * Metadata for this connection step message + */ + meta: WebConnectionProtocol1HelloMeta; + /** + * The message payload, containing data pertaining to this connection step. + */ + payload: WebConnectionProtocol5ValidateAppIdentityFailedResponsePayload; + /** + * Identifies the type of the connection step message. + */ + type: "WCP5ValidateAppIdentityFailedResponse"; +} + +/** + * The message payload, containing data pertaining to this connection step. + */ +export interface WebConnectionProtocol5ValidateAppIdentityFailedResponsePayload { + message?: string; +} + +/** + * Identifies the type of the connection step message. + */ + +/** + * Message sent by the Desktop Agent to an app after successful identity validation + * + * A message used during the connection flow for an application to a Desktop Agent in a + * browser window. Used for messages sent in either direction. + */ +export interface WebConnectionProtocol5ValidateAppIdentitySuccessResponse { + /** + * Metadata for this connection step message + */ + meta: WebConnectionProtocol1HelloMeta; + /** + * The message payload, containing data pertaining to this connection step. + */ + payload: WebConnectionProtocol5ValidateAppIdentitySuccessResponsePayload; + /** + * Identifies the type of the connection step message. + */ + type: "WCP5ValidateAppIdentityResponse"; +} + +/** + * The message payload, containing data pertaining to this connection step. + */ +export interface WebConnectionProtocol5ValidateAppIdentitySuccessResponsePayload { + /** + * The appId that the app's identity was validated against + */ + appId: string; + /** + * Implementation metadata for the Desktop Agent, which includes an appMetadata element + * containing a copy of the app's own metadata + */ + implementationMetadata: ImplementationMetadata; + /** + * The instance Id granted to the application by the Desktop Agent. + */ + instanceId: string; + /** + * Instance UUID associated with the instanceId granted, which may be used to retrieve the + * same instance Id if the app is reloaded or navigates. + */ + instanceUuid: string; +} + +/** + * Identifies the type of the connection step message. + */ + +/** + * Goodbye message to be sent to the Desktop Agent when disconnecting (e.g. when closing the + * window or navigating). Desktop Agents should close the MessagePort after receiving this + * message, but retain instance details in case the application reconnects (e.g. after a + * navigation event). + * + * A message used during the connection flow for an application to a Desktop Agent in a + * browser window. Used for messages sent in either direction. + */ +export interface WebConnectionProtocol6Goodbye { + /** + * Metadata for a disconnection step message + */ + meta: WebConnectionProtocol6GoodbyeMeta; + /** + * Identifies the type of the connection step message. + */ + type: "WCP6Goodbye"; +} + +/** + * Metadata for a disconnection step message + * + * Metadata for this connection step message + */ +export interface WebConnectionProtocol6GoodbyeMeta { + timestamp: Date; +} + +/** + * Identifies the type of the connection step message. + */ + +/** + * A message used during the connection flow for an application to a Desktop Agent in a + * browser window. Used for messages sent in either direction. + */ +export interface WebConnectionProtocolMessage { + meta: WebConnectionProtocolMessageMeta; + /** + * The message payload, containing data pertaining to this connection step. + */ + payload?: { [key: string]: any }; + /** + * Identifies the type of the connection step message. + */ + type: ConnectionStepMessageType; +} + +/** + * Metadata for a disconnection step message + * + * Metadata for this connection step message + */ +export interface WebConnectionProtocolMessageMeta { + timestamp: Date; + connectionAttemptUuid?: string; +} + +/** + * Identifies the type of the connection step message. + */ +export type ConnectionStepMessageType = "WCP1Hello" | "WCP2LoadUrl" | "WCP3Handshake" | "WCP4ValidateAppIdentity" | "WCP5ValidateAppIdentityFailedResponse" | "WCP5ValidateAppIdentityResponse" | "WCP6Goodbye"; + +// Converts JSON strings to/from your types +// and asserts the results of JSON.parse at runtime +export class Convert { + public static toAddContextListenerRequest(json: string): AddContextListenerRequest { + return cast(JSON.parse(json), r("AddContextListenerRequest")); + } + + public static addContextListenerRequestToJson(value: AddContextListenerRequest): string { + return JSON.stringify(uncast(value, r("AddContextListenerRequest")), null, 2); + } + + public static toAddContextListenerResponse(json: string): AddContextListenerResponse { + return cast(JSON.parse(json), r("AddContextListenerResponse")); + } + + public static addContextListenerResponseToJson(value: AddContextListenerResponse): string { + return JSON.stringify(uncast(value, r("AddContextListenerResponse")), null, 2); + } + + public static toAddEventListenerRequest(json: string): AddEventListenerRequest { + return cast(JSON.parse(json), r("AddEventListenerRequest")); + } + + public static addEventListenerRequestToJson(value: AddEventListenerRequest): string { + return JSON.stringify(uncast(value, r("AddEventListenerRequest")), null, 2); + } + + public static toAddEventListenerResponse(json: string): AddEventListenerResponse { + return cast(JSON.parse(json), r("AddEventListenerResponse")); + } + + public static addEventListenerResponseToJson(value: AddEventListenerResponse): string { + return JSON.stringify(uncast(value, r("AddEventListenerResponse")), null, 2); + } + + public static toAddIntentListenerRequest(json: string): AddIntentListenerRequest { + return cast(JSON.parse(json), r("AddIntentListenerRequest")); + } + + public static addIntentListenerRequestToJson(value: AddIntentListenerRequest): string { + return JSON.stringify(uncast(value, r("AddIntentListenerRequest")), null, 2); + } + + public static toAddIntentListenerResponse(json: string): AddIntentListenerResponse { + return cast(JSON.parse(json), r("AddIntentListenerResponse")); + } + + public static addIntentListenerResponseToJson(value: AddIntentListenerResponse): string { + return JSON.stringify(uncast(value, r("AddIntentListenerResponse")), null, 2); + } + + public static toAgentEventMessage(json: string): AgentEventMessage { + return cast(JSON.parse(json), r("AgentEventMessage")); + } + + public static agentEventMessageToJson(value: AgentEventMessage): string { + return JSON.stringify(uncast(value, r("AgentEventMessage")), null, 2); + } + + public static toAgentResponseMessage(json: string): AgentResponseMessage { + return cast(JSON.parse(json), r("AgentResponseMessage")); + } + + public static agentResponseMessageToJson(value: AgentResponseMessage): string { + return JSON.stringify(uncast(value, r("AgentResponseMessage")), null, 2); + } + + public static toAppRequestMessage(json: string): AppRequestMessage { + return cast(JSON.parse(json), r("AppRequestMessage")); + } + + public static appRequestMessageToJson(value: AppRequestMessage): string { + return JSON.stringify(uncast(value, r("AppRequestMessage")), null, 2); + } + + public static toBroadcastEvent(json: string): BroadcastEvent { + return cast(JSON.parse(json), r("BroadcastEvent")); + } + + public static broadcastEventToJson(value: BroadcastEvent): string { + return JSON.stringify(uncast(value, r("BroadcastEvent")), null, 2); + } + + public static toBroadcastRequest(json: string): BroadcastRequest { + return cast(JSON.parse(json), r("BroadcastRequest")); + } + + public static broadcastRequestToJson(value: BroadcastRequest): string { + return JSON.stringify(uncast(value, r("BroadcastRequest")), null, 2); + } + + public static toBroadcastResponse(json: string): BroadcastResponse { + return cast(JSON.parse(json), r("BroadcastResponse")); + } + + public static broadcastResponseToJson(value: BroadcastResponse): string { + return JSON.stringify(uncast(value, r("BroadcastResponse")), null, 2); + } + + public static toChannelChangedEvent(json: string): ChannelChangedEvent { + return cast(JSON.parse(json), r("ChannelChangedEvent")); + } + + public static channelChangedEventToJson(value: ChannelChangedEvent): string { + return JSON.stringify(uncast(value, r("ChannelChangedEvent")), null, 2); + } + + public static toContextListenerUnsubscribeRequest(json: string): ContextListenerUnsubscribeRequest { + return cast(JSON.parse(json), r("ContextListenerUnsubscribeRequest")); + } + + public static contextListenerUnsubscribeRequestToJson(value: ContextListenerUnsubscribeRequest): string { + return JSON.stringify(uncast(value, r("ContextListenerUnsubscribeRequest")), null, 2); + } + + public static toContextListenerUnsubscribeResponse(json: string): ContextListenerUnsubscribeResponse { + return cast(JSON.parse(json), r("ContextListenerUnsubscribeResponse")); + } + + public static contextListenerUnsubscribeResponseToJson(value: ContextListenerUnsubscribeResponse): string { + return JSON.stringify(uncast(value, r("ContextListenerUnsubscribeResponse")), null, 2); + } + + public static toCreatePrivateChannelRequest(json: string): CreatePrivateChannelRequest { + return cast(JSON.parse(json), r("CreatePrivateChannelRequest")); + } + + public static createPrivateChannelRequestToJson(value: CreatePrivateChannelRequest): string { + return JSON.stringify(uncast(value, r("CreatePrivateChannelRequest")), null, 2); + } + + public static toCreatePrivateChannelResponse(json: string): CreatePrivateChannelResponse { + return cast(JSON.parse(json), r("CreatePrivateChannelResponse")); + } + + public static createPrivateChannelResponseToJson(value: CreatePrivateChannelResponse): string { + return JSON.stringify(uncast(value, r("CreatePrivateChannelResponse")), null, 2); + } + + public static toEventListenerUnsubscribeRequest(json: string): EventListenerUnsubscribeRequest { + return cast(JSON.parse(json), r("EventListenerUnsubscribeRequest")); + } + + public static eventListenerUnsubscribeRequestToJson(value: EventListenerUnsubscribeRequest): string { + return JSON.stringify(uncast(value, r("EventListenerUnsubscribeRequest")), null, 2); + } + + public static toEventListenerUnsubscribeResponse(json: string): EventListenerUnsubscribeResponse { + return cast(JSON.parse(json), r("EventListenerUnsubscribeResponse")); + } + + public static eventListenerUnsubscribeResponseToJson(value: EventListenerUnsubscribeResponse): string { + return JSON.stringify(uncast(value, r("EventListenerUnsubscribeResponse")), null, 2); + } + + public static toFdc3UserInterfaceChannels(json: string): Fdc3UserInterfaceChannels { + return cast(JSON.parse(json), r("Fdc3UserInterfaceChannels")); + } + + public static fdc3UserInterfaceChannelsToJson(value: Fdc3UserInterfaceChannels): string { + return JSON.stringify(uncast(value, r("Fdc3UserInterfaceChannels")), null, 2); + } + + public static toFdc3UserInterfaceChannelSelected(json: string): Fdc3UserInterfaceChannelSelected { + return cast(JSON.parse(json), r("Fdc3UserInterfaceChannelSelected")); + } + + public static fdc3UserInterfaceChannelSelectedToJson(value: Fdc3UserInterfaceChannelSelected): string { + return JSON.stringify(uncast(value, r("Fdc3UserInterfaceChannelSelected")), null, 2); + } + + public static toFdc3UserInterfaceDrag(json: string): Fdc3UserInterfaceDrag { + return cast(JSON.parse(json), r("Fdc3UserInterfaceDrag")); + } + + public static fdc3UserInterfaceDragToJson(value: Fdc3UserInterfaceDrag): string { + return JSON.stringify(uncast(value, r("Fdc3UserInterfaceDrag")), null, 2); + } + + public static toFdc3UserInterfaceHandshake(json: string): Fdc3UserInterfaceHandshake { + return cast(JSON.parse(json), r("Fdc3UserInterfaceHandshake")); + } + + public static fdc3UserInterfaceHandshakeToJson(value: Fdc3UserInterfaceHandshake): string { + return JSON.stringify(uncast(value, r("Fdc3UserInterfaceHandshake")), null, 2); + } + + public static toFdc3UserInterfaceHello(json: string): Fdc3UserInterfaceHello { + return cast(JSON.parse(json), r("Fdc3UserInterfaceHello")); + } + + public static fdc3UserInterfaceHelloToJson(value: Fdc3UserInterfaceHello): string { + return JSON.stringify(uncast(value, r("Fdc3UserInterfaceHello")), null, 2); + } + + public static toFdc3UserInterfaceMessage(json: string): Fdc3UserInterfaceMessage { + return cast(JSON.parse(json), r("Fdc3UserInterfaceMessage")); + } + + public static fdc3UserInterfaceMessageToJson(value: Fdc3UserInterfaceMessage): string { + return JSON.stringify(uncast(value, r("Fdc3UserInterfaceMessage")), null, 2); + } + + public static toFdc3UserInterfaceResolve(json: string): Fdc3UserInterfaceResolve { + return cast(JSON.parse(json), r("Fdc3UserInterfaceResolve")); + } + + public static fdc3UserInterfaceResolveToJson(value: Fdc3UserInterfaceResolve): string { + return JSON.stringify(uncast(value, r("Fdc3UserInterfaceResolve")), null, 2); + } + + public static toFdc3UserInterfaceResolveAction(json: string): Fdc3UserInterfaceResolveAction { + return cast(JSON.parse(json), r("Fdc3UserInterfaceResolveAction")); + } + + public static fdc3UserInterfaceResolveActionToJson(value: Fdc3UserInterfaceResolveAction): string { + return JSON.stringify(uncast(value, r("Fdc3UserInterfaceResolveAction")), null, 2); + } + + public static toFdc3UserInterfaceRestyle(json: string): Fdc3UserInterfaceRestyle { + return cast(JSON.parse(json), r("Fdc3UserInterfaceRestyle")); + } + + public static fdc3UserInterfaceRestyleToJson(value: Fdc3UserInterfaceRestyle): string { + return JSON.stringify(uncast(value, r("Fdc3UserInterfaceRestyle")), null, 2); + } + + public static toFindInstancesRequest(json: string): FindInstancesRequest { + return cast(JSON.parse(json), r("FindInstancesRequest")); + } + + public static findInstancesRequestToJson(value: FindInstancesRequest): string { + return JSON.stringify(uncast(value, r("FindInstancesRequest")), null, 2); + } + + public static toFindInstancesResponse(json: string): FindInstancesResponse { + return cast(JSON.parse(json), r("FindInstancesResponse")); + } + + public static findInstancesResponseToJson(value: FindInstancesResponse): string { + return JSON.stringify(uncast(value, r("FindInstancesResponse")), null, 2); + } + + public static toFindIntentRequest(json: string): FindIntentRequest { + return cast(JSON.parse(json), r("FindIntentRequest")); + } + + public static findIntentRequestToJson(value: FindIntentRequest): string { + return JSON.stringify(uncast(value, r("FindIntentRequest")), null, 2); + } + + public static toFindIntentResponse(json: string): FindIntentResponse { + return cast(JSON.parse(json), r("FindIntentResponse")); + } + + public static findIntentResponseToJson(value: FindIntentResponse): string { + return JSON.stringify(uncast(value, r("FindIntentResponse")), null, 2); + } + + public static toFindIntentsByContextRequest(json: string): FindIntentsByContextRequest { + return cast(JSON.parse(json), r("FindIntentsByContextRequest")); + } + + public static findIntentsByContextRequestToJson(value: FindIntentsByContextRequest): string { + return JSON.stringify(uncast(value, r("FindIntentsByContextRequest")), null, 2); + } + + public static toFindIntentsByContextResponse(json: string): FindIntentsByContextResponse { + return cast(JSON.parse(json), r("FindIntentsByContextResponse")); + } + + public static findIntentsByContextResponseToJson(value: FindIntentsByContextResponse): string { + return JSON.stringify(uncast(value, r("FindIntentsByContextResponse")), null, 2); + } + + public static toGetAppMetadataRequest(json: string): GetAppMetadataRequest { + return cast(JSON.parse(json), r("GetAppMetadataRequest")); + } + + public static getAppMetadataRequestToJson(value: GetAppMetadataRequest): string { + return JSON.stringify(uncast(value, r("GetAppMetadataRequest")), null, 2); + } + + public static toGetAppMetadataResponse(json: string): GetAppMetadataResponse { + return cast(JSON.parse(json), r("GetAppMetadataResponse")); + } + + public static getAppMetadataResponseToJson(value: GetAppMetadataResponse): string { + return JSON.stringify(uncast(value, r("GetAppMetadataResponse")), null, 2); + } + + public static toGetCurrentChannelRequest(json: string): GetCurrentChannelRequest { + return cast(JSON.parse(json), r("GetCurrentChannelRequest")); + } + + public static getCurrentChannelRequestToJson(value: GetCurrentChannelRequest): string { + return JSON.stringify(uncast(value, r("GetCurrentChannelRequest")), null, 2); + } + + public static toGetCurrentChannelResponse(json: string): GetCurrentChannelResponse { + return cast(JSON.parse(json), r("GetCurrentChannelResponse")); + } + + public static getCurrentChannelResponseToJson(value: GetCurrentChannelResponse): string { + return JSON.stringify(uncast(value, r("GetCurrentChannelResponse")), null, 2); + } + + public static toGetCurrentContextRequest(json: string): GetCurrentContextRequest { + return cast(JSON.parse(json), r("GetCurrentContextRequest")); + } + + public static getCurrentContextRequestToJson(value: GetCurrentContextRequest): string { + return JSON.stringify(uncast(value, r("GetCurrentContextRequest")), null, 2); + } + + public static toGetCurrentContextResponse(json: string): GetCurrentContextResponse { + return cast(JSON.parse(json), r("GetCurrentContextResponse")); + } + + public static getCurrentContextResponseToJson(value: GetCurrentContextResponse): string { + return JSON.stringify(uncast(value, r("GetCurrentContextResponse")), null, 2); + } + + public static toGetInfoRequest(json: string): GetInfoRequest { + return cast(JSON.parse(json), r("GetInfoRequest")); + } + + public static getInfoRequestToJson(value: GetInfoRequest): string { + return JSON.stringify(uncast(value, r("GetInfoRequest")), null, 2); + } + + public static toGetInfoResponse(json: string): GetInfoResponse { + return cast(JSON.parse(json), r("GetInfoResponse")); + } + + public static getInfoResponseToJson(value: GetInfoResponse): string { + return JSON.stringify(uncast(value, r("GetInfoResponse")), null, 2); + } + + public static toGetOrCreateChannelRequest(json: string): GetOrCreateChannelRequest { + return cast(JSON.parse(json), r("GetOrCreateChannelRequest")); + } + + public static getOrCreateChannelRequestToJson(value: GetOrCreateChannelRequest): string { + return JSON.stringify(uncast(value, r("GetOrCreateChannelRequest")), null, 2); + } + + public static toGetOrCreateChannelResponse(json: string): GetOrCreateChannelResponse { + return cast(JSON.parse(json), r("GetOrCreateChannelResponse")); + } + + public static getOrCreateChannelResponseToJson(value: GetOrCreateChannelResponse): string { + return JSON.stringify(uncast(value, r("GetOrCreateChannelResponse")), null, 2); + } + + public static toGetUserChannelsRequest(json: string): GetUserChannelsRequest { + return cast(JSON.parse(json), r("GetUserChannelsRequest")); + } + + public static getUserChannelsRequestToJson(value: GetUserChannelsRequest): string { + return JSON.stringify(uncast(value, r("GetUserChannelsRequest")), null, 2); + } + + public static toGetUserChannelsResponse(json: string): GetUserChannelsResponse { + return cast(JSON.parse(json), r("GetUserChannelsResponse")); + } + + public static getUserChannelsResponseToJson(value: GetUserChannelsResponse): string { + return JSON.stringify(uncast(value, r("GetUserChannelsResponse")), null, 2); + } + + public static toHeartbeatAcknowledgementRequest(json: string): HeartbeatAcknowledgementRequest { + return cast(JSON.parse(json), r("HeartbeatAcknowledgementRequest")); + } + + public static heartbeatAcknowledgementRequestToJson(value: HeartbeatAcknowledgementRequest): string { + return JSON.stringify(uncast(value, r("HeartbeatAcknowledgementRequest")), null, 2); + } + + public static toHeartbeatEvent(json: string): HeartbeatEvent { + return cast(JSON.parse(json), r("HeartbeatEvent")); + } + + public static heartbeatEventToJson(value: HeartbeatEvent): string { + return JSON.stringify(uncast(value, r("HeartbeatEvent")), null, 2); + } + + public static toIntentEvent(json: string): IntentEvent { + return cast(JSON.parse(json), r("IntentEvent")); + } + + public static intentEventToJson(value: IntentEvent): string { + return JSON.stringify(uncast(value, r("IntentEvent")), null, 2); + } + + public static toIntentListenerUnsubscribeRequest(json: string): IntentListenerUnsubscribeRequest { + return cast(JSON.parse(json), r("IntentListenerUnsubscribeRequest")); + } + + public static intentListenerUnsubscribeRequestToJson(value: IntentListenerUnsubscribeRequest): string { + return JSON.stringify(uncast(value, r("IntentListenerUnsubscribeRequest")), null, 2); + } + + public static toIntentListenerUnsubscribeResponse(json: string): IntentListenerUnsubscribeResponse { + return cast(JSON.parse(json), r("IntentListenerUnsubscribeResponse")); + } + + public static intentListenerUnsubscribeResponseToJson(value: IntentListenerUnsubscribeResponse): string { + return JSON.stringify(uncast(value, r("IntentListenerUnsubscribeResponse")), null, 2); + } + + public static toIntentResultRequest(json: string): IntentResultRequest { + return cast(JSON.parse(json), r("IntentResultRequest")); + } + + public static intentResultRequestToJson(value: IntentResultRequest): string { + return JSON.stringify(uncast(value, r("IntentResultRequest")), null, 2); + } + + public static toIntentResultResponse(json: string): IntentResultResponse { + return cast(JSON.parse(json), r("IntentResultResponse")); + } + + public static intentResultResponseToJson(value: IntentResultResponse): string { + return JSON.stringify(uncast(value, r("IntentResultResponse")), null, 2); + } + + public static toJoinUserChannelRequest(json: string): JoinUserChannelRequest { + return cast(JSON.parse(json), r("JoinUserChannelRequest")); + } + + public static joinUserChannelRequestToJson(value: JoinUserChannelRequest): string { + return JSON.stringify(uncast(value, r("JoinUserChannelRequest")), null, 2); + } + + public static toJoinUserChannelResponse(json: string): JoinUserChannelResponse { + return cast(JSON.parse(json), r("JoinUserChannelResponse")); + } + + public static joinUserChannelResponseToJson(value: JoinUserChannelResponse): string { + return JSON.stringify(uncast(value, r("JoinUserChannelResponse")), null, 2); + } + + public static toLeaveCurrentChannelRequest(json: string): LeaveCurrentChannelRequest { + return cast(JSON.parse(json), r("LeaveCurrentChannelRequest")); + } + + public static leaveCurrentChannelRequestToJson(value: LeaveCurrentChannelRequest): string { + return JSON.stringify(uncast(value, r("LeaveCurrentChannelRequest")), null, 2); + } + + public static toLeaveCurrentChannelResponse(json: string): LeaveCurrentChannelResponse { + return cast(JSON.parse(json), r("LeaveCurrentChannelResponse")); + } + + public static leaveCurrentChannelResponseToJson(value: LeaveCurrentChannelResponse): string { + return JSON.stringify(uncast(value, r("LeaveCurrentChannelResponse")), null, 2); + } + + public static toOpenRequest(json: string): OpenRequest { + return cast(JSON.parse(json), r("OpenRequest")); + } + + public static openRequestToJson(value: OpenRequest): string { + return JSON.stringify(uncast(value, r("OpenRequest")), null, 2); + } + + public static toOpenResponse(json: string): OpenResponse { + return cast(JSON.parse(json), r("OpenResponse")); + } + + public static openResponseToJson(value: OpenResponse): string { + return JSON.stringify(uncast(value, r("OpenResponse")), null, 2); + } + + public static toPrivateChannelAddEventListenerRequest(json: string): PrivateChannelAddEventListenerRequest { + return cast(JSON.parse(json), r("PrivateChannelAddEventListenerRequest")); + } + + public static privateChannelAddEventListenerRequestToJson(value: PrivateChannelAddEventListenerRequest): string { + return JSON.stringify(uncast(value, r("PrivateChannelAddEventListenerRequest")), null, 2); + } + + public static toPrivateChannelAddEventListenerResponse(json: string): PrivateChannelAddEventListenerResponse { + return cast(JSON.parse(json), r("PrivateChannelAddEventListenerResponse")); + } + + public static privateChannelAddEventListenerResponseToJson(value: PrivateChannelAddEventListenerResponse): string { + return JSON.stringify(uncast(value, r("PrivateChannelAddEventListenerResponse")), null, 2); + } + + public static toPrivateChannelDisconnectRequest(json: string): PrivateChannelDisconnectRequest { + return cast(JSON.parse(json), r("PrivateChannelDisconnectRequest")); + } + + public static privateChannelDisconnectRequestToJson(value: PrivateChannelDisconnectRequest): string { + return JSON.stringify(uncast(value, r("PrivateChannelDisconnectRequest")), null, 2); + } + + public static toPrivateChannelDisconnectResponse(json: string): PrivateChannelDisconnectResponse { + return cast(JSON.parse(json), r("PrivateChannelDisconnectResponse")); + } + + public static privateChannelDisconnectResponseToJson(value: PrivateChannelDisconnectResponse): string { + return JSON.stringify(uncast(value, r("PrivateChannelDisconnectResponse")), null, 2); + } + + public static toPrivateChannelOnAddContextListenerEvent(json: string): PrivateChannelOnAddContextListenerEvent { + return cast(JSON.parse(json), r("PrivateChannelOnAddContextListenerEvent")); + } + + public static privateChannelOnAddContextListenerEventToJson(value: PrivateChannelOnAddContextListenerEvent): string { + return JSON.stringify(uncast(value, r("PrivateChannelOnAddContextListenerEvent")), null, 2); + } + + public static toPrivateChannelOnDisconnectEvent(json: string): PrivateChannelOnDisconnectEvent { + return cast(JSON.parse(json), r("PrivateChannelOnDisconnectEvent")); + } + + public static privateChannelOnDisconnectEventToJson(value: PrivateChannelOnDisconnectEvent): string { + return JSON.stringify(uncast(value, r("PrivateChannelOnDisconnectEvent")), null, 2); + } + + public static toPrivateChannelOnUnsubscribeEvent(json: string): PrivateChannelOnUnsubscribeEvent { + return cast(JSON.parse(json), r("PrivateChannelOnUnsubscribeEvent")); + } + + public static privateChannelOnUnsubscribeEventToJson(value: PrivateChannelOnUnsubscribeEvent): string { + return JSON.stringify(uncast(value, r("PrivateChannelOnUnsubscribeEvent")), null, 2); + } + + public static toPrivateChannelUnsubscribeEventListenerRequest(json: string): PrivateChannelUnsubscribeEventListenerRequest { + return cast(JSON.parse(json), r("PrivateChannelUnsubscribeEventListenerRequest")); + } + + public static privateChannelUnsubscribeEventListenerRequestToJson(value: PrivateChannelUnsubscribeEventListenerRequest): string { + return JSON.stringify(uncast(value, r("PrivateChannelUnsubscribeEventListenerRequest")), null, 2); + } + + public static toPrivateChannelUnsubscribeEventListenerResponse(json: string): PrivateChannelUnsubscribeEventListenerResponse { + return cast(JSON.parse(json), r("PrivateChannelUnsubscribeEventListenerResponse")); + } + + public static privateChannelUnsubscribeEventListenerResponseToJson(value: PrivateChannelUnsubscribeEventListenerResponse): string { + return JSON.stringify(uncast(value, r("PrivateChannelUnsubscribeEventListenerResponse")), null, 2); + } + + public static toRaiseIntentForContextRequest(json: string): RaiseIntentForContextRequest { + return cast(JSON.parse(json), r("RaiseIntentForContextRequest")); + } + + public static raiseIntentForContextRequestToJson(value: RaiseIntentForContextRequest): string { + return JSON.stringify(uncast(value, r("RaiseIntentForContextRequest")), null, 2); + } + + public static toRaiseIntentForContextResponse(json: string): RaiseIntentForContextResponse { + return cast(JSON.parse(json), r("RaiseIntentForContextResponse")); + } + + public static raiseIntentForContextResponseToJson(value: RaiseIntentForContextResponse): string { + return JSON.stringify(uncast(value, r("RaiseIntentForContextResponse")), null, 2); + } + + public static toRaiseIntentRequest(json: string): RaiseIntentRequest { + return cast(JSON.parse(json), r("RaiseIntentRequest")); + } + + public static raiseIntentRequestToJson(value: RaiseIntentRequest): string { + return JSON.stringify(uncast(value, r("RaiseIntentRequest")), null, 2); + } + + public static toRaiseIntentResponse(json: string): RaiseIntentResponse { + return cast(JSON.parse(json), r("RaiseIntentResponse")); + } + + public static raiseIntentResponseToJson(value: RaiseIntentResponse): string { + return JSON.stringify(uncast(value, r("RaiseIntentResponse")), null, 2); + } + + public static toRaiseIntentResultResponse(json: string): RaiseIntentResultResponse { + return cast(JSON.parse(json), r("RaiseIntentResultResponse")); + } + + public static raiseIntentResultResponseToJson(value: RaiseIntentResultResponse): string { + return JSON.stringify(uncast(value, r("RaiseIntentResultResponse")), null, 2); + } + + public static toWebConnectionProtocol1Hello(json: string): WebConnectionProtocol1Hello { + return cast(JSON.parse(json), r("WebConnectionProtocol1Hello")); + } + + public static webConnectionProtocol1HelloToJson(value: WebConnectionProtocol1Hello): string { + return JSON.stringify(uncast(value, r("WebConnectionProtocol1Hello")), null, 2); + } + + public static toWebConnectionProtocol2LoadURL(json: string): WebConnectionProtocol2LoadURL { + return cast(JSON.parse(json), r("WebConnectionProtocol2LoadURL")); + } + + public static webConnectionProtocol2LoadURLToJson(value: WebConnectionProtocol2LoadURL): string { + return JSON.stringify(uncast(value, r("WebConnectionProtocol2LoadURL")), null, 2); + } + + public static toWebConnectionProtocol3Handshake(json: string): WebConnectionProtocol3Handshake { + return cast(JSON.parse(json), r("WebConnectionProtocol3Handshake")); + } + + public static webConnectionProtocol3HandshakeToJson(value: WebConnectionProtocol3Handshake): string { + return JSON.stringify(uncast(value, r("WebConnectionProtocol3Handshake")), null, 2); + } + + public static toWebConnectionProtocol4ValidateAppIdentity(json: string): WebConnectionProtocol4ValidateAppIdentity { + return cast(JSON.parse(json), r("WebConnectionProtocol4ValidateAppIdentity")); + } + + public static webConnectionProtocol4ValidateAppIdentityToJson(value: WebConnectionProtocol4ValidateAppIdentity): string { + return JSON.stringify(uncast(value, r("WebConnectionProtocol4ValidateAppIdentity")), null, 2); + } + + public static toWebConnectionProtocol5ValidateAppIdentityFailedResponse(json: string): WebConnectionProtocol5ValidateAppIdentityFailedResponse { + return cast(JSON.parse(json), r("WebConnectionProtocol5ValidateAppIdentityFailedResponse")); + } + + public static webConnectionProtocol5ValidateAppIdentityFailedResponseToJson(value: WebConnectionProtocol5ValidateAppIdentityFailedResponse): string { + return JSON.stringify(uncast(value, r("WebConnectionProtocol5ValidateAppIdentityFailedResponse")), null, 2); + } + + public static toWebConnectionProtocol5ValidateAppIdentitySuccessResponse(json: string): WebConnectionProtocol5ValidateAppIdentitySuccessResponse { + return cast(JSON.parse(json), r("WebConnectionProtocol5ValidateAppIdentitySuccessResponse")); + } + + public static webConnectionProtocol5ValidateAppIdentitySuccessResponseToJson(value: WebConnectionProtocol5ValidateAppIdentitySuccessResponse): string { + return JSON.stringify(uncast(value, r("WebConnectionProtocol5ValidateAppIdentitySuccessResponse")), null, 2); + } + + public static toWebConnectionProtocol6Goodbye(json: string): WebConnectionProtocol6Goodbye { + return cast(JSON.parse(json), r("WebConnectionProtocol6Goodbye")); + } + + public static webConnectionProtocol6GoodbyeToJson(value: WebConnectionProtocol6Goodbye): string { + return JSON.stringify(uncast(value, r("WebConnectionProtocol6Goodbye")), null, 2); + } + + public static toWebConnectionProtocolMessage(json: string): WebConnectionProtocolMessage { + return cast(JSON.parse(json), r("WebConnectionProtocolMessage")); + } + + public static webConnectionProtocolMessageToJson(value: WebConnectionProtocolMessage): string { + return JSON.stringify(uncast(value, r("WebConnectionProtocolMessage")), null, 2); + } +} + +function invalidValue(typ: any, val: any, key: any, parent: any = ''): never { + const prettyTyp = prettyTypeName(typ); + const parentText = parent ? ` on ${parent}` : ''; + const keyText = key ? ` for key "${key}"` : ''; + throw Error(`Invalid value${keyText}${parentText}. Expected ${prettyTyp} but got ${JSON.stringify(val)}`); +} + +function prettyTypeName(typ: any): string { + if (Array.isArray(typ)) { + if (typ.length === 2 && typ[0] === undefined) { + return `an optional ${prettyTypeName(typ[1])}`; + } else { + return `one of [${typ.map(a => { return prettyTypeName(a); }).join(", ")}]`; + } + } else if (typeof typ === "object" && typ.literal !== undefined) { + return typ.literal; + } else { + return typeof typ; + } +} + +function jsonToJSProps(typ: any): any { + if (typ.jsonToJS === undefined) { + const map: any = {}; + typ.props.forEach((p: any) => map[p.json] = { key: p.js, typ: p.typ }); + typ.jsonToJS = map; + } + return typ.jsonToJS; +} + +function jsToJSONProps(typ: any): any { + if (typ.jsToJSON === undefined) { + const map: any = {}; + typ.props.forEach((p: any) => map[p.js] = { key: p.json, typ: p.typ }); + typ.jsToJSON = map; + } + return typ.jsToJSON; +} + +function transform(val: any, typ: any, getProps: any, key: any = '', parent: any = ''): any { + function transformPrimitive(typ: string, val: any): any { + if (typeof typ === typeof val) return val; + return invalidValue(typ, val, key, parent); + } + + function transformUnion(typs: any[], val: any): any { + // val must validate against one typ in typs + const l = typs.length; + for (let i = 0; i < l; i++) { + const typ = typs[i]; + try { + return transform(val, typ, getProps); + } catch (_) {} + } + return invalidValue(typs, val, key, parent); + } + + function transformEnum(cases: string[], val: any): any { + if (cases.indexOf(val) !== -1) return val; + return invalidValue(cases.map(a => { return l(a); }), val, key, parent); + } + + function transformArray(typ: any, val: any): any { + // val must be an array with no invalid elements + if (!Array.isArray(val)) return invalidValue(l("array"), val, key, parent); + return val.map(el => transform(el, typ, getProps)); + } + + function transformDate(val: any): any { + if (val === null) { + return null; + } + const d = new Date(val); + if (isNaN(d.valueOf())) { + return invalidValue(l("Date"), val, key, parent); + } + return d; + } + + function transformObject(props: { [k: string]: any }, additional: any, val: any): any { + if (val === null || typeof val !== "object" || Array.isArray(val)) { + return invalidValue(l(ref || "object"), val, key, parent); + } + const result: any = {}; + Object.getOwnPropertyNames(props).forEach(key => { + const prop = props[key]; + const v = Object.prototype.hasOwnProperty.call(val, key) ? val[key] : undefined; + result[prop.key] = transform(v, prop.typ, getProps, key, ref); + }); + Object.getOwnPropertyNames(val).forEach(key => { + if (!Object.prototype.hasOwnProperty.call(props, key)) { + result[key] = transform(val[key], additional, getProps, key, ref); + } + }); + return result; + } + + if (typ === "any") return val; + if (typ === null) { + if (val === null) return val; + return invalidValue(typ, val, key, parent); + } + if (typ === false) return invalidValue(typ, val, key, parent); + let ref: any = undefined; + while (typeof typ === "object" && typ.ref !== undefined) { + ref = typ.ref; + typ = typeMap[typ.ref]; + } + if (Array.isArray(typ)) return transformEnum(typ, val); + if (typeof typ === "object") { + return typ.hasOwnProperty("unionMembers") ? transformUnion(typ.unionMembers, val) + : typ.hasOwnProperty("arrayItems") ? transformArray(typ.arrayItems, val) + : typ.hasOwnProperty("props") ? transformObject(getProps(typ), typ.additional, val) + : invalidValue(typ, val, key, parent); + } + // Numbers can be parsed by Date but shouldn't be. + if (typ === Date && typeof val !== "number") return transformDate(val); + return transformPrimitive(typ, val); +} + +function cast(val: any, typ: any): T { + return transform(val, typ, jsonToJSProps); +} + +function uncast(val: T, typ: any): any { + return transform(val, typ, jsToJSONProps); +} + +function l(typ: any) { + return { literal: typ }; +} + +function a(typ: any) { + return { arrayItems: typ }; +} + +function u(...typs: any[]) { + return { unionMembers: typs }; +} + +function o(props: any[], additional: any) { + return { props, additional }; +} + +function m(additional: any) { + return { props: [], additional }; +} + +function r(name: string) { + return { ref: name }; +} + +const typeMap: any = { + "AddContextListenerRequest": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerRequestMeta") }, + { json: "payload", js: "payload", typ: r("AddContextListenerRequestPayload") }, + { json: "type", js: "type", typ: r("AddContextListenerRequestType") }, + ], false), + "AddContextListenerRequestMeta": o([ + { json: "requestUuid", js: "requestUuid", typ: "" }, + { json: "source", js: "source", typ: u(undefined, r("AppIdentifier")) }, + { json: "timestamp", js: "timestamp", typ: Date }, + ], false), + "AppIdentifier": o([ + { json: "appId", js: "appId", typ: "" }, + { json: "desktopAgent", js: "desktopAgent", typ: u(undefined, "") }, + { json: "instanceId", js: "instanceId", typ: u(undefined, "") }, + ], "any"), + "AddContextListenerRequestPayload": o([ + { json: "channelId", js: "channelId", typ: u(null, "") }, + { json: "contextType", js: "contextType", typ: u(null, "") }, + ], false), + "AddContextListenerResponse": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerResponseMeta") }, + { json: "payload", js: "payload", typ: r("AddContextListenerResponsePayload") }, + { json: "type", js: "type", typ: r("AddContextListenerResponseType") }, + ], false), + "AddContextListenerResponseMeta": o([ + { json: "requestUuid", js: "requestUuid", typ: "" }, + { json: "responseUuid", js: "responseUuid", typ: "" }, + { json: "source", js: "source", typ: u(undefined, r("AppIdentifier")) }, + { json: "timestamp", js: "timestamp", typ: Date }, + ], false), + "AddContextListenerResponsePayload": o([ + { json: "error", js: "error", typ: u(undefined, r("PurpleError")) }, + { json: "listenerUUID", js: "listenerUUID", typ: u(undefined, "") }, + ], false), + "AddEventListenerRequest": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerRequestMeta") }, + { json: "payload", js: "payload", typ: r("AddEventListenerRequestPayload") }, + { json: "type", js: "type", typ: r("AddEventListenerRequestType") }, + ], false), + "AddEventListenerRequestPayload": o([ + { json: "type", js: "type", typ: u(r("FDC3EventType"), null) }, + ], false), + "AddEventListenerResponse": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerResponseMeta") }, + { json: "payload", js: "payload", typ: r("AddEventListenerResponsePayload") }, + { json: "type", js: "type", typ: r("AddEventListenerResponseType") }, + ], false), + "AddEventListenerResponsePayload": o([ + { json: "error", js: "error", typ: u(undefined, r("ResponsePayloadError")) }, + { json: "listenerUUID", js: "listenerUUID", typ: u(undefined, "") }, + ], false), + "AddIntentListenerRequest": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerRequestMeta") }, + { json: "payload", js: "payload", typ: r("AddIntentListenerRequestPayload") }, + { json: "type", js: "type", typ: r("AddIntentListenerRequestType") }, + ], false), + "AddIntentListenerRequestPayload": o([ + { json: "intent", js: "intent", typ: "" }, + ], false), + "AddIntentListenerResponse": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerResponseMeta") }, + { json: "payload", js: "payload", typ: r("AddIntentListenerResponsePayload") }, + { json: "type", js: "type", typ: r("AddIntentListenerResponseType") }, + ], false), + "AddIntentListenerResponsePayload": o([ + { json: "error", js: "error", typ: u(undefined, r("FluffyError")) }, + { json: "listenerUUID", js: "listenerUUID", typ: u(undefined, "") }, + ], "any"), + "AgentEventMessage": o([ + { json: "meta", js: "meta", typ: r("AgentEventMessageMeta") }, + { json: "payload", js: "payload", typ: m("any") }, + { json: "type", js: "type", typ: r("EventMessageType") }, + ], false), + "AgentEventMessageMeta": o([ + { json: "eventUuid", js: "eventUuid", typ: "" }, + { json: "timestamp", js: "timestamp", typ: Date }, + ], false), + "AgentResponseMessage": o([ + { json: "meta", js: "meta", typ: r("AgentResponseMessageMeta") }, + { json: "payload", js: "payload", typ: r("AgentResponseMessageResponsePayload") }, + { json: "type", js: "type", typ: r("ResponseMessageType") }, + ], false), + "AgentResponseMessageMeta": o([ + { json: "requestUuid", js: "requestUuid", typ: "" }, + { json: "responseUuid", js: "responseUuid", typ: "" }, + { json: "source", js: "source", typ: u(undefined, r("AppIdentifier")) }, + { json: "timestamp", js: "timestamp", typ: Date }, + ], false), + "AgentResponseMessageResponsePayload": o([ + { json: "error", js: "error", typ: u(undefined, r("ResponsePayloadError")) }, + ], "any"), + "AppRequestMessage": o([ + { json: "meta", js: "meta", typ: r("AppRequestMessageMeta") }, + { json: "payload", js: "payload", typ: m("any") }, + { json: "type", js: "type", typ: r("RequestMessageType") }, + ], false), + "AppRequestMessageMeta": o([ + { json: "requestUuid", js: "requestUuid", typ: "" }, + { json: "source", js: "source", typ: u(undefined, r("AppIdentifier")) }, + { json: "timestamp", js: "timestamp", typ: Date }, + ], false), + "BroadcastEvent": o([ + { json: "meta", js: "meta", typ: r("BroadcastEventMeta") }, + { json: "payload", js: "payload", typ: r("BroadcastEventPayload") }, + { json: "type", js: "type", typ: r("BroadcastEventType") }, + ], false), + "BroadcastEventMeta": o([ + { json: "eventUuid", js: "eventUuid", typ: "" }, + { json: "timestamp", js: "timestamp", typ: Date }, + ], false), + "BroadcastEventPayload": o([ + { json: "channelId", js: "channelId", typ: u(null, "") }, + { json: "context", js: "context", typ: r("Context") }, + { json: "originatingApp", js: "originatingApp", typ: u(undefined, r("AppIdentifier")) }, + ], false), + "Context": o([ + { json: "id", js: "id", typ: u(undefined, m("any")) }, + { json: "name", js: "name", typ: u(undefined, "") }, + { json: "type", js: "type", typ: "" }, + ], "any"), + "BroadcastRequest": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerRequestMeta") }, + { json: "payload", js: "payload", typ: r("BroadcastRequestPayload") }, + { json: "type", js: "type", typ: r("BroadcastRequestType") }, + ], false), + "BroadcastRequestPayload": o([ + { json: "channelId", js: "channelId", typ: "" }, + { json: "context", js: "context", typ: r("Context") }, + ], false), + "BroadcastResponse": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerResponseMeta") }, + { json: "payload", js: "payload", typ: r("BroadcastResponseResponsePayload") }, + { json: "type", js: "type", typ: r("BroadcastResponseType") }, + ], false), + "BroadcastResponseResponsePayload": o([ + { json: "error", js: "error", typ: u(undefined, r("ResponsePayloadError")) }, + ], "any"), + "ChannelChangedEvent": o([ + { json: "meta", js: "meta", typ: r("BroadcastEventMeta") }, + { json: "payload", js: "payload", typ: r("ChannelChangedEventPayload") }, + { json: "type", js: "type", typ: r("ChannelChangedEventType") }, + ], false), + "ChannelChangedEventPayload": o([ + { json: "newChannelId", js: "newChannelId", typ: u(null, "") }, + ], false), + "ContextListenerUnsubscribeRequest": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerRequestMeta") }, + { json: "payload", js: "payload", typ: r("ContextListenerUnsubscribeRequestPayload") }, + { json: "type", js: "type", typ: r("ContextListenerUnsubscribeRequestType") }, + ], false), + "ContextListenerUnsubscribeRequestPayload": o([ + { json: "listenerUUID", js: "listenerUUID", typ: "" }, + ], false), + "ContextListenerUnsubscribeResponse": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerResponseMeta") }, + { json: "payload", js: "payload", typ: r("BroadcastResponseResponsePayload") }, + { json: "type", js: "type", typ: r("ContextListenerUnsubscribeResponseType") }, + ], false), + "CreatePrivateChannelRequest": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerRequestMeta") }, + { json: "payload", js: "payload", typ: r("CreatePrivateChannelRequestPayload") }, + { json: "type", js: "type", typ: r("CreatePrivateChannelRequestType") }, + ], false), + "CreatePrivateChannelRequestPayload": o([ + ], false), + "CreatePrivateChannelResponse": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerResponseMeta") }, + { json: "payload", js: "payload", typ: r("CreatePrivateChannelResponsePayload") }, + { json: "type", js: "type", typ: r("CreatePrivateChannelResponseType") }, + ], false), + "CreatePrivateChannelResponsePayload": o([ + { json: "error", js: "error", typ: u(undefined, r("PurpleError")) }, + { json: "privateChannel", js: "privateChannel", typ: u(undefined, r("Channel")) }, + ], false), + "Channel": o([ + { json: "displayMetadata", js: "displayMetadata", typ: u(undefined, r("DisplayMetadata")) }, + { json: "id", js: "id", typ: "" }, + { json: "type", js: "type", typ: r("Type") }, + ], false), + "DisplayMetadata": o([ + { json: "color", js: "color", typ: u(undefined, "") }, + { json: "glyph", js: "glyph", typ: u(undefined, "") }, + { json: "name", js: "name", typ: u(undefined, "") }, + ], false), + "EventListenerUnsubscribeRequest": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerRequestMeta") }, + { json: "payload", js: "payload", typ: r("EventListenerUnsubscribeRequestPayload") }, + { json: "type", js: "type", typ: r("EventListenerUnsubscribeRequestType") }, + ], false), + "EventListenerUnsubscribeRequestPayload": o([ + { json: "listenerUUID", js: "listenerUUID", typ: "" }, + ], false), + "EventListenerUnsubscribeResponse": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerResponseMeta") }, + { json: "payload", js: "payload", typ: r("BroadcastResponseResponsePayload") }, + { json: "type", js: "type", typ: r("EventListenerUnsubscribeResponseType") }, + ], false), + "Fdc3UserInterfaceChannels": o([ + { json: "payload", js: "payload", typ: r("Fdc3UserInterfaceChannelsPayload") }, + { json: "type", js: "type", typ: r("Fdc3UserInterfaceChannelsType") }, + ], false), + "Fdc3UserInterfaceChannelsPayload": o([ + { json: "selected", js: "selected", typ: u(null, "") }, + { json: "userChannels", js: "userChannels", typ: a(r("Channel")) }, + ], false), + "Fdc3UserInterfaceChannelSelected": o([ + { json: "payload", js: "payload", typ: r("Fdc3UserInterfaceChannelSelectedPayload") }, + { json: "type", js: "type", typ: r("Fdc3UserInterfaceChannelSelectedType") }, + ], false), + "Fdc3UserInterfaceChannelSelectedPayload": o([ + { json: "selected", js: "selected", typ: u(null, "") }, + ], false), + "Fdc3UserInterfaceDrag": o([ + { json: "payload", js: "payload", typ: r("Fdc3UserInterfaceDragPayload") }, + { json: "type", js: "type", typ: r("Fdc3UserInterfaceDragType") }, + ], false), + "Fdc3UserInterfaceDragPayload": o([ + { json: "mouseOffsets", js: "mouseOffsets", typ: r("MouseOffsets") }, + ], false), + "MouseOffsets": o([ + { json: "x", js: "x", typ: 0 }, + { json: "y", js: "y", typ: 0 }, + ], false), + "Fdc3UserInterfaceHandshake": o([ + { json: "payload", js: "payload", typ: r("Fdc3UserInterfaceHandshakePayload") }, + { json: "type", js: "type", typ: r("Fdc3UserInterfaceHandshakeType") }, + ], false), + "Fdc3UserInterfaceHandshakePayload": o([ + { json: "fdc3Version", js: "fdc3Version", typ: "" }, + ], false), + "Fdc3UserInterfaceHello": o([ + { json: "payload", js: "payload", typ: r("Fdc3UserInterfaceHelloPayload") }, + { json: "type", js: "type", typ: r("Fdc3UserInterfaceHelloType") }, + ], false), + "Fdc3UserInterfaceHelloPayload": o([ + { json: "implementationDetails", js: "implementationDetails", typ: "" }, + { json: "initialCSS", js: "initialCSS", typ: r("InitialCSS") }, + ], false), + "InitialCSS": o([ + { json: "bottom", js: "bottom", typ: u(undefined, "") }, + { json: "height", js: "height", typ: u(undefined, "") }, + { json: "left", js: "left", typ: u(undefined, "") }, + { json: "maxHeight", js: "maxHeight", typ: u(undefined, "") }, + { json: "maxWidth", js: "maxWidth", typ: u(undefined, "") }, + { json: "right", js: "right", typ: u(undefined, "") }, + { json: "top", js: "top", typ: u(undefined, "") }, + { json: "transition", js: "transition", typ: u(undefined, "") }, + { json: "width", js: "width", typ: u(undefined, "") }, + { json: "zIndex", js: "zIndex", typ: u(undefined, "") }, + ], "any"), + "Fdc3UserInterfaceMessage": o([ + { json: "payload", js: "payload", typ: u(undefined, m("any")) }, + { json: "type", js: "type", typ: r("Fdc3UserInterfaceMessageType") }, + ], false), + "Fdc3UserInterfaceResolve": o([ + { json: "payload", js: "payload", typ: r("Fdc3UserInterfaceResolvePayload") }, + { json: "type", js: "type", typ: r("Fdc3UserInterfaceResolveType") }, + ], false), + "Fdc3UserInterfaceResolvePayload": o([ + { json: "appIntents", js: "appIntents", typ: a(r("AppIntent")) }, + { json: "context", js: "context", typ: r("Context") }, + ], false), + "AppIntent": o([ + { json: "apps", js: "apps", typ: a(r("AppMetadata")) }, + { json: "intent", js: "intent", typ: r("IntentMetadata") }, + ], false), + "AppMetadata": o([ + { json: "appId", js: "appId", typ: "" }, + { json: "description", js: "description", typ: u(undefined, "") }, + { json: "desktopAgent", js: "desktopAgent", typ: u(undefined, "") }, + { json: "icons", js: "icons", typ: u(undefined, a(r("Icon"))) }, + { json: "instanceId", js: "instanceId", typ: u(undefined, "") }, + { json: "instanceMetadata", js: "instanceMetadata", typ: u(undefined, m("any")) }, + { json: "name", js: "name", typ: u(undefined, "") }, + { json: "resultType", js: "resultType", typ: u(undefined, u(null, "")) }, + { json: "screenshots", js: "screenshots", typ: u(undefined, a(r("Image"))) }, + { json: "title", js: "title", typ: u(undefined, "") }, + { json: "tooltip", js: "tooltip", typ: u(undefined, "") }, + { json: "version", js: "version", typ: u(undefined, "") }, + ], false), + "Icon": o([ + { json: "size", js: "size", typ: u(undefined, "") }, + { json: "src", js: "src", typ: "" }, + { json: "type", js: "type", typ: u(undefined, "") }, + ], false), + "Image": o([ + { json: "label", js: "label", typ: u(undefined, "") }, + { json: "size", js: "size", typ: u(undefined, "") }, + { json: "src", js: "src", typ: "" }, + { json: "type", js: "type", typ: u(undefined, "") }, + ], false), + "IntentMetadata": o([ + { json: "displayName", js: "displayName", typ: u(undefined, "") }, + { json: "name", js: "name", typ: "" }, + ], false), + "Fdc3UserInterfaceResolveAction": o([ + { json: "payload", js: "payload", typ: r("Fdc3UserInterfaceResolveActionPayload") }, + { json: "type", js: "type", typ: r("Fdc3UserInterfaceResolveActionType") }, + ], false), + "Fdc3UserInterfaceResolveActionPayload": o([ + { json: "action", js: "action", typ: r("Action") }, + { json: "appIdentifier", js: "appIdentifier", typ: u(undefined, r("AppIdentifier")) }, + { json: "intent", js: "intent", typ: u(undefined, "") }, + ], false), + "Fdc3UserInterfaceRestyle": o([ + { json: "payload", js: "payload", typ: r("Fdc3UserInterfaceRestylePayload") }, + { json: "type", js: "type", typ: r("Fdc3UserInterfaceRestyleType") }, + ], false), + "Fdc3UserInterfaceRestylePayload": o([ + { json: "updatedCSS", js: "updatedCSS", typ: r("UpdatedCSS") }, + ], false), + "UpdatedCSS": o([ + { json: "bottom", js: "bottom", typ: u(undefined, "") }, + { json: "height", js: "height", typ: u(undefined, "") }, + { json: "left", js: "left", typ: u(undefined, "") }, + { json: "maxHeight", js: "maxHeight", typ: u(undefined, "") }, + { json: "maxWidth", js: "maxWidth", typ: u(undefined, "") }, + { json: "right", js: "right", typ: u(undefined, "") }, + { json: "top", js: "top", typ: u(undefined, "") }, + { json: "transition", js: "transition", typ: u(undefined, "") }, + { json: "width", js: "width", typ: u(undefined, "") }, + { json: "zIndex", js: "zIndex", typ: u(undefined, "") }, + ], "any"), + "FindInstancesRequest": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerRequestMeta") }, + { json: "payload", js: "payload", typ: r("FindInstancesRequestPayload") }, + { json: "type", js: "type", typ: r("FindInstancesRequestType") }, + ], false), + "FindInstancesRequestPayload": o([ + { json: "app", js: "app", typ: r("AppIdentifier") }, + ], false), + "FindInstancesResponse": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerResponseMeta") }, + { json: "payload", js: "payload", typ: r("FindInstancesResponsePayload") }, + { json: "type", js: "type", typ: r("FindInstancesResponseType") }, + ], false), + "FindInstancesResponsePayload": o([ + { json: "error", js: "error", typ: u(undefined, r("FindInstancesErrors")) }, + { json: "appIdentifiers", js: "appIdentifiers", typ: u(undefined, a(r("AppMetadata"))) }, + ], false), + "FindIntentRequest": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerRequestMeta") }, + { json: "payload", js: "payload", typ: r("FindIntentRequestPayload") }, + { json: "type", js: "type", typ: r("FindIntentRequestType") }, + ], false), + "FindIntentRequestPayload": o([ + { json: "context", js: "context", typ: u(undefined, r("Context")) }, + { json: "intent", js: "intent", typ: "" }, + { json: "resultType", js: "resultType", typ: u(undefined, "") }, + ], false), + "FindIntentResponse": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerResponseMeta") }, + { json: "payload", js: "payload", typ: r("FindIntentResponsePayload") }, + { json: "type", js: "type", typ: r("FindIntentResponseType") }, + ], false), + "FindIntentResponsePayload": o([ + { json: "error", js: "error", typ: u(undefined, r("FindInstancesErrors")) }, + { json: "appIntent", js: "appIntent", typ: u(undefined, r("AppIntent")) }, + ], false), + "FindIntentsByContextRequest": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerRequestMeta") }, + { json: "payload", js: "payload", typ: r("FindIntentsByContextRequestPayload") }, + { json: "type", js: "type", typ: r("FindIntentsByContextRequestType") }, + ], false), + "FindIntentsByContextRequestPayload": o([ + { json: "context", js: "context", typ: r("Context") }, + { json: "resultType", js: "resultType", typ: u(undefined, "") }, + ], false), + "FindIntentsByContextResponse": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerResponseMeta") }, + { json: "payload", js: "payload", typ: r("FindIntentsByContextResponsePayload") }, + { json: "type", js: "type", typ: r("FindIntentsByContextResponseType") }, + ], false), + "FindIntentsByContextResponsePayload": o([ + { json: "error", js: "error", typ: u(undefined, r("FindInstancesErrors")) }, + { json: "appIntents", js: "appIntents", typ: u(undefined, a(r("AppIntent"))) }, + ], false), + "GetAppMetadataRequest": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerRequestMeta") }, + { json: "payload", js: "payload", typ: r("GetAppMetadataRequestPayload") }, + { json: "type", js: "type", typ: r("GetAppMetadataRequestType") }, + ], false), + "GetAppMetadataRequestPayload": o([ + { json: "app", js: "app", typ: r("AppIdentifier") }, + ], false), + "GetAppMetadataResponse": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerResponseMeta") }, + { json: "payload", js: "payload", typ: r("GetAppMetadataResponsePayload") }, + { json: "type", js: "type", typ: r("GetAppMetadataResponseType") }, + ], false), + "GetAppMetadataResponsePayload": o([ + { json: "error", js: "error", typ: u(undefined, r("FindInstancesErrors")) }, + { json: "appMetadata", js: "appMetadata", typ: u(undefined, r("AppMetadata")) }, + ], false), + "GetCurrentChannelRequest": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerRequestMeta") }, + { json: "payload", js: "payload", typ: r("GetCurrentChannelRequestPayload") }, + { json: "type", js: "type", typ: r("GetCurrentChannelRequestType") }, + ], false), + "GetCurrentChannelRequestPayload": o([ + ], false), + "GetCurrentChannelResponse": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerResponseMeta") }, + { json: "payload", js: "payload", typ: r("GetCurrentChannelResponsePayload") }, + { json: "type", js: "type", typ: r("GetCurrentChannelResponseType") }, + ], false), + "GetCurrentChannelResponsePayload": o([ + { json: "error", js: "error", typ: u(undefined, r("ResponsePayloadError")) }, + { json: "channel", js: "channel", typ: u(undefined, u(r("Channel"), null)) }, + ], false), + "GetCurrentContextRequest": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerRequestMeta") }, + { json: "payload", js: "payload", typ: r("GetCurrentContextRequestPayload") }, + { json: "type", js: "type", typ: r("GetCurrentContextRequestType") }, + ], false), + "GetCurrentContextRequestPayload": o([ + { json: "channelId", js: "channelId", typ: "" }, + { json: "contextType", js: "contextType", typ: u(null, "") }, + ], false), + "GetCurrentContextResponse": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerResponseMeta") }, + { json: "payload", js: "payload", typ: r("GetCurrentContextResponsePayload") }, + { json: "type", js: "type", typ: r("GetCurrentContextResponseType") }, + ], false), + "GetCurrentContextResponsePayload": o([ + { json: "error", js: "error", typ: u(undefined, r("PurpleError")) }, + { json: "context", js: "context", typ: u(undefined, u(null, r("Context"))) }, + ], false), + "GetInfoRequest": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerRequestMeta") }, + { json: "payload", js: "payload", typ: r("GetInfoRequestPayload") }, + { json: "type", js: "type", typ: r("GetInfoRequestType") }, + ], false), + "GetInfoRequestPayload": o([ + ], false), + "GetInfoResponse": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerResponseMeta") }, + { json: "payload", js: "payload", typ: r("GetInfoResponsePayload") }, + { json: "type", js: "type", typ: r("GetInfoResponseType") }, + ], false), + "GetInfoResponsePayload": o([ + { json: "error", js: "error", typ: u(undefined, r("ResponsePayloadError")) }, + { json: "implementationMetadata", js: "implementationMetadata", typ: u(undefined, r("ImplementationMetadata")) }, + ], false), + "ImplementationMetadata": o([ + { json: "appMetadata", js: "appMetadata", typ: r("AppMetadata") }, + { json: "fdc3Version", js: "fdc3Version", typ: "" }, + { json: "optionalFeatures", js: "optionalFeatures", typ: r("OptionalFeatures") }, + { json: "provider", js: "provider", typ: "" }, + { json: "providerVersion", js: "providerVersion", typ: u(undefined, "") }, + ], false), + "OptionalFeatures": o([ + { json: "DesktopAgentBridging", js: "DesktopAgentBridging", typ: true }, + { json: "OriginatingAppMetadata", js: "OriginatingAppMetadata", typ: true }, + { json: "UserChannelMembershipAPIs", js: "UserChannelMembershipAPIs", typ: true }, + ], false), + "GetOrCreateChannelRequest": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerRequestMeta") }, + { json: "payload", js: "payload", typ: r("GetOrCreateChannelRequestPayload") }, + { json: "type", js: "type", typ: r("GetOrCreateChannelRequestType") }, + ], false), + "GetOrCreateChannelRequestPayload": o([ + { json: "channelId", js: "channelId", typ: "" }, + ], false), + "GetOrCreateChannelResponse": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerResponseMeta") }, + { json: "payload", js: "payload", typ: r("GetOrCreateChannelResponsePayload") }, + { json: "type", js: "type", typ: r("GetOrCreateChannelResponseType") }, + ], false), + "GetOrCreateChannelResponsePayload": o([ + { json: "error", js: "error", typ: u(undefined, r("PurpleError")) }, + { json: "channel", js: "channel", typ: u(undefined, r("Channel")) }, + ], false), + "GetUserChannelsRequest": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerRequestMeta") }, + { json: "payload", js: "payload", typ: r("GetUserChannelsRequestPayload") }, + { json: "type", js: "type", typ: r("GetUserChannelsRequestType") }, + ], false), + "GetUserChannelsRequestPayload": o([ + ], false), + "GetUserChannelsResponse": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerResponseMeta") }, + { json: "payload", js: "payload", typ: r("GetUserChannelsResponsePayload") }, + { json: "type", js: "type", typ: r("GetUserChannelsResponseType") }, + ], false), + "GetUserChannelsResponsePayload": o([ + { json: "error", js: "error", typ: u(undefined, r("PurpleError")) }, + { json: "userChannels", js: "userChannels", typ: u(undefined, a(r("Channel"))) }, + ], false), + "HeartbeatAcknowledgementRequest": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerRequestMeta") }, + { json: "payload", js: "payload", typ: r("HeartbeatAcknowledgementRequestPayload") }, + { json: "type", js: "type", typ: r("HeartbeatAcknowledgementRequestType") }, + ], false), + "HeartbeatAcknowledgementRequestPayload": o([ + { json: "heartbeatEventUuid", js: "heartbeatEventUuid", typ: "" }, + ], false), + "HeartbeatEvent": o([ + { json: "meta", js: "meta", typ: r("BroadcastEventMeta") }, + { json: "payload", js: "payload", typ: r("HeartbeatEventPayload") }, + { json: "type", js: "type", typ: r("HeartbeatEventType") }, + ], false), + "HeartbeatEventPayload": o([ + ], false), + "IntentEvent": o([ + { json: "meta", js: "meta", typ: r("BroadcastEventMeta") }, + { json: "payload", js: "payload", typ: r("IntentEventPayload") }, + { json: "type", js: "type", typ: r("IntentEventType") }, + ], false), + "IntentEventPayload": o([ + { json: "context", js: "context", typ: r("Context") }, + { json: "intent", js: "intent", typ: "" }, + { json: "originatingApp", js: "originatingApp", typ: u(undefined, r("AppIdentifier")) }, + { json: "raiseIntentRequestUuid", js: "raiseIntentRequestUuid", typ: "" }, + ], false), + "IntentListenerUnsubscribeRequest": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerRequestMeta") }, + { json: "payload", js: "payload", typ: r("IntentListenerUnsubscribeRequestPayload") }, + { json: "type", js: "type", typ: r("IntentListenerUnsubscribeRequestType") }, + ], false), + "IntentListenerUnsubscribeRequestPayload": o([ + { json: "listenerUUID", js: "listenerUUID", typ: "" }, + ], false), + "IntentListenerUnsubscribeResponse": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerResponseMeta") }, + { json: "payload", js: "payload", typ: r("BroadcastResponseResponsePayload") }, + { json: "type", js: "type", typ: r("IntentListenerUnsubscribeResponseType") }, + ], false), + "IntentResultRequest": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerRequestMeta") }, + { json: "payload", js: "payload", typ: r("IntentResultRequestPayload") }, + { json: "type", js: "type", typ: r("IntentResultRequestType") }, + ], false), + "IntentResultRequestPayload": o([ + { json: "intentEventUuid", js: "intentEventUuid", typ: "" }, + { json: "intentResult", js: "intentResult", typ: r("IntentResult") }, + { json: "raiseIntentRequestUuid", js: "raiseIntentRequestUuid", typ: "" }, + ], false), + "IntentResult": o([ + { json: "context", js: "context", typ: u(undefined, r("Context")) }, + { json: "channel", js: "channel", typ: u(undefined, r("Channel")) }, + ], false), + "IntentResultResponse": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerResponseMeta") }, + { json: "payload", js: "payload", typ: r("BroadcastResponseResponsePayload") }, + { json: "type", js: "type", typ: r("IntentResultResponseType") }, + ], false), + "JoinUserChannelRequest": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerRequestMeta") }, + { json: "payload", js: "payload", typ: r("JoinUserChannelRequestPayload") }, + { json: "type", js: "type", typ: r("JoinUserChannelRequestType") }, + ], false), + "JoinUserChannelRequestPayload": o([ + { json: "channelId", js: "channelId", typ: "" }, + ], false), + "JoinUserChannelResponse": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerResponseMeta") }, + { json: "payload", js: "payload", typ: r("JoinUserChannelResponsePayload") }, + { json: "type", js: "type", typ: r("JoinUserChannelResponseType") }, + ], false), + "JoinUserChannelResponsePayload": o([ + { json: "error", js: "error", typ: u(undefined, r("PurpleError")) }, + ], false), + "LeaveCurrentChannelRequest": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerRequestMeta") }, + { json: "payload", js: "payload", typ: r("LeaveCurrentChannelRequestPayload") }, + { json: "type", js: "type", typ: r("LeaveCurrentChannelRequestType") }, + ], false), + "LeaveCurrentChannelRequestPayload": o([ + ], false), + "LeaveCurrentChannelResponse": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerResponseMeta") }, + { json: "payload", js: "payload", typ: r("LeaveCurrentChannelResponsePayload") }, + { json: "type", js: "type", typ: r("LeaveCurrentChannelResponseType") }, + ], false), + "LeaveCurrentChannelResponsePayload": o([ + { json: "error", js: "error", typ: u(undefined, r("PurpleError")) }, + ], false), + "OpenRequest": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerRequestMeta") }, + { json: "payload", js: "payload", typ: r("OpenRequestPayload") }, + { json: "type", js: "type", typ: r("OpenRequestType") }, + ], false), + "OpenRequestPayload": o([ + { json: "app", js: "app", typ: r("AppIdentifier") }, + { json: "context", js: "context", typ: u(undefined, r("Context")) }, + ], false), + "OpenResponse": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerResponseMeta") }, + { json: "payload", js: "payload", typ: r("OpenResponsePayload") }, + { json: "type", js: "type", typ: r("OpenResponseType") }, + ], false), + "OpenResponsePayload": o([ + { json: "error", js: "error", typ: u(undefined, r("OpenErrorResponsePayload")) }, + { json: "appIdentifier", js: "appIdentifier", typ: u(undefined, r("AppIdentifier")) }, + ], false), + "PrivateChannelAddEventListenerRequest": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerRequestMeta") }, + { json: "payload", js: "payload", typ: r("TPayload") }, + { json: "type", js: "type", typ: r("PrivateChannelAddEventListenerRequestType") }, + ], false), + "TPayload": o([ + { json: "listenerType", js: "listenerType", typ: r("PrivateChannelEventListenerTypes") }, + { json: "privateChannelId", js: "privateChannelId", typ: "" }, + ], false), + "PrivateChannelAddEventListenerResponse": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerResponseMeta") }, + { json: "payload", js: "payload", typ: r("PrivateChannelAddEventListenerResponsePayload") }, + { json: "type", js: "type", typ: r("PrivateChannelAddEventListenerResponseType") }, + ], false), + "PrivateChannelAddEventListenerResponsePayload": o([ + { json: "error", js: "error", typ: u(undefined, r("PurpleError")) }, + { json: "listenerUUID", js: "listenerUUID", typ: u(undefined, "") }, + ], "any"), + "PrivateChannelDisconnectRequest": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerRequestMeta") }, + { json: "payload", js: "payload", typ: r("PrivateChannelDisconnectRequestPayload") }, + { json: "type", js: "type", typ: r("PrivateChannelDisconnectRequestType") }, + ], false), + "PrivateChannelDisconnectRequestPayload": o([ + { json: "channelId", js: "channelId", typ: "" }, + ], false), + "PrivateChannelDisconnectResponse": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerResponseMeta") }, + { json: "payload", js: "payload", typ: r("PrivateChannelDisconnectResponsePayload") }, + { json: "type", js: "type", typ: r("PrivateChannelDisconnectResponseType") }, + ], false), + "PrivateChannelDisconnectResponsePayload": o([ + { json: "error", js: "error", typ: u(undefined, r("PurpleError")) }, + ], false), + "PrivateChannelOnAddContextListenerEvent": o([ + { json: "meta", js: "meta", typ: r("BroadcastEventMeta") }, + { json: "payload", js: "payload", typ: r("PrivateChannelOnAddContextListenerEventPayload") }, + { json: "type", js: "type", typ: r("PrivateChannelOnAddContextListenerEventType") }, + ], false), + "PrivateChannelOnAddContextListenerEventPayload": o([ + { json: "contextType", js: "contextType", typ: u(null, "") }, + { json: "privateChannelId", js: "privateChannelId", typ: "" }, + ], false), + "PrivateChannelOnDisconnectEvent": o([ + { json: "meta", js: "meta", typ: r("BroadcastEventMeta") }, + { json: "payload", js: "payload", typ: r("PrivateChannelOnDisconnectEventPayload") }, + { json: "type", js: "type", typ: r("PrivateChannelOnDisconnectEventType") }, + ], false), + "PrivateChannelOnDisconnectEventPayload": o([ + { json: "privateChannelId", js: "privateChannelId", typ: "" }, + ], false), + "PrivateChannelOnUnsubscribeEvent": o([ + { json: "meta", js: "meta", typ: r("BroadcastEventMeta") }, + { json: "payload", js: "payload", typ: r("PrivateChannelOnUnsubscribeEventPayload") }, + { json: "type", js: "type", typ: r("PrivateChannelOnUnsubscribeEventType") }, + ], false), + "PrivateChannelOnUnsubscribeEventPayload": o([ + { json: "contextType", js: "contextType", typ: u(null, "") }, + { json: "privateChannelId", js: "privateChannelId", typ: "" }, + ], false), + "PrivateChannelUnsubscribeEventListenerRequest": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerRequestMeta") }, + { json: "payload", js: "payload", typ: r("PrivateChannelUnsubscribeEventListenerRequestPayload") }, + { json: "type", js: "type", typ: r("PrivateChannelUnsubscribeEventListenerRequestType") }, + ], false), + "PrivateChannelUnsubscribeEventListenerRequestPayload": o([ + { json: "listenerUUID", js: "listenerUUID", typ: "" }, + ], false), + "PrivateChannelUnsubscribeEventListenerResponse": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerResponseMeta") }, + { json: "payload", js: "payload", typ: r("BroadcastResponseResponsePayload") }, + { json: "type", js: "type", typ: r("PrivateChannelUnsubscribeEventListenerResponseType") }, + ], false), + "RaiseIntentForContextRequest": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerRequestMeta") }, + { json: "payload", js: "payload", typ: r("RaiseIntentForContextRequestPayload") }, + { json: "type", js: "type", typ: r("RaiseIntentForContextRequestType") }, + ], false), + "RaiseIntentForContextRequestPayload": o([ + { json: "app", js: "app", typ: u(undefined, r("AppIdentifier")) }, + { json: "context", js: "context", typ: r("Context") }, + ], false), + "RaiseIntentForContextResponse": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerResponseMeta") }, + { json: "payload", js: "payload", typ: r("RaiseIntentForContextResponsePayload") }, + { json: "type", js: "type", typ: r("RaiseIntentForContextResponseType") }, + ], false), + "RaiseIntentForContextResponsePayload": o([ + { json: "error", js: "error", typ: u(undefined, r("FindInstancesErrors")) }, + { json: "intentResolution", js: "intentResolution", typ: u(undefined, r("IntentResolution")) }, + { json: "appIntents", js: "appIntents", typ: u(undefined, a(r("AppIntent"))) }, + ], false), + "IntentResolution": o([ + { json: "intent", js: "intent", typ: "" }, + { json: "source", js: "source", typ: r("AppIdentifier") }, + ], false), + "RaiseIntentRequest": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerRequestMeta") }, + { json: "payload", js: "payload", typ: r("RaiseIntentRequestPayload") }, + { json: "type", js: "type", typ: r("RaiseIntentRequestType") }, + ], false), + "RaiseIntentRequestPayload": o([ + { json: "app", js: "app", typ: u(undefined, r("AppIdentifier")) }, + { json: "context", js: "context", typ: r("Context") }, + { json: "intent", js: "intent", typ: "" }, + ], false), + "RaiseIntentResponse": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerResponseMeta") }, + { json: "payload", js: "payload", typ: r("RaiseIntentResponsePayload") }, + { json: "type", js: "type", typ: r("RaiseIntentResponseType") }, + ], false), + "RaiseIntentResponsePayload": o([ + { json: "error", js: "error", typ: u(undefined, r("FindInstancesErrors")) }, + { json: "intentResolution", js: "intentResolution", typ: u(undefined, r("IntentResolution")) }, + { json: "appIntent", js: "appIntent", typ: u(undefined, r("AppIntent")) }, + ], false), + "RaiseIntentResultResponse": o([ + { json: "meta", js: "meta", typ: r("AddContextListenerResponseMeta") }, + { json: "payload", js: "payload", typ: r("RaiseIntentResultResponsePayload") }, + { json: "type", js: "type", typ: r("RaiseIntentResultResponseType") }, + ], false), + "RaiseIntentResultResponsePayload": o([ + { json: "error", js: "error", typ: u(undefined, r("ResponsePayloadError")) }, + { json: "intentResult", js: "intentResult", typ: u(undefined, r("IntentResult")) }, + ], false), + "WebConnectionProtocol1Hello": o([ + { json: "meta", js: "meta", typ: r("WebConnectionProtocol1HelloMeta") }, + { json: "payload", js: "payload", typ: r("WebConnectionProtocol1HelloPayload") }, + { json: "type", js: "type", typ: r("WebConnectionProtocol1HelloType") }, + ], false), + "WebConnectionProtocol1HelloMeta": o([ + { json: "connectionAttemptUuid", js: "connectionAttemptUuid", typ: "" }, + { json: "timestamp", js: "timestamp", typ: Date }, + ], false), + "WebConnectionProtocol1HelloPayload": o([ + { json: "actualUrl", js: "actualUrl", typ: "" }, + { json: "channelSelector", js: "channelSelector", typ: u(undefined, true) }, + { json: "fdc3Version", js: "fdc3Version", typ: "" }, + { json: "identityUrl", js: "identityUrl", typ: "" }, + { json: "intentResolver", js: "intentResolver", typ: u(undefined, true) }, + ], "any"), + "WebConnectionProtocol2LoadURL": o([ + { json: "meta", js: "meta", typ: r("WebConnectionProtocol1HelloMeta") }, + { json: "payload", js: "payload", typ: r("WebConnectionProtocol2LoadURLPayload") }, + { json: "type", js: "type", typ: r("WebConnectionProtocol2LoadURLType") }, + ], false), + "WebConnectionProtocol2LoadURLPayload": o([ + { json: "iframeUrl", js: "iframeUrl", typ: "" }, + ], "any"), + "WebConnectionProtocol3Handshake": o([ + { json: "meta", js: "meta", typ: r("WebConnectionProtocol1HelloMeta") }, + { json: "payload", js: "payload", typ: r("WebConnectionProtocol3HandshakePayload") }, + { json: "type", js: "type", typ: r("WebConnectionProtocol3HandshakeType") }, + ], false), + "WebConnectionProtocol3HandshakePayload": o([ + { json: "channelSelectorUrl", js: "channelSelectorUrl", typ: u(true, "") }, + { json: "fdc3Version", js: "fdc3Version", typ: "" }, + { json: "intentResolverUrl", js: "intentResolverUrl", typ: u(true, "") }, + ], false), + "WebConnectionProtocol4ValidateAppIdentity": o([ + { json: "meta", js: "meta", typ: r("WebConnectionProtocol1HelloMeta") }, + { json: "payload", js: "payload", typ: r("WebConnectionProtocol4ValidateAppIdentityPayload") }, + { json: "type", js: "type", typ: r("WebConnectionProtocol4ValidateAppIdentityType") }, + ], false), + "WebConnectionProtocol4ValidateAppIdentityPayload": o([ + { json: "actualUrl", js: "actualUrl", typ: "" }, + { json: "identityUrl", js: "identityUrl", typ: "" }, + { json: "instanceId", js: "instanceId", typ: u(undefined, "") }, + { json: "instanceUuid", js: "instanceUuid", typ: u(undefined, "") }, + ], false), + "WebConnectionProtocol5ValidateAppIdentityFailedResponse": o([ + { json: "meta", js: "meta", typ: r("WebConnectionProtocol1HelloMeta") }, + { json: "payload", js: "payload", typ: r("WebConnectionProtocol5ValidateAppIdentityFailedResponsePayload") }, + { json: "type", js: "type", typ: r("WebConnectionProtocol5ValidateAppIdentityFailedResponseType") }, + ], false), + "WebConnectionProtocol5ValidateAppIdentityFailedResponsePayload": o([ + { json: "message", js: "message", typ: u(undefined, "") }, + ], false), + "WebConnectionProtocol5ValidateAppIdentitySuccessResponse": o([ + { json: "meta", js: "meta", typ: r("WebConnectionProtocol1HelloMeta") }, + { json: "payload", js: "payload", typ: r("WebConnectionProtocol5ValidateAppIdentitySuccessResponsePayload") }, + { json: "type", js: "type", typ: r("WebConnectionProtocol5ValidateAppIdentitySuccessResponseType") }, + ], false), + "WebConnectionProtocol5ValidateAppIdentitySuccessResponsePayload": o([ + { json: "appId", js: "appId", typ: "" }, + { json: "implementationMetadata", js: "implementationMetadata", typ: r("ImplementationMetadata") }, + { json: "instanceId", js: "instanceId", typ: "" }, + { json: "instanceUuid", js: "instanceUuid", typ: "" }, + ], false), + "WebConnectionProtocol6Goodbye": o([ + { json: "meta", js: "meta", typ: r("WebConnectionProtocol6GoodbyeMeta") }, + { json: "type", js: "type", typ: r("WebConnectionProtocol6GoodbyeType") }, + ], false), + "WebConnectionProtocol6GoodbyeMeta": o([ + { json: "timestamp", js: "timestamp", typ: Date }, + ], false), + "WebConnectionProtocolMessage": o([ + { json: "meta", js: "meta", typ: r("WebConnectionProtocolMessageMeta") }, + { json: "payload", js: "payload", typ: u(undefined, m("any")) }, + { json: "type", js: "type", typ: r("ConnectionStepMessageType") }, + ], false), + "WebConnectionProtocolMessageMeta": o([ + { json: "timestamp", js: "timestamp", typ: Date }, + { json: "connectionAttemptUuid", js: "connectionAttemptUuid", typ: u(undefined, "") }, + ], false), + "AddContextListenerRequestType": [ + "addContextListenerRequest", + ], + "PurpleError": [ + "AccessDenied", + "CreationFailed", + "MalformedContext", + "NoChannelFound", + ], + "AddContextListenerResponseType": [ + "addContextListenerResponse", + ], + "FDC3EventType": [ + "USER_CHANNEL_CHANGED", + ], + "AddEventListenerRequestType": [ + "addEventListenerRequest", + ], + "ResponsePayloadError": [ + "AccessDenied", + "AgentDisconnected", + "AppNotFound", + "AppTimeout", + "CreationFailed", + "DesktopAgentNotFound", + "ErrorOnLaunch", + "IntentDeliveryFailed", + "IntentHandlerRejected", + "MalformedContext", + "MalformedMessage", + "NoAppsFound", + "NoChannelFound", + "NoResultReturned", + "NotConnectedToBridge", + "ResolverTimeout", + "ResolverUnavailable", + "ResponseToBridgeTimedOut", + "TargetAppUnavailable", + "TargetInstanceUnavailable", + "UserCancelledResolution", + ], + "AddEventListenerResponseType": [ + "addEventListenerResponse", + ], + "AddIntentListenerRequestType": [ + "addIntentListenerRequest", + ], + "FluffyError": [ + "DesktopAgentNotFound", + "IntentDeliveryFailed", + "MalformedContext", + "NoAppsFound", + "ResolverTimeout", + "ResolverUnavailable", + "TargetAppUnavailable", + "TargetInstanceUnavailable", + "UserCancelledResolution", + ], + "AddIntentListenerResponseType": [ + "addIntentListenerResponse", + ], + "EventMessageType": [ + "addEventListenerEvent", + "broadcastEvent", + "channelChangedEvent", + "heartbeatEvent", + "intentEvent", + "privateChannelOnAddContextListenerEvent", + "privateChannelOnDisconnectEvent", + "privateChannelOnUnsubscribeEvent", + ], + "ResponseMessageType": [ + "addContextListenerResponse", + "addEventListenerResponse", + "addIntentListenerResponse", + "broadcastResponse", + "contextListenerUnsubscribeResponse", + "createPrivateChannelResponse", + "eventListenerUnsubscribeResponse", + "findInstancesResponse", + "findIntentResponse", + "findIntentsByContextResponse", + "getAppMetadataResponse", + "getCurrentChannelResponse", + "getCurrentContextResponse", + "getInfoResponse", + "getOrCreateChannelResponse", + "getUserChannelsResponse", + "intentListenerUnsubscribeResponse", + "intentResultResponse", + "joinUserChannelResponse", + "leaveCurrentChannelResponse", + "openResponse", + "privateChannelAddEventListenerResponse", + "privateChannelDisconnectResponse", + "privateChannelUnsubscribeEventListenerResponse", + "raiseIntentForContextResponse", + "raiseIntentResponse", + "raiseIntentResultResponse", + ], + "RequestMessageType": [ + "addContextListenerRequest", + "addEventListenerRequest", + "addIntentListenerRequest", + "broadcastRequest", + "contextListenerUnsubscribeRequest", + "createPrivateChannelRequest", + "eventListenerUnsubscribeRequest", + "findInstancesRequest", + "findIntentRequest", + "findIntentsByContextRequest", + "getAppMetadataRequest", + "getCurrentChannelRequest", + "getCurrentContextRequest", + "getInfoRequest", + "getOrCreateChannelRequest", + "getUserChannelsRequest", + "heartbeatAcknowledgementRequest", + "intentListenerUnsubscribeRequest", + "intentResultRequest", + "joinUserChannelRequest", + "leaveCurrentChannelRequest", + "openRequest", + "privateChannelAddEventListenerRequest", + "privateChannelDisconnectRequest", + "privateChannelUnsubscribeEventListenerRequest", + "raiseIntentForContextRequest", + "raiseIntentRequest", + ], + "BroadcastEventType": [ + "broadcastEvent", + ], + "BroadcastRequestType": [ + "broadcastRequest", + ], + "BroadcastResponseType": [ + "broadcastResponse", + ], + "ChannelChangedEventType": [ + "channelChangedEvent", + ], + "ContextListenerUnsubscribeRequestType": [ + "contextListenerUnsubscribeRequest", + ], + "ContextListenerUnsubscribeResponseType": [ + "contextListenerUnsubscribeResponse", + ], + "CreatePrivateChannelRequestType": [ + "createPrivateChannelRequest", + ], + "Type": [ + "app", + "private", + "user", + ], + "CreatePrivateChannelResponseType": [ + "createPrivateChannelResponse", + ], + "EventListenerUnsubscribeRequestType": [ + "eventListenerUnsubscribeRequest", + ], + "EventListenerUnsubscribeResponseType": [ + "eventListenerUnsubscribeResponse", + ], + "Fdc3UserInterfaceChannelsType": [ + "Fdc3UserInterfaceChannels", + ], + "Fdc3UserInterfaceChannelSelectedType": [ + "Fdc3UserInterfaceChannelSelected", + ], + "Fdc3UserInterfaceDragType": [ + "Fdc3UserInterfaceDrag", + ], + "Fdc3UserInterfaceHandshakeType": [ + "Fdc3UserInterfaceHandshake", + ], + "Fdc3UserInterfaceHelloType": [ + "Fdc3UserInterfaceHello", + ], + "Fdc3UserInterfaceMessageType": [ + "Fdc3UserInterfaceChannelSelected", + "Fdc3UserInterfaceChannels", + "Fdc3UserInterfaceDrag", + "Fdc3UserInterfaceHandshake", + "Fdc3UserInterfaceHello", + "Fdc3UserInterfaceResolve", + "Fdc3UserInterfaceResolveAction", + "Fdc3UserInterfaceRestyle", + ], + "Fdc3UserInterfaceResolveType": [ + "Fdc3UserInterfaceResolve", + ], + "Action": [ + "cancel", + "click", + "hover", + ], + "Fdc3UserInterfaceResolveActionType": [ + "Fdc3UserInterfaceResolveAction", + ], + "Fdc3UserInterfaceRestyleType": [ + "Fdc3UserInterfaceRestyle", + ], + "FindInstancesRequestType": [ + "findInstancesRequest", + ], + "FindInstancesErrors": [ + "AgentDisconnected", + "DesktopAgentNotFound", + "IntentDeliveryFailed", + "MalformedContext", + "MalformedMessage", + "NoAppsFound", + "NotConnectedToBridge", + "ResolverTimeout", + "ResolverUnavailable", + "ResponseToBridgeTimedOut", + "TargetAppUnavailable", + "TargetInstanceUnavailable", + "UserCancelledResolution", + ], + "FindInstancesResponseType": [ + "findInstancesResponse", + ], + "FindIntentRequestType": [ + "findIntentRequest", + ], + "FindIntentResponseType": [ + "findIntentResponse", + ], + "FindIntentsByContextRequestType": [ + "findIntentsByContextRequest", + ], + "FindIntentsByContextResponseType": [ + "findIntentsByContextResponse", + ], + "GetAppMetadataRequestType": [ + "getAppMetadataRequest", + ], + "GetAppMetadataResponseType": [ + "getAppMetadataResponse", + ], + "GetCurrentChannelRequestType": [ + "getCurrentChannelRequest", + ], + "GetCurrentChannelResponseType": [ + "getCurrentChannelResponse", + ], + "GetCurrentContextRequestType": [ + "getCurrentContextRequest", + ], + "GetCurrentContextResponseType": [ + "getCurrentContextResponse", + ], + "GetInfoRequestType": [ + "getInfoRequest", + ], + "GetInfoResponseType": [ + "getInfoResponse", + ], + "GetOrCreateChannelRequestType": [ + "getOrCreateChannelRequest", + ], + "GetOrCreateChannelResponseType": [ + "getOrCreateChannelResponse", + ], + "GetUserChannelsRequestType": [ + "getUserChannelsRequest", + ], + "GetUserChannelsResponseType": [ + "getUserChannelsResponse", + ], + "HeartbeatAcknowledgementRequestType": [ + "heartbeatAcknowledgementRequest", + ], + "HeartbeatEventType": [ + "heartbeatEvent", + ], + "IntentEventType": [ + "intentEvent", + ], + "IntentListenerUnsubscribeRequestType": [ + "intentListenerUnsubscribeRequest", + ], + "IntentListenerUnsubscribeResponseType": [ + "intentListenerUnsubscribeResponse", + ], + "IntentResultRequestType": [ + "intentResultRequest", + ], + "IntentResultResponseType": [ + "intentResultResponse", + ], + "JoinUserChannelRequestType": [ + "joinUserChannelRequest", + ], + "JoinUserChannelResponseType": [ + "joinUserChannelResponse", + ], + "LeaveCurrentChannelRequestType": [ + "leaveCurrentChannelRequest", + ], + "LeaveCurrentChannelResponseType": [ + "leaveCurrentChannelResponse", + ], + "OpenRequestType": [ + "openRequest", + ], + "OpenErrorResponsePayload": [ + "AgentDisconnected", + "AppNotFound", + "AppTimeout", + "DesktopAgentNotFound", + "ErrorOnLaunch", + "MalformedContext", + "MalformedMessage", + "NotConnectedToBridge", + "ResolverUnavailable", + "ResponseToBridgeTimedOut", + ], + "OpenResponseType": [ + "openResponse", + ], + "PrivateChannelEventListenerTypes": [ + "onAddContextListener", + "onDisconnect", + "onUnsubscribe", + ], + "PrivateChannelAddEventListenerRequestType": [ + "privateChannelAddEventListenerRequest", + ], + "PrivateChannelAddEventListenerResponseType": [ + "privateChannelAddEventListenerResponse", + ], + "PrivateChannelDisconnectRequestType": [ + "privateChannelDisconnectRequest", + ], + "PrivateChannelDisconnectResponseType": [ + "privateChannelDisconnectResponse", + ], + "PrivateChannelOnAddContextListenerEventType": [ + "privateChannelOnAddContextListenerEvent", + ], + "PrivateChannelOnDisconnectEventType": [ + "privateChannelOnDisconnectEvent", + ], + "PrivateChannelOnUnsubscribeEventType": [ + "privateChannelOnUnsubscribeEvent", + ], + "PrivateChannelUnsubscribeEventListenerRequestType": [ + "privateChannelUnsubscribeEventListenerRequest", + ], + "PrivateChannelUnsubscribeEventListenerResponseType": [ + "privateChannelUnsubscribeEventListenerResponse", + ], + "RaiseIntentForContextRequestType": [ + "raiseIntentForContextRequest", + ], + "RaiseIntentForContextResponseType": [ + "raiseIntentForContextResponse", + ], + "RaiseIntentRequestType": [ + "raiseIntentRequest", + ], + "RaiseIntentResponseType": [ + "raiseIntentResponse", + ], + "RaiseIntentResultResponseType": [ + "raiseIntentResultResponse", + ], + "WebConnectionProtocol1HelloType": [ + "WCP1Hello", + ], + "WebConnectionProtocol2LoadURLType": [ + "WCP2LoadUrl", + ], + "WebConnectionProtocol3HandshakeType": [ + "WCP3Handshake", + ], + "WebConnectionProtocol4ValidateAppIdentityType": [ + "WCP4ValidateAppIdentity", + ], + "WebConnectionProtocol5ValidateAppIdentityFailedResponseType": [ + "WCP5ValidateAppIdentityFailedResponse", + ], + "WebConnectionProtocol5ValidateAppIdentitySuccessResponseType": [ + "WCP5ValidateAppIdentityResponse", + ], + "WebConnectionProtocol6GoodbyeType": [ + "WCP6Goodbye", + ], + "ConnectionStepMessageType": [ + "WCP1Hello", + "WCP2LoadUrl", + "WCP3Handshake", + "WCP4ValidateAppIdentity", + "WCP5ValidateAppIdentityFailedResponse", + "WCP5ValidateAppIdentityResponse", + "WCP6Goodbye", + ], +}; diff --git a/src/api/DesktopAgent.ts b/src/api/DesktopAgent.ts index b31289d74..3691ae3f6 100644 --- a/src/api/DesktopAgent.ts +++ b/src/api/DesktopAgent.ts @@ -548,7 +548,7 @@ export interface DesktopAgent { getAppMetadata(app: AppIdentifier): Promise; //--------------------------------------------------------------------------------------------- - //Deprecated function signatures + // Deprecated function signatures //--------------------------------------------------------------------------------------------- /** diff --git a/src/api/Errors.ts b/src/api/Errors.ts index 2b10d5944..b73182fa5 100644 --- a/src/api/Errors.ts +++ b/src/api/Errors.ts @@ -3,69 +3,112 @@ * Copyright FINOS FDC3 contributors - see NOTICE file */ +/** + * Contains constants representing the errors that can be encountered when trying to connect to a web-based Desktop Agent with the getAgent function. + */ +export enum AgentError { + /** Returned if no Desktop Agent was found by any means available or + * if the Agent previously connected to is not contactable on a + * subsequent connection attempt.*/ + AgentNotFound = "AgentNotFound", + + /** Returned if validation of the app identity by the Desktop Agent + * Failed or the app is not being allowed to connect to the Desktop Agent + * for another reason. */ + AccessDenied = "AccessDenied", + + /** Returned if an error or exception occurs while trying to set + * up communication with a Desktop Agent. */ + ErrorOnConnect = "ErrorOnConnect", + + /** Returned if either the failover function itself, or what it returned, + * was not the right type. */ + InvalidFailover = "InvalidFailover", +}; + /** Constants representing the errors that can be encountered when calling the `open` method on the DesktopAgent object (`fdc3`). */ export enum OpenError { /** Returned if the specified application is not found.*/ - AppNotFound = 'AppNotFound', + AppNotFound = "AppNotFound", + /** Returned if the specified application fails to launch correctly.*/ - ErrorOnLaunch = 'ErrorOnLaunch', + ErrorOnLaunch = "ErrorOnLaunch", + /** Returned if the specified application launches but fails to add a context listener in order to receive the context passed to the `fdc3.open` call.*/ - AppTimeout = 'AppTimeout', + AppTimeout = "AppTimeout", + /** Returned if the FDC3 desktop agent implementation is not currently able to handle the request.*/ - ResolverUnavailable = 'ResolverUnavailable', + ResolverUnavailable = "ResolverUnavailable", + /** Returned if a call to the `open` function is made with an invalid context argument. Contexts should be Objects with at least a `type` field that has a `string` value.*/ - MalformedContext = 'MalformedContext', + MalformedContext = "MalformedContext", + /** @experimental Returned if the specified Desktop Agent is not found, via a connected Desktop Agent Bridge.*/ - DesktopAgentNotFound = 'DesktopAgentNotFound', + DesktopAgentNotFound = "DesktopAgentNotFound", } /** Constants representing the errors that can be encountered when calling the `findIntent`, `findIntentsByContext`, `raiseIntent` or `raiseIntentForContext` methods on the DesktopAgent (`fdc3`). */ export enum ResolveError { /** SHOULD be returned if no apps are available that can resolve the intent and context combination.*/ - NoAppsFound = 'NoAppsFound', + NoAppsFound = "NoAppsFound", + /** Returned if the FDC3 desktop agent implementation is not currently able to handle the request.*/ - ResolverUnavailable = 'ResolverUnavailable', + ResolverUnavailable = "ResolverUnavailable", + /** Returned if the user cancelled the resolution request, for example by closing or cancelling a resolver UI.*/ - UserCancelled = 'UserCancelledResolution', + UserCancelled = "UserCancelledResolution", + /** SHOULD be returned if a timeout cancels an intent resolution that required user interaction. Please use `ResolverUnavailable` instead for situations where a resolver UI or similar fails.*/ - ResolverTimeout = 'ResolverTimeout', + ResolverTimeout = "ResolverTimeout", + /** Returned if a specified target application is not available or a new instance of it cannot be opened. */ - TargetAppUnavailable = 'TargetAppUnavailable', + TargetAppUnavailable = "TargetAppUnavailable", + /** Returned if a specified target application instance is not available, for example because it has been closed. */ - TargetInstanceUnavailable = 'TargetInstanceUnavailable', + TargetInstanceUnavailable = "TargetInstanceUnavailable", + /** Returned if the intent and context could not be delivered to the selected application or instance, for example because it has not added an intent handler within a timeout.*/ - IntentDeliveryFailed = 'IntentDeliveryFailed', + IntentDeliveryFailed = "IntentDeliveryFailed", + /** Returned if a call to one of the `raiseIntent` functions is made with an invalid context argument. Contexts should be Objects with at least a `type` field that has a `string` value.*/ - MalformedContext = 'MalformedContext', + MalformedContext = "MalformedContext", + /** @experimental Returned if the specified Desktop Agent is not found, via a connected Desktop Agent Bridge.*/ - DesktopAgentNotFound = 'DesktopAgentNotFound', + DesktopAgentNotFound = "DesktopAgentNotFound", } export enum ResultError { /** Returned if the intent handler exited without returning a valid result (a promise resolving to a Context, Channel object or void). */ - NoResultReturned = 'NoResultReturned', + NoResultReturned = "NoResultReturned", + /** Returned if the Intent handler function processing the raised intent throws an error or rejects the Promise it returned. */ - IntentHandlerRejected = 'IntentHandlerRejected', + IntentHandlerRejected = "IntentHandlerRejected", } export enum ChannelError { /** Returned if the specified channel is not found when attempting to join a channel via the `joinUserChannel` function of the DesktopAgent (`fdc3`).*/ - NoChannelFound = 'NoChannelFound', + NoChannelFound = "NoChannelFound", + /** SHOULD be returned when a request to join a user channel or to a retrieve a Channel object via the `joinUserChannel` or `getOrCreateChannel` methods of the DesktopAgent (`fdc3`) object is denied. */ - AccessDenied = 'AccessDenied', + AccessDenied = "AccessDenied", + /** SHOULD be returned when a channel cannot be created or retrieved via the `getOrCreateChannel` method of the DesktopAgent (`fdc3`).*/ - CreationFailed = 'CreationFailed', + CreationFailed = "CreationFailed", + /** Returned if a call to the `broadcast` functions is made with an invalid context argument. Contexts should be Objects with at least a `type` field that has a `string` value.*/ - MalformedContext = 'MalformedContext', + MalformedContext = "MalformedContext", } export enum BridgingError { /** @experimental Returned if a Desktop Agent did not return a response, via Desktop Agent Bridging, within the alloted timeout. */ - ResponseTimedOut = 'ResponseToBridgeTimedOut', + ResponseTimedOut = "ResponseToBridgeTimedOut", + /** @experimental Returned if a Desktop Agent that has been targeted by a particular request has been disconnected from the Bridge before a response has been received from it. */ - AgentDisconnected = 'AgentDisconnected', + AgentDisconnected = "AgentDisconnected", + /** @experimental Returned for FDC3 API calls that are specified with arguments indicating that a remote Desktop agent should be targeted (e.g. raiseIntent with an app on a remote DesktopAgent targeted), when the local Desktop Agent is not connected to a bridge. */ - NotConnectedToBridge = 'NotConnectedToBridge', + NotConnectedToBridge = "NotConnectedToBridge", + /** @experimental Returned if a message to a Bridge deviates from the schema for that message sufficiently that it could not be processed. */ - MalformedMessage = 'MalformedMessage', + MalformedMessage = "MalformedMessage", } diff --git a/src/api/GetAgent.ts b/src/api/GetAgent.ts new file mode 100644 index 000000000..bd5dbf800 --- /dev/null +++ b/src/api/GetAgent.ts @@ -0,0 +1,161 @@ +/** + * Typescript related to the getAgent() function. Note that GetAgent.md is a copy of this file which has been modified + * for display in markdown format. + */ +import { DesktopAgent } from './DesktopAgent'; + +/** + * Function used to retrieve an FDC3 Desktop Agent API instance, which + * supports the discovery of a Desktop Agent Preload (a container-injected + * API implementation) or a Desktop Agent Proxy (a Browser-based Desktop Agent + * running in another window or frame). Finally, if no Desktop Agent is found, + * a failover function may be supplied by an app allowing it to start or otherwise + * connect to a Desktop Agent (e.g. by loading a proprietary adaptor that + * returns a `DesktopAgent` implementation or by creating a window or iframe of + * its own that will provide a Desktop Agent Proxy. + * + * @param {GetAgentParams} params Optional parameters object, which + * may include a URL to use for the app's identity, other settings + * that affect the behavior of the getAgent() function and a `failover` + * function that should be run if a Desktop Agent is not detected. + * + * @returns A promise that resolves to a DesktopAgent implementation or + * rejects with an error message from the `AgentError` enumeration if unable to + * return a Desktop Agent implementation. + * + * @example + * const fdc3 = await getAgent(); + * + * // OR + * + * getAgent({ + * identityUrl: "https://example.com/path?param=appName#example", + * channelSelector: false, + * intentResolver: false + * }).then((fdc3) => { + * //do FDC3 stuff here + * }; + */ +export type GetAgentType = (params?: GetAgentParams) => Promise; + +/** + * @typedef {Object} GetAgentParams Type representing parameters passed to the + * getAgent function. + * + * @property {number} timeoutMs Number of milliseconds to allow for an FDC3 + * implementation to be found before calling the failover function or + * rejecting (default 750). Note that the timeout is cancelled as soon as a + * Desktop Agent is detected. There may be additional set-up steps to perform + * which will happen outside the timeout. + * + * @property {string} identityUrl The app's current URL is normally sent to + * a web-based desktop agent to help establish its identity. This property + * may be used to override the URL sent (to handle situations where an app's + * URL is not sufficiently stable to use for identity purposes, e.g. due to + * client-side route changes when navigating within the app). The URL set MUST + * match the origin of the application (scheme, hostname, and port) or it will + * be ignored. If not specified, the app's current URL will be used. + * + * @property {boolean} channelSelector Flag indicating that the application + * needs access to a channel selector UI (i.e. because it supports User Channels + * and does not implement its own UI for selecting channels). Defaults to + * `true`. MAY be ignored by Desktop Agent Preload (container) implementations. + * + * @property {boolean} intentResolver Flag indicating that the application + * needs access to an intent resolver UI (i.e. because it supports raising one + * or more intents and and does not implement its own UI for selecting target + * apps). Defaults to `true`. MAY be ignored by Desktop Agent Preload (container) + * implementations. + * + * @property {boolean} dontSetWindowFdc3 For backwards compatibility, `getAgent` + * will set a reference to the Desktop Agent implementation at `window.fdc3` + * if one does not already exist, and will fire the fdc3Ready event. Defaults to + * `false`. Setting this flag to `true` will inhibit that behavior, leaving + * `window.fdc3` unset. + * + * @property {function} failover An optional function that provides a + * means of connecting to or starting a Desktop Agent, which will be called + * if no Desktop Agent is detected. Must return either a Desktop Agent + * implementation directly (e.g. by using a proprietary adaptor) or a + * WindowProxy (e.g a reference to another window returned by `window.open` + * or an iframe's `contentWindow`) for a window or frame in which it has loaded + * a Desktop Agent or suitable proxy to one that works with FDC3 Web Connection + * and Desktop Agent Communication Protocols. + */ +type GetAgentParams = { + timeoutMs?: number; + identityUrl?: string; + channelSelector?: boolean; + intentResolver?: boolean; + dontSetWindowFdc3?: boolean; + failover?: (args: GetAgentParams) => Promise; +}; + +/** Type representing data on the Desktop Agent that an app + * connected to that is persisted by the getAgent function + * to be used when re-connecting (after a navigation or + * refresh event) and to ensure a consistent instanceId. + */ +export type DesktopAgentDetails = { + /** The type of Desktop Agent connected to. Used to + * prevent an inadvertent switch to a different agent.*/ + agentType: WebDesktopAgentType; + + /** The URL that was previously sent to the Desktop Agent + * to establish the app's identity.*/ + identityUrl?: string; + + /** The current URL at the time of the last connection to + * a Desktop Agent.*/ + actualUrl?: string; + + /** Optional URL field that should be used to store any + * URL that was used to connect to a Desktop Agent. URLs + * may have been provided by a parent window that has since + * gone away and persisting may allow re-connection in such + * cases. */ + agentUrl?: string; + + /** The appId that was identified for the application by the + * Desktop Agent.*/ + appId: string; + + /** The instanceId that was issued to the app by the Desktop + * Agent. */ + instanceId: string; + + /** The instanceUuid that was issued to the app. This should be + * passed when connecting to the Desktop Agent to help + * identify that this app has connected before and which + * instance it is, enabling the Desktop Agent to reissue + * the same instanceId. The instanceUuid should never be shared + * with other applications and is not available through the + * FDC3 API, allowing it to be used as a shared secret with + * the Desktop Agent that issued the associated instanceId.*/ + instanceUuid: string; +}; + +/** Enumeration of values used to describe types of web-based + * Desktop Agent. Each 'type' refers to the means by which + * a connection to the agent is made and/or an interface to it + * received. */ +export enum WebDesktopAgentType { + /** Denotes Desktop Agents that inject the FDC3 interface + * at `window.fdc3`. */ + Preload = 'PRELOAD', + + /** Denotes Desktop Agents that run (or provide an interface) + * within a parent window or frame, a reference to which + * will be found at `window.opener`, `window.parent`, + * `window.parent.opener` etc. */ + ProxyParent = 'PROXY_PARENT', + + /** Denotes Desktop Agents that are connected to by loading a URL + * into a hidden iframe whose URL was returned by a parent window + * or frame. */ + ProxyUrl = 'PROXY_URL', + + /** Denotes a Desktop Agent that was returned by a failover + * function that was passed by the application. */ + Failover = 'FAILOVER', +} diff --git a/src/api/Methods.ts b/src/api/Methods.ts index c29b2f862..1e4a09baa 100644 --- a/src/api/Methods.ts +++ b/src/api/Methods.ts @@ -35,7 +35,7 @@ function rejectIfNoGlobal(f: () => Promise) { } /** - * Utility function that returns a promise that will resolve immeadiately + * Utility function that returns a promise that will resolve immediately * if the desktop agent API is found at `window.fdc3`. If the API is found, * the promise will resolve when the `fdc3Ready` event is received or if it * is found at the end of the specified timeout. If the API is not found, it @@ -46,6 +46,9 @@ function rejectIfNoGlobal(f: () => Promise) { * const intentListener = await addIntentListener("ViewChart", intentHandlerFn); * ``` * + * There is no need to use this function if you are using `await getAgent()` to + * retrieve a Desktop Agent as it already waits for the Desktop Agent to be ready. + * * @param waitForMs The number of milliseconds to wait for the FDC3 API to be * ready. Defaults to 5 seconds. */ diff --git a/src/bridging/BridgingTypes.ts b/src/bridging/BridgingTypes.ts index 63b1bafc9..ec0a3b481 100644 --- a/src/bridging/BridgingTypes.ts +++ b/src/bridging/BridgingTypes.ts @@ -1,8 +1,7 @@ // To parse this data: // -// import { Convert, AgentErrorResponseMessage, AgentRequestMessage, AgentResponseMessage, BridgeErrorResponseMessage, BridgeRequestMessage, BridgeResponseMessage, BroadcastAgentRequest, BroadcastBridgeRequest, ConnectionStepMessage, ConnectionStep2Hello, ConnectionStep3Handshake, ConnectionStep4AuthenticationFailed, ConnectionStep6ConnectedAgentsUpdate, FindInstancesAgentErrorResponse, FindInstancesAgentRequest, FindInstancesAgentResponse, FindInstancesBridgeErrorResponse, FindInstancesBridgeRequest, FindInstancesBridgeResponse, FindIntentAgentErrorResponse, FindIntentAgentRequest, FindIntentAgentResponse, FindIntentBridgeErrorResponse, FindIntentBridgeRequest, FindIntentBridgeResponse, FindIntentsByContextAgentErrorResponse, FindIntentsByContextAgentRequest, FindIntentsByContextAgentResponse, FindIntentsByContextBridgeErrorResponse, FindIntentsByContextBridgeRequest, FindIntentsByContextBridgeResponse, GetAppMetadataAgentErrorResponse, GetAppMetadataAgentRequest, GetAppMetadataAgentResponse, GetAppMetadataBridgeErrorResponse, GetAppMetadataBridgeRequest, GetAppMetadataBridgeResponse, OpenAgentErrorResponse, OpenAgentRequest, OpenAgentResponse, OpenBridgeErrorResponse, OpenBridgeRequest, OpenBridgeResponse, PrivateChannelBroadcastAgentRequest, PrivateChannelBroadcastBridgeRequest, PrivateChannelEventListenerAddedAgentRequest, PrivateChannelEventListenerAddedBridgeRequest, PrivateChannelEventListenerRemovedAgentRequest, PrivateChannelEventListenerRemovedBridgeRequest, PrivateChannelOnAddContextListenerAgentRequest, PrivateChannelOnAddContextListenerBridgeRequest, PrivateChannelOnDisconnectAgentRequest, PrivateChannelOnDisconnectBridgeRequest, PrivateChannelOnUnsubscribeAgentRequest, PrivateChannelOnUnsubscribeBridgeRequest, RaiseIntentAgentErrorResponse, RaiseIntentAgentRequest, RaiseIntentAgentResponse, RaiseIntentBridgeErrorResponse, RaiseIntentBridgeRequest, RaiseIntentBridgeResponse, RaiseIntentResultAgentErrorResponse, RaiseIntentResultAgentResponse, RaiseIntentResultBridgeErrorResponse, RaiseIntentResultBridgeResponse, Context } from "./file"; +// import { Convert, AgentErrorResponseMessage, AgentRequestMessage, AgentResponseMessage, BridgeErrorResponseMessage, BridgeRequestMessage, BridgeResponseMessage, BroadcastAgentRequest, BroadcastBridgeRequest, ConnectionStepMessage, ConnectionStep2Hello, ConnectionStep3Handshake, ConnectionStep4AuthenticationFailed, ConnectionStep6ConnectedAgentsUpdate, FindInstancesAgentErrorResponse, FindInstancesAgentRequest, FindInstancesAgentResponse, FindInstancesBridgeErrorResponse, FindInstancesBridgeRequest, FindInstancesBridgeResponse, FindIntentAgentErrorResponse, FindIntentAgentRequest, FindIntentAgentResponse, FindIntentBridgeErrorResponse, FindIntentBridgeRequest, FindIntentBridgeResponse, FindIntentsByContextAgentErrorResponse, FindIntentsByContextAgentRequest, FindIntentsByContextAgentResponse, FindIntentsByContextBridgeErrorResponse, FindIntentsByContextBridgeRequest, FindIntentsByContextBridgeResponse, GetAppMetadataAgentErrorResponse, GetAppMetadataAgentRequest, GetAppMetadataAgentResponse, GetAppMetadataBridgeErrorResponse, GetAppMetadataBridgeRequest, GetAppMetadataBridgeResponse, OpenAgentErrorResponse, OpenAgentRequest, OpenAgentResponse, OpenBridgeErrorResponse, OpenBridgeRequest, OpenBridgeResponse, PrivateChannelBroadcastAgentRequest, PrivateChannelBroadcastBridgeRequest, PrivateChannelEventListenerAddedAgentRequest, PrivateChannelEventListenerAddedBridgeRequest, PrivateChannelEventListenerRemovedAgentRequest, PrivateChannelEventListenerRemovedBridgeRequest, PrivateChannelOnAddContextListenerAgentRequest, PrivateChannelOnAddContextListenerBridgeRequest, PrivateChannelOnDisconnectAgentRequest, PrivateChannelOnDisconnectBridgeRequest, PrivateChannelOnUnsubscribeAgentRequest, PrivateChannelOnUnsubscribeBridgeRequest, RaiseIntentAgentErrorResponse, RaiseIntentAgentRequest, RaiseIntentAgentResponse, RaiseIntentBridgeErrorResponse, RaiseIntentBridgeRequest, RaiseIntentBridgeResponse, RaiseIntentResultAgentErrorResponse, RaiseIntentResultAgentResponse, RaiseIntentResultBridgeErrorResponse, RaiseIntentResultBridgeResponse } from "./file"; // -// const fDC3DesktopAgentAPISchema = Convert.toFDC3DesktopAgentAPISchema(json); // const agentErrorResponseMessage = Convert.toAgentErrorResponseMessage(json); // const agentRequestMessage = Convert.toAgentRequestMessage(json); // const agentResponseMessage = Convert.toAgentResponseMessage(json); @@ -11,7 +10,7 @@ // const bridgeResponseMessage = Convert.toBridgeResponseMessage(json); // const broadcastAgentRequest = Convert.toBroadcastAgentRequest(json); // const broadcastBridgeRequest = Convert.toBroadcastBridgeRequest(json); -// const bridgingCommons = Convert.toBridgingCommons(json); +// const bridgeCommonDefinitions = Convert.toBridgeCommonDefinitions(json); // const connectionStepMessage = Convert.toConnectionStepMessage(json); // const connectionStep2Hello = Convert.toConnectionStep2Hello(json); // const connectionStep3Handshake = Convert.toConnectionStep3Handshake(json); @@ -69,7 +68,6 @@ // const raiseIntentResultAgentResponse = Convert.toRaiseIntentResultAgentResponse(json); // const raiseIntentResultBridgeErrorResponse = Convert.toRaiseIntentResultBridgeErrorResponse(json); // const raiseIntentResultBridgeResponse = Convert.toRaiseIntentResultBridgeResponse(json); -// const context = Convert.toContext(json); // // These functions will throw an error if the JSON doesn't // match the expected interface, even if the JSON is valid. @@ -549,12 +547,14 @@ export interface BroadcastAgentRequestPayload { */ channelId: string; /** - * The context object that was the payload of a broadcast message. + * The context object that is to be broadcast. */ - context: ContextElement; + context: Context; } /** + * The context object that is to be broadcast. + * * The context object that was the payload of a broadcast message. * * The `fdc3.context` type defines the basic contract or "shape" for all data exchanged by @@ -569,7 +569,7 @@ export interface BroadcastAgentRequestPayload { * data object of a particular type can be expected to have, but this can always be extended * with custom fields as appropriate. */ -export interface ContextElement { +export interface Context { /** * Context data objects may include a set of equivalent key-value pairs that can be used to * help applications identify and look up the context type they receive in their own domain. @@ -614,9 +614,10 @@ export interface ContextElement { * Identifies the type of the message and it is typically set to the FDC3 function name that * the message relates to, e.g. 'findIntent', with 'Request' appended. * - * UUID for the request + * Unique identifier for a request or event message. Required in all message types * - * UUID for this specific response message. + * Unique identifier for a response to a specific message and must always be accompanied by + * a RequestUuid. */ /** @@ -730,9 +731,9 @@ export interface BroadcastBridgeRequestPayload { */ channelId: string; /** - * The context object that was the payload of a broadcast message. + * The context object that is to be broadcast. */ - context: ContextElement; + context: Context; } /** @@ -855,7 +856,7 @@ export interface ConnectionStep3HandshakePayload { * channels), as a mapping of channel id to an array of Context objects, one per type found * in the channel, most recent first. */ - channelsState: { [key: string]: ContextElement[] }; + channelsState: { [key: string]: Context[] }; /** * Desktop Agent ImplementationMetadata trying to connect to the bridge. */ @@ -1003,7 +1004,7 @@ export interface ConnectionStep6ConnectedAgentsUpdatePayload { * The updated state of channels that should be adopted by the agents. Should only be set * when an agent is connecting to the bridge. */ - channelsState?: { [key: string]: ContextElement[] }; + channelsState?: { [key: string]: Context[] }; /** * Should be set when an agent disconnects from the bridge and provide the name that no * longer is assigned. @@ -1058,7 +1059,7 @@ export interface FindInstancesAgentErrorResponse { /** * Error message payload containing an standardized error string. */ - payload: FindInstancesAgentErrorResponsePayload; + payload: PayloadClass; /** * Identifies the type of the message and it is typically set to the FDC3 function name that * the message relates to, e.g. 'findIntent', with 'Response' appended. @@ -1078,11 +1079,18 @@ export interface FindInstancesAgentErrorResponseMeta { /** * Error message payload containing an standardized error string. */ -export interface FindInstancesAgentErrorResponsePayload { - error: ErrorMessage; +export interface PayloadClass { + error: FindInstancesErrors; } /** + * Unique identifier for a request or event message. Required in all message types + * + * Unique identifier for a response to a specific message and must always be accompanied by + * a RequestUuid. + * + * Should be set if the raiseIntent request returned an error. + * * Constants representing the errors that can be encountered when calling the `findIntent`, * `findIntentsByContext`, `raiseIntent` or `raiseIntentForContext` methods on the * DesktopAgent (`fdc3`). @@ -1094,15 +1102,16 @@ export interface FindInstancesAgentErrorResponsePayload { * Constants representing the errors that can be encountered when calling the `open` method * on the DesktopAgent object (`fdc3`). */ -export type ErrorMessage = "DesktopAgentNotFound" | "IntentDeliveryFailed" | "MalformedContext" | "NoAppsFound" | "ResolverTimeout" | "ResolverUnavailable" | "TargetAppUnavailable" | "TargetInstanceUnavailable" | "UserCancelledResolution" | "AgentDisconnected" | "NotConnectedToBridge" | "ResponseToBridgeTimedOut" | "MalformedMessage"; +export type FindInstancesErrors = "DesktopAgentNotFound" | "IntentDeliveryFailed" | "MalformedContext" | "NoAppsFound" | "ResolverTimeout" | "ResolverUnavailable" | "TargetAppUnavailable" | "TargetInstanceUnavailable" | "UserCancelledResolution" | "AgentDisconnected" | "NotConnectedToBridge" | "ResponseToBridgeTimedOut" | "MalformedMessage"; /** * Identifies the type of the message and it is typically set to the FDC3 function name that * the message relates to, e.g. 'findIntent', with 'Response' appended. * - * UUID for the request + * Unique identifier for a request or event message. Required in all message types * - * UUID for this specific response message. + * Unique identifier for a response to a specific message and must always be accompanied by + * a RequestUuid. */ /** @@ -1259,9 +1268,10 @@ export interface AppIdentifier { * Identifies the type of the message and it is typically set to the FDC3 function name that * the message relates to, e.g. 'findIntent', with 'Request' appended. * - * UUID for the request + * Unique identifier for a request or event message. Required in all message types * - * UUID for this specific response message. + * Unique identifier for a response to a specific message and must always be accompanied by + * a RequestUuid. */ /** @@ -1270,7 +1280,7 @@ export interface AppIdentifier { * A response message from a Desktop Agent to the Bridge. */ export interface FindInstancesAgentResponse { - meta: FindInstancesAgentResponseMeta; + meta: AgentResponseMetadata; /** * The message payload typically contains return values for FDC3 API functions. */ @@ -1283,15 +1293,10 @@ export interface FindInstancesAgentResponse { } /** - * Metadata for a response messages sent by a Desktop Agent to the Bridge - */ -export interface FindInstancesAgentResponseMeta { - requestUuid: string; - responseUuid: string; - timestamp: Date; -} - -/** + * The message payload contains a flag indicating whether the API call was successful, plus + * any return values for the FDC3 API function called, or indicating that the request + * resulted in an error and including a standardized error message. + * * The message payload typically contains return values for FDC3 API functions. */ export interface FindInstancesAgentResponsePayload { @@ -1427,7 +1432,7 @@ export interface FindInstancesBridgeErrorResponse { * The error message payload contains details of an error return to the app or agent that * raised the original request. */ - payload: FindInstancesBridgeErrorResponsePayload; + payload: MessagePayload; /** * Identifies the type of the message and it is typically set to the FDC3 function name that * the message relates to, e.g. 'findIntent', with 'Response' appended. @@ -1450,8 +1455,8 @@ export interface FindInstancesBridgeErrorResponseMeta { * The error message payload contains details of an error return to the app or agent that * raised the original request. */ -export interface FindInstancesBridgeErrorResponsePayload { - error: ErrorMessage; +export interface MessagePayload { + error: FindInstancesErrors; } /** @@ -1582,7 +1587,7 @@ export interface FindInstancesBridgeRequestPayload { * request. */ export interface FindInstancesBridgeResponse { - meta: FindInstancesBridgeResponseMeta; + meta: BridgeResponseMessageMeta; /** * The message payload typically contains return values for FDC3 API functions. */ @@ -1595,18 +1600,10 @@ export interface FindInstancesBridgeResponse { } /** - * Metadata required in a response message collated and/or forwarded on by the Bridge - */ -export interface FindInstancesBridgeResponseMeta { - errorDetails?: ResponseErrorDetail[]; - errorSources?: DesktopAgentIdentifier[]; - requestUuid: string; - responseUuid: string; - sources?: DesktopAgentIdentifier[]; - timestamp: Date; -} - -/** + * The message payload contains a flag indicating whether the API call was successful, plus + * any return values for the FDC3 API function called, or indicating that the request + * resulted in an error and including a standardized error message. + * * The message payload typically contains return values for FDC3 API functions. */ export interface FindInstancesBridgeResponsePayload { @@ -1645,16 +1642,17 @@ export interface FindIntentAgentErrorResponseMeta { * Error message payload containing an standardized error string. */ export interface FindIntentAgentErrorResponsePayload { - error: ErrorMessage; + error: FindInstancesErrors; } /** * Identifies the type of the message and it is typically set to the FDC3 function name that * the message relates to, e.g. 'findIntent', with 'Response' appended. * - * UUID for the request + * Unique identifier for a request or event message. Required in all message types * - * UUID for this specific response message. + * Unique identifier for a response to a specific message and must always be accompanied by + * a RequestUuid. */ /** @@ -1698,7 +1696,7 @@ export interface FindIntentAgentRequestMeta { * The message payload typically contains the arguments to FDC3 API functions. */ export interface FindIntentAgentRequestPayload { - context?: ContextElement; + context?: Context; intent: string; resultType?: string; } @@ -1707,9 +1705,10 @@ export interface FindIntentAgentRequestPayload { * Identifies the type of the message and it is typically set to the FDC3 function name that * the message relates to, e.g. 'findIntent', with 'Request' appended. * - * UUID for the request + * Unique identifier for a request or event message. Required in all message types * - * UUID for this specific response message. + * Unique identifier for a response to a specific message and must always be accompanied by + * a RequestUuid. */ /** @@ -1812,7 +1811,7 @@ export interface FindIntentBridgeErrorResponseMeta { * raised the original request. */ export interface FindIntentBridgeErrorResponsePayload { - error: ErrorMessage; + error: FindInstancesErrors; } /** @@ -1857,7 +1856,7 @@ export interface FindIntentBridgeRequestMeta { * The message payload typically contains the arguments to FDC3 API functions. */ export interface FindIntentBridgeRequestPayload { - context?: ContextElement; + context?: Context; intent: string; resultType?: string; } @@ -1932,16 +1931,17 @@ export interface FindIntentsByContextAgentErrorResponseMeta { * Error message payload containing an standardized error string. */ export interface FindIntentsByContextAgentErrorResponsePayload { - error: ErrorMessage; + error: FindInstancesErrors; } /** * Identifies the type of the message and it is typically set to the FDC3 function name that * the message relates to, e.g. 'findIntent', with 'Response' appended. * - * UUID for the request + * Unique identifier for a request or event message. Required in all message types * - * UUID for this specific response message. + * Unique identifier for a response to a specific message and must always be accompanied by + * a RequestUuid. */ /** @@ -1986,7 +1986,7 @@ export interface FindIntentsByContextAgentRequestMeta { * The message payload typically contains the arguments to FDC3 API functions. */ export interface FindIntentsByContextAgentRequestPayload { - context: ContextElement; + context: Context; resultType?: string; } @@ -1994,9 +1994,10 @@ export interface FindIntentsByContextAgentRequestPayload { * Identifies the type of the message and it is typically set to the FDC3 function name that * the message relates to, e.g. 'findIntent', with 'Request' appended. * - * UUID for the request + * Unique identifier for a request or event message. Required in all message types * - * UUID for this specific response message. + * Unique identifier for a response to a specific message and must always be accompanied by + * a RequestUuid. */ /** @@ -2069,7 +2070,7 @@ export interface FindIntentsByContextBridgeErrorResponseMeta { * raised the original request. */ export interface FindIntentsByContextBridgeErrorResponsePayload { - error: ErrorMessage; + error: FindInstancesErrors; } /** @@ -2115,7 +2116,7 @@ export interface FindIntentsByContextBridgeRequestMeta { * The message payload typically contains the arguments to FDC3 API functions. */ export interface FindIntentsByContextBridgeRequestPayload { - context: ContextElement; + context: Context; resultType?: string; } @@ -2189,16 +2190,17 @@ export interface GetAppMetadataAgentErrorResponseMeta { * Error message payload containing an standardized error string. */ export interface GetAppMetadataAgentErrorResponsePayload { - error: ErrorMessage; + error: FindInstancesErrors; } /** * Identifies the type of the message and it is typically set to the FDC3 function name that * the message relates to, e.g. 'findIntent', with 'Response' appended. * - * UUID for the request + * Unique identifier for a request or event message. Required in all message types * - * UUID for this specific response message. + * Unique identifier for a response to a specific message and must always be accompanied by + * a RequestUuid. */ /** @@ -2242,7 +2244,7 @@ export interface GetAppMetadataAgentRequestMeta { * The message payload typically contains the arguments to FDC3 API functions. */ export interface GetAppMetadataAgentRequestPayload { - app: AppDestinationIdentifier; + app: AppObject; } /** @@ -2282,7 +2284,7 @@ export interface GetAppMetadataAgentRequestPayload { * `source.instanceId` MUST be set, indicating the specific app instance that * received the intent. */ -export interface AppDestinationIdentifier { +export interface AppObject { /** * Used in Desktop Agent Bridging to attribute or target a message to a * particular Desktop Agent. @@ -2308,9 +2310,10 @@ export interface AppDestinationIdentifier { * Identifies the type of the message and it is typically set to the FDC3 function name that * the message relates to, e.g. 'findIntent', with 'Request' appended. * - * UUID for the request + * Unique identifier for a request or event message. Required in all message types * - * UUID for this specific response message. + * Unique identifier for a response to a specific message and must always be accompanied by + * a RequestUuid. */ /** @@ -2383,7 +2386,7 @@ export interface GetAppMetadataBridgeErrorResponseMeta { * raised the original request. */ export interface GetAppMetadataBridgeErrorResponsePayload { - error: ErrorMessage; + error: FindInstancesErrors; } /** @@ -2428,7 +2431,7 @@ export interface GetAppMetadataBridgeRequestMeta { * The message payload typically contains the arguments to FDC3 API functions. */ export interface GetAppMetadataBridgeRequestPayload { - app: AppDestinationIdentifier; + app: AppObject; } /** @@ -2501,7 +2504,7 @@ export interface OpenAgentErrorResponseMeta { * Error message payload containing an standardized error string. */ export interface OpenAgentErrorResponsePayload { - error: OpenErrorMessage; + error: OpenErrorResponsePayload; } /** @@ -2516,15 +2519,16 @@ export interface OpenAgentErrorResponsePayload { * `findIntentsByContext`, `raiseIntent` or `raiseIntentForContext` methods on the * DesktopAgent (`fdc3`). */ -export type OpenErrorMessage = "AppNotFound" | "AppTimeout" | "DesktopAgentNotFound" | "ErrorOnLaunch" | "MalformedContext" | "ResolverUnavailable" | "AgentDisconnected" | "NotConnectedToBridge" | "ResponseToBridgeTimedOut" | "MalformedMessage"; +export type OpenErrorResponsePayload = "AppNotFound" | "AppTimeout" | "DesktopAgentNotFound" | "ErrorOnLaunch" | "MalformedContext" | "ResolverUnavailable" | "AgentDisconnected" | "NotConnectedToBridge" | "ResponseToBridgeTimedOut" | "MalformedMessage"; /** * Identifies the type of the message and it is typically set to the FDC3 function name that * the message relates to, e.g. 'findIntent', with 'Response' appended. * - * UUID for the request + * Unique identifier for a request or event message. Required in all message types * - * UUID for this specific response message. + * Unique identifier for a response to a specific message and must always be accompanied by + * a RequestUuid. */ /** @@ -2572,7 +2576,7 @@ export interface OpenAgentRequestPayload { * The application to open on the specified Desktop Agent */ app: AppToOpen; - context?: ContextElement; + context?: Context; } /** @@ -2637,9 +2641,10 @@ export interface AppToOpen { * Identifies the type of the message and it is typically set to the FDC3 function name that * the message relates to, e.g. 'findIntent', with 'Request' appended. * - * UUID for the request + * Unique identifier for a request or event message. Required in all message types * - * UUID for this specific response message. + * Unique identifier for a response to a specific message and must always be accompanied by + * a RequestUuid. */ /** @@ -2712,7 +2717,7 @@ export interface OpenBridgeErrorResponseMeta { * raised the original request. */ export interface OpenBridgeErrorResponsePayload { - error: OpenErrorMessage; + error: OpenErrorResponsePayload; } /** @@ -2761,7 +2766,7 @@ export interface OpenBridgeRequestPayload { * The application to open on the specified Desktop Agent */ app: AppToOpen; - context?: ContextElement; + context?: Context; } /** @@ -2920,16 +2925,17 @@ export interface PrivateChannelBroadcastAgentRequestPayload { /** * The context object that was the payload of a broadcast message. */ - context: ContextElement; + context: Context; } /** * Identifies the type of the message and it is typically set to the FDC3 function name that * the message relates to, e.g. 'findIntent', with 'Request' appended. * - * UUID for the request + * Unique identifier for a request or event message. Required in all message types * - * UUID for this specific response message. + * Unique identifier for a response to a specific message and must always be accompanied by + * a RequestUuid. */ /** @@ -2981,7 +2987,7 @@ export interface PrivateChannelBroadcastBridgeRequestPayload { /** * The context object that was the payload of a broadcast message. */ - context: ContextElement; + context: Context; } /** @@ -3041,9 +3047,10 @@ export type PrivateChannelEventListenerTypes = "onAddContextListener" | "onUnsub * Identifies the type of the message and it is typically set to the FDC3 function name that * the message relates to, e.g. 'findIntent', with 'Request' appended. * - * UUID for the request + * Unique identifier for a request or event message. Required in all message types * - * UUID for this specific response message. + * Unique identifier for a response to a specific message and must always be accompanied by + * a RequestUuid. */ /** @@ -3147,9 +3154,10 @@ export interface PrivateChannelEventListenerRemovedAgentRequestPayload { * Identifies the type of the message and it is typically set to the FDC3 function name that * the message relates to, e.g. 'findIntent', with 'Request' appended. * - * UUID for the request + * Unique identifier for a request or event message. Required in all message types * - * UUID for this specific response message. + * Unique identifier for a response to a specific message and must always be accompanied by + * a RequestUuid. */ /** @@ -3256,9 +3264,10 @@ export interface PrivateChannelOnAddContextListenerAgentRequestPayload { * Identifies the type of the message and it is typically set to the FDC3 function name that * the message relates to, e.g. 'findIntent', with 'Request' appended. * - * UUID for the request + * Unique identifier for a request or event message. Required in all message types * - * UUID for this specific response message. + * Unique identifier for a response to a specific message and must always be accompanied by + * a RequestUuid. */ /** @@ -3364,9 +3373,10 @@ export interface PrivateChannelOnDisconnectAgentRequestPayload { * Identifies the type of the message and it is typically set to the FDC3 function name that * the message relates to, e.g. 'findIntent', with 'Request' appended. * - * UUID for the request + * Unique identifier for a request or event message. Required in all message types * - * UUID for this specific response message. + * Unique identifier for a response to a specific message and must always be accompanied by + * a RequestUuid. */ /** @@ -3473,9 +3483,10 @@ export interface PrivateChannelOnUnsubscribeAgentRequestPayload { * Identifies the type of the message and it is typically set to the FDC3 function name that * the message relates to, e.g. 'findIntent', with 'Request' appended. * - * UUID for the request + * Unique identifier for a request or event message. Required in all message types * - * UUID for this specific response message. + * Unique identifier for a response to a specific message and must always be accompanied by + * a RequestUuid. */ /** @@ -3560,19 +3571,25 @@ export interface RaiseIntentAgentErrorResponseMeta { } /** + * Used if a raiseIntent request resulted in an error + * * Error message payload containing an standardized error string. */ export interface RaiseIntentAgentErrorResponsePayload { - error: ErrorMessage; + /** + * Should be set if the raiseIntent request returned an error. + */ + error: FindInstancesErrors; } /** * Identifies the type of the message and it is typically set to the FDC3 function name that * the message relates to, e.g. 'findIntent', with 'Response' appended. * - * UUID for the request + * Unique identifier for a request or event message. Required in all message types * - * UUID for this specific response message. + * Unique identifier for a response to a specific message and must always be accompanied by + * a RequestUuid. */ /** @@ -3617,17 +3634,77 @@ export interface RaiseIntentAgentRequestMeta { */ export interface RaiseIntentAgentRequestPayload { app: AppDestinationIdentifier; - context: ContextElement; + context: Context; intent: string; } +/** + * Field that represents a destination App on a remote Desktop Agent that a request is to be + * sent to. + * + * Identifies a particular Desktop Agent in Desktop Agent Bridging scenarios + * where a request needs to be directed to a Desktop Agent rather than a specific app, or a + * response message is returned by the Desktop Agent (or more specifically its resolver) + * rather than a specific app. Used as a substitute for `AppIdentifier` in cases where no + * app details are available or are appropriate. + * + * Array of DesktopAgentIdentifiers for responses that were not returned to the bridge + * before the timeout or because an error occurred. May be omitted if all sources responded + * without errors. MUST include the `desktopAgent` field when returned by the bridge. + * + * Array of DesktopAgentIdentifiers for the sources that generated responses to the request. + * Will contain a single value for individual responses and multiple values for responses + * that were collated by the bridge. May be omitted if all sources errored. MUST include the + * `desktopAgent` field when returned by the bridge. + * + * Field that represents a destination Desktop Agent that a request is to be sent to. + * + * Identifies an application, or instance of an application, and is used to target FDC3 API + * calls, such as `fdc3.open` or `fdc3.raiseIntent` at specific applications or application + * instances. + * + * Will always include at least an `appId` field, which uniquely identifies a specific app. + * + * If the `instanceId` field is set then the `AppMetadata` object represents a specific + * instance of the application that may be addressed using that Id. + * + * Field that represents the source application that a request or response was received + * from. + * + * Identifier for the app instance that was selected (or started) to resolve the intent. + * `source.instanceId` MUST be set, indicating the specific app instance that + * received the intent. + */ +export interface AppDestinationIdentifier { + /** + * Used in Desktop Agent Bridging to attribute or target a message to a + * particular Desktop Agent. + * + * The Desktop Agent that the app is available on. Used in Desktop Agent Bridging to + * identify the Desktop Agent to target. + */ + desktopAgent: string; + /** + * The unique application identifier located within a specific application directory + * instance. An example of an appId might be 'app@sub.root' + */ + appId: string; + /** + * An optional instance identifier, indicating that this object represents a specific + * instance of the application described. + */ + instanceId?: string; + [property: string]: any; +} + /** * Identifies the type of the message and it is typically set to the FDC3 function name that * the message relates to, e.g. 'findIntent', with 'Request' appended. * - * UUID for the request + * Unique identifier for a request or event message. Required in all message types * - * UUID for this specific response message. + * Unique identifier for a response to a specific message and must always be accompanied by + * a RequestUuid. */ /** @@ -3661,10 +3738,15 @@ export interface RaiseIntentAgentResponseMeta { * The message payload typically contains return values for FDC3 API functions. */ export interface RaiseIntentAgentResponsePayload { + /** + * Used if the raiseIntent request was successfully resolved + */ intentResolution: IntentResolution; } /** + * Used if the raiseIntent request was successfully resolved + * * IntentResolution provides a standard format for data returned upon resolving an intent. * * ```javascript @@ -3736,11 +3818,16 @@ export interface RaiseIntentBridgeErrorResponseMeta { } /** + * Used if a raiseIntent request resulted in an error + * * The error message payload contains details of an error return to the app or agent that * raised the original request. */ export interface RaiseIntentBridgeErrorResponsePayload { - error: ErrorMessage; + /** + * Should be set if the raiseIntent request returned an error. + */ + error: FindInstancesErrors; } /** @@ -3786,7 +3873,7 @@ export interface RaiseIntentBridgeRequestMeta { */ export interface RaiseIntentBridgeRequestPayload { app: AppDestinationIdentifier; - context: ContextElement; + context: Context; intent: string; } @@ -3825,6 +3912,9 @@ export interface RaiseIntentBridgeResponseMeta { * The message payload typically contains return values for FDC3 API functions. */ export interface RaiseIntentBridgeResponsePayload { + /** + * Used if the raiseIntent request was successfully resolved + */ intentResolution: IntentResolution; } @@ -3882,9 +3972,10 @@ export type RaiseIntentResultErrorMessage = "IntentHandlerRejected" | "NoResultR * Identifies the type of the message and it is typically set to the FDC3 function name that * the message relates to, e.g. 'findIntent', with 'Response' appended. * - * UUID for the request + * Unique identifier for a request or event message. Required in all message types * - * UUID for this specific response message. + * Unique identifier for a response to a specific message and must always be accompanied by + * a RequestUuid. */ /** @@ -3922,7 +4013,7 @@ export interface RaiseIntentResultAgentResponsePayload { } export interface IntentResult { - context?: ContextElement; + context?: Context; channel?: Channel; } @@ -4069,71 +4160,9 @@ export interface RaiseIntentResultBridgeResponsePayload { intentResult: IntentResult; } -/** - * The `fdc3.context` type defines the basic contract or "shape" for all data exchanged by - * FDC3 operations. As such, it is not really meant to be used on its own, but is imported - * by more specific type definitions (standardized or custom) to provide the structure and - * properties shared by all FDC3 context data types. - * - * The key element of FDC3 context types is their mandatory `type` property, which is used - * to identify what type of data the object represents, and what shape it has. - * - * The FDC3 context type, and all derived types, define the minimum set of fields a context - * data object of a particular type can be expected to have, but this can always be extended - * with custom fields as appropriate. - */ -export interface Context { - /** - * Context data objects may include a set of equivalent key-value pairs that can be used to - * help applications identify and look up the context type they receive in their own domain. - * The idea behind this design is that applications can provide as many equivalent - * identifiers to a target application as possible, e.g. an instrument may be represented by - * an ISIN, CUSIP or Bloomberg identifier. - * - * Identifiers do not make sense for all types of data, so the `id` property is therefore - * optional, but some derived types may choose to require at least one identifier. - * Identifier values SHOULD always be of type string. - */ - id?: { [key: string]: any }; - /** - * Context data objects may include a name property that can be used for more information, - * or display purposes. Some derived types may require the name object as mandatory, - * depending on use case. - */ - name?: string; - /** - * The type property is the only _required_ part of the FDC3 context data schema. The FDC3 - * [API](https://fdc3.finos.org/docs/api/spec) relies on the `type` property being present - * to route shared context data appropriately. - * - * FDC3 [Intents](https://fdc3.finos.org/docs/intents/spec) also register the context data - * types they support in an FDC3 [App - * Directory](https://fdc3.finos.org/docs/app-directory/overview), used for intent discovery - * and routing. - * - * Standardized FDC3 context types have well-known `type` properties prefixed with the - * `fdc3` namespace, e.g. `fdc3.instrument`. For non-standard types, e.g. those defined and - * used by a particular organization, the convention is to prefix them with an - * organization-specific namespace, e.g. `blackrock.fund`. - * - * See the [Context Data Specification](https://fdc3.finos.org/docs/context/spec) for more - * information about context data types. - */ - type: string; - [property: string]: any; -} - // Converts JSON strings to/from your types // and asserts the results of JSON.parse at runtime export class Convert { - public static toFDC3DesktopAgentAPISchema(json: string): any { - return cast(JSON.parse(json), "any"); - } - - public static fDC3DesktopAgentAPISchemaToJson(value: any): string { - return JSON.stringify(uncast(value, "any"), null, 2); - } - public static toAgentErrorResponseMessage(json: string): AgentErrorResponseMessage { return cast(JSON.parse(json), r("AgentErrorResponseMessage")); } @@ -4198,11 +4227,11 @@ export class Convert { return JSON.stringify(uncast(value, r("BroadcastBridgeRequest")), null, 2); } - public static toBridgingCommons(json: string): { [key: string]: any } { + public static toBridgeCommonDefinitions(json: string): { [key: string]: any } { return cast(JSON.parse(json), m("any")); } - public static bridgingCommonsToJson(value: { [key: string]: any }): string { + public static bridgeCommonDefinitionsToJson(value: { [key: string]: any }): string { return JSON.stringify(uncast(value, m("any")), null, 2); } @@ -4661,14 +4690,6 @@ export class Convert { public static raiseIntentResultBridgeResponseToJson(value: RaiseIntentResultBridgeResponse): string { return JSON.stringify(uncast(value, r("RaiseIntentResultBridgeResponse")), null, 2); } - - public static toContext(json: string): Context { - return cast(JSON.parse(json), r("Context")); - } - - public static contextToJson(value: Context): string { - return JSON.stringify(uncast(value, r("Context")), null, 2); - } } function invalidValue(typ: any, val: any, key: any, parent: any = ''): never { @@ -4922,9 +4943,9 @@ const typeMap: any = { ], "any"), "BroadcastAgentRequestPayload": o([ { json: "channelId", js: "channelId", typ: "" }, - { json: "context", js: "context", typ: r("ContextElement") }, + { json: "context", js: "context", typ: r("Context") }, ], false), - "ContextElement": o([ + "Context": o([ { json: "id", js: "id", typ: u(undefined, m("any")) }, { json: "name", js: "name", typ: u(undefined, "") }, { json: "type", js: "type", typ: "" }, @@ -4946,7 +4967,7 @@ const typeMap: any = { ], "any"), "BroadcastBridgeRequestPayload": o([ { json: "channelId", js: "channelId", typ: "" }, - { json: "context", js: "context", typ: r("ContextElement") }, + { json: "context", js: "context", typ: r("Context") }, ], false), "ConnectionStepMessage": o([ { json: "meta", js: "meta", typ: r("ConnectionStepMetadata") }, @@ -4983,7 +5004,7 @@ const typeMap: any = { ], false), "ConnectionStep3HandshakePayload": o([ { json: "authToken", js: "authToken", typ: u(undefined, "") }, - { json: "channelsState", js: "channelsState", typ: m(a(r("ContextElement"))) }, + { json: "channelsState", js: "channelsState", typ: m(a(r("Context"))) }, { json: "implementationMetadata", js: "implementationMetadata", typ: r("ConnectingAgentImplementationMetadata") }, { json: "requestedName", js: "requestedName", typ: "" }, ], false), @@ -5024,7 +5045,7 @@ const typeMap: any = { "ConnectionStep6ConnectedAgentsUpdatePayload": o([ { json: "addAgent", js: "addAgent", typ: u(undefined, "") }, { json: "allAgents", js: "allAgents", typ: a(r("DesktopAgentImplementationMetadata")) }, - { json: "channelsState", js: "channelsState", typ: u(undefined, m(a(r("ContextElement")))) }, + { json: "channelsState", js: "channelsState", typ: u(undefined, m(a(r("Context")))) }, { json: "removeAgent", js: "removeAgent", typ: u(undefined, "") }, ], false), "DesktopAgentImplementationMetadata": o([ @@ -5036,7 +5057,7 @@ const typeMap: any = { ], false), "FindInstancesAgentErrorResponse": o([ { json: "meta", js: "meta", typ: r("FindInstancesAgentErrorResponseMeta") }, - { json: "payload", js: "payload", typ: r("FindInstancesAgentErrorResponsePayload") }, + { json: "payload", js: "payload", typ: r("PayloadClass") }, { json: "type", js: "type", typ: r("FindInstancesAgentErrorResponseType") }, ], false), "FindInstancesAgentErrorResponseMeta": o([ @@ -5044,8 +5065,8 @@ const typeMap: any = { { json: "responseUuid", js: "responseUuid", typ: "" }, { json: "timestamp", js: "timestamp", typ: Date }, ], false), - "FindInstancesAgentErrorResponsePayload": o([ - { json: "error", js: "error", typ: r("ErrorMessage") }, + "PayloadClass": o([ + { json: "error", js: "error", typ: r("FindInstancesErrors") }, ], false), "FindInstancesAgentRequest": o([ { json: "meta", js: "meta", typ: r("FindInstancesAgentRequestMeta") }, @@ -5072,15 +5093,10 @@ const typeMap: any = { { json: "instanceId", js: "instanceId", typ: u(undefined, "") }, ], "any"), "FindInstancesAgentResponse": o([ - { json: "meta", js: "meta", typ: r("FindInstancesAgentResponseMeta") }, + { json: "meta", js: "meta", typ: r("AgentResponseMetadata") }, { json: "payload", js: "payload", typ: r("FindInstancesAgentResponsePayload") }, { json: "type", js: "type", typ: r("FindInstancesAgentErrorResponseType") }, ], false), - "FindInstancesAgentResponseMeta": o([ - { json: "requestUuid", js: "requestUuid", typ: "" }, - { json: "responseUuid", js: "responseUuid", typ: "" }, - { json: "timestamp", js: "timestamp", typ: Date }, - ], false), "FindInstancesAgentResponsePayload": o([ { json: "appIdentifiers", js: "appIdentifiers", typ: a(r("AppMetadata")) }, ], false), @@ -5111,7 +5127,7 @@ const typeMap: any = { ], false), "FindInstancesBridgeErrorResponse": o([ { json: "meta", js: "meta", typ: r("FindInstancesBridgeErrorResponseMeta") }, - { json: "payload", js: "payload", typ: r("FindInstancesBridgeErrorResponsePayload") }, + { json: "payload", js: "payload", typ: r("MessagePayload") }, { json: "type", js: "type", typ: r("FindInstancesAgentErrorResponseType") }, ], false), "FindInstancesBridgeErrorResponseMeta": o([ @@ -5121,8 +5137,8 @@ const typeMap: any = { { json: "responseUuid", js: "responseUuid", typ: "" }, { json: "timestamp", js: "timestamp", typ: Date }, ], false), - "FindInstancesBridgeErrorResponsePayload": o([ - { json: "error", js: "error", typ: r("ErrorMessage") }, + "MessagePayload": o([ + { json: "error", js: "error", typ: r("FindInstancesErrors") }, ], false), "FindInstancesBridgeRequest": o([ { json: "meta", js: "meta", typ: r("FindInstancesBridgeRequestMeta") }, @@ -5144,18 +5160,10 @@ const typeMap: any = { { json: "app", js: "app", typ: r("AppIdentifier") }, ], false), "FindInstancesBridgeResponse": o([ - { json: "meta", js: "meta", typ: r("FindInstancesBridgeResponseMeta") }, + { json: "meta", js: "meta", typ: r("BridgeResponseMessageMeta") }, { json: "payload", js: "payload", typ: r("FindInstancesBridgeResponsePayload") }, { json: "type", js: "type", typ: r("FindInstancesAgentErrorResponseType") }, ], false), - "FindInstancesBridgeResponseMeta": o([ - { json: "errorDetails", js: "errorDetails", typ: u(undefined, a(r("ResponseErrorDetail"))) }, - { json: "errorSources", js: "errorSources", typ: u(undefined, a(r("DesktopAgentIdentifier"))) }, - { json: "requestUuid", js: "requestUuid", typ: "" }, - { json: "responseUuid", js: "responseUuid", typ: "" }, - { json: "sources", js: "sources", typ: u(undefined, a(r("DesktopAgentIdentifier"))) }, - { json: "timestamp", js: "timestamp", typ: Date }, - ], false), "FindInstancesBridgeResponsePayload": o([ { json: "appIdentifiers", js: "appIdentifiers", typ: a(r("AppMetadata")) }, ], false), @@ -5170,7 +5178,7 @@ const typeMap: any = { { json: "timestamp", js: "timestamp", typ: Date }, ], false), "FindIntentAgentErrorResponsePayload": o([ - { json: "error", js: "error", typ: r("ErrorMessage") }, + { json: "error", js: "error", typ: r("FindInstancesErrors") }, ], false), "FindIntentAgentRequest": o([ { json: "meta", js: "meta", typ: r("FindIntentAgentRequestMeta") }, @@ -5184,7 +5192,7 @@ const typeMap: any = { { json: "destination", js: "destination", typ: u(undefined, r("BridgeParticipantIdentifier")) }, ], false), "FindIntentAgentRequestPayload": o([ - { json: "context", js: "context", typ: u(undefined, r("ContextElement")) }, + { json: "context", js: "context", typ: u(undefined, r("Context")) }, { json: "intent", js: "intent", typ: "" }, { json: "resultType", js: "resultType", typ: u(undefined, "") }, ], false), @@ -5222,7 +5230,7 @@ const typeMap: any = { { json: "timestamp", js: "timestamp", typ: Date }, ], false), "FindIntentBridgeErrorResponsePayload": o([ - { json: "error", js: "error", typ: r("ErrorMessage") }, + { json: "error", js: "error", typ: r("FindInstancesErrors") }, ], false), "FindIntentBridgeRequest": o([ { json: "meta", js: "meta", typ: r("FindIntentBridgeRequestMeta") }, @@ -5236,7 +5244,7 @@ const typeMap: any = { { json: "destination", js: "destination", typ: u(undefined, r("BridgeParticipantIdentifier")) }, ], false), "FindIntentBridgeRequestPayload": o([ - { json: "context", js: "context", typ: u(undefined, r("ContextElement")) }, + { json: "context", js: "context", typ: u(undefined, r("Context")) }, { json: "intent", js: "intent", typ: "" }, { json: "resultType", js: "resultType", typ: u(undefined, "") }, ], false), @@ -5267,7 +5275,7 @@ const typeMap: any = { { json: "timestamp", js: "timestamp", typ: Date }, ], false), "FindIntentsByContextAgentErrorResponsePayload": o([ - { json: "error", js: "error", typ: r("ErrorMessage") }, + { json: "error", js: "error", typ: r("FindInstancesErrors") }, ], false), "FindIntentsByContextAgentRequest": o([ { json: "meta", js: "meta", typ: r("FindIntentsByContextAgentRequestMeta") }, @@ -5281,7 +5289,7 @@ const typeMap: any = { { json: "destination", js: "destination", typ: u(undefined, r("BridgeParticipantIdentifier")) }, ], false), "FindIntentsByContextAgentRequestPayload": o([ - { json: "context", js: "context", typ: r("ContextElement") }, + { json: "context", js: "context", typ: r("Context") }, { json: "resultType", js: "resultType", typ: u(undefined, "") }, ], false), "FindIntentsByContextAgentResponse": o([ @@ -5310,7 +5318,7 @@ const typeMap: any = { { json: "timestamp", js: "timestamp", typ: Date }, ], false), "FindIntentsByContextBridgeErrorResponsePayload": o([ - { json: "error", js: "error", typ: r("ErrorMessage") }, + { json: "error", js: "error", typ: r("FindInstancesErrors") }, ], false), "FindIntentsByContextBridgeRequest": o([ { json: "meta", js: "meta", typ: r("FindIntentsByContextBridgeRequestMeta") }, @@ -5324,7 +5332,7 @@ const typeMap: any = { { json: "destination", js: "destination", typ: u(undefined, r("BridgeParticipantIdentifier")) }, ], false), "FindIntentsByContextBridgeRequestPayload": o([ - { json: "context", js: "context", typ: r("ContextElement") }, + { json: "context", js: "context", typ: r("Context") }, { json: "resultType", js: "resultType", typ: u(undefined, "") }, ], false), "FindIntentsByContextBridgeResponse": o([ @@ -5354,7 +5362,7 @@ const typeMap: any = { { json: "timestamp", js: "timestamp", typ: Date }, ], false), "GetAppMetadataAgentErrorResponsePayload": o([ - { json: "error", js: "error", typ: r("ErrorMessage") }, + { json: "error", js: "error", typ: r("FindInstancesErrors") }, ], false), "GetAppMetadataAgentRequest": o([ { json: "meta", js: "meta", typ: r("GetAppMetadataAgentRequestMeta") }, @@ -5368,9 +5376,9 @@ const typeMap: any = { { json: "timestamp", js: "timestamp", typ: Date }, ], false), "GetAppMetadataAgentRequestPayload": o([ - { json: "app", js: "app", typ: r("AppDestinationIdentifier") }, + { json: "app", js: "app", typ: r("AppObject") }, ], false), - "AppDestinationIdentifier": o([ + "AppObject": o([ { json: "desktopAgent", js: "desktopAgent", typ: "" }, { json: "appId", js: "appId", typ: "" }, { json: "instanceId", js: "instanceId", typ: u(undefined, "") }, @@ -5401,7 +5409,7 @@ const typeMap: any = { { json: "timestamp", js: "timestamp", typ: Date }, ], false), "GetAppMetadataBridgeErrorResponsePayload": o([ - { json: "error", js: "error", typ: r("ErrorMessage") }, + { json: "error", js: "error", typ: r("FindInstancesErrors") }, ], false), "GetAppMetadataBridgeRequest": o([ { json: "meta", js: "meta", typ: r("GetAppMetadataBridgeRequestMeta") }, @@ -5415,7 +5423,7 @@ const typeMap: any = { { json: "timestamp", js: "timestamp", typ: Date }, ], false), "GetAppMetadataBridgeRequestPayload": o([ - { json: "app", js: "app", typ: r("AppDestinationIdentifier") }, + { json: "app", js: "app", typ: r("AppObject") }, ], false), "GetAppMetadataBridgeResponse": o([ { json: "meta", js: "meta", typ: r("GetAppMetadataBridgeResponseMeta") }, @@ -5444,7 +5452,7 @@ const typeMap: any = { { json: "timestamp", js: "timestamp", typ: Date }, ], false), "OpenAgentErrorResponsePayload": o([ - { json: "error", js: "error", typ: r("OpenErrorMessage") }, + { json: "error", js: "error", typ: r("OpenErrorResponsePayload") }, ], false), "OpenAgentRequest": o([ { json: "meta", js: "meta", typ: r("OpenAgentRequestMeta") }, @@ -5459,7 +5467,7 @@ const typeMap: any = { ], false), "OpenAgentRequestPayload": o([ { json: "app", js: "app", typ: r("AppToOpen") }, - { json: "context", js: "context", typ: u(undefined, r("ContextElement")) }, + { json: "context", js: "context", typ: u(undefined, r("Context")) }, ], false), "AppToOpen": o([ { json: "desktopAgent", js: "desktopAgent", typ: "" }, @@ -5492,7 +5500,7 @@ const typeMap: any = { { json: "timestamp", js: "timestamp", typ: Date }, ], false), "OpenBridgeErrorResponsePayload": o([ - { json: "error", js: "error", typ: r("OpenErrorMessage") }, + { json: "error", js: "error", typ: r("OpenErrorResponsePayload") }, ], false), "OpenBridgeRequest": o([ { json: "meta", js: "meta", typ: r("OpenBridgeRequestMeta") }, @@ -5507,7 +5515,7 @@ const typeMap: any = { ], false), "OpenBridgeRequestPayload": o([ { json: "app", js: "app", typ: r("AppToOpen") }, - { json: "context", js: "context", typ: u(undefined, r("ContextElement")) }, + { json: "context", js: "context", typ: u(undefined, r("Context")) }, ], false), "OpenBridgeResponse": o([ { json: "meta", js: "meta", typ: r("OpenBridgeResponseMeta") }, @@ -5543,7 +5551,7 @@ const typeMap: any = { ], "any"), "PrivateChannelBroadcastAgentRequestPayload": o([ { json: "channelId", js: "channelId", typ: "" }, - { json: "context", js: "context", typ: r("ContextElement") }, + { json: "context", js: "context", typ: r("Context") }, ], false), "PrivateChannelBroadcastBridgeRequest": o([ { json: "meta", js: "meta", typ: r("PrivateChannelBroadcastBridgeRequestMeta") }, @@ -5558,7 +5566,7 @@ const typeMap: any = { ], false), "PrivateChannelBroadcastBridgeRequestPayload": o([ { json: "channelId", js: "channelId", typ: "" }, - { json: "context", js: "context", typ: r("ContextElement") }, + { json: "context", js: "context", typ: r("Context") }, ], false), "PrivateChannelEventListenerAddedAgentRequest": o([ { json: "meta", js: "meta", typ: r("PrivateChannelEventListenerAddedAgentRequestMeta") }, @@ -5719,7 +5727,7 @@ const typeMap: any = { { json: "timestamp", js: "timestamp", typ: Date }, ], false), "RaiseIntentAgentErrorResponsePayload": o([ - { json: "error", js: "error", typ: r("ErrorMessage") }, + { json: "error", js: "error", typ: r("FindInstancesErrors") }, ], false), "RaiseIntentAgentRequest": o([ { json: "meta", js: "meta", typ: r("RaiseIntentAgentRequestMeta") }, @@ -5734,9 +5742,14 @@ const typeMap: any = { ], false), "RaiseIntentAgentRequestPayload": o([ { json: "app", js: "app", typ: r("AppDestinationIdentifier") }, - { json: "context", js: "context", typ: r("ContextElement") }, + { json: "context", js: "context", typ: r("Context") }, { json: "intent", js: "intent", typ: "" }, ], false), + "AppDestinationIdentifier": o([ + { json: "desktopAgent", js: "desktopAgent", typ: "" }, + { json: "appId", js: "appId", typ: "" }, + { json: "instanceId", js: "instanceId", typ: u(undefined, "") }, + ], "any"), "RaiseIntentAgentResponse": o([ { json: "meta", js: "meta", typ: r("RaiseIntentAgentResponseMeta") }, { json: "payload", js: "payload", typ: r("RaiseIntentAgentResponsePayload") }, @@ -5767,7 +5780,7 @@ const typeMap: any = { { json: "timestamp", js: "timestamp", typ: Date }, ], false), "RaiseIntentBridgeErrorResponsePayload": o([ - { json: "error", js: "error", typ: r("ErrorMessage") }, + { json: "error", js: "error", typ: r("FindInstancesErrors") }, ], false), "RaiseIntentBridgeRequest": o([ { json: "meta", js: "meta", typ: r("RaiseIntentBridgeRequestMeta") }, @@ -5782,7 +5795,7 @@ const typeMap: any = { ], false), "RaiseIntentBridgeRequestPayload": o([ { json: "app", js: "app", typ: r("AppDestinationIdentifier") }, - { json: "context", js: "context", typ: r("ContextElement") }, + { json: "context", js: "context", typ: r("Context") }, { json: "intent", js: "intent", typ: "" }, ], false), "RaiseIntentBridgeResponse": o([ @@ -5828,7 +5841,7 @@ const typeMap: any = { { json: "intentResult", js: "intentResult", typ: r("IntentResult") }, ], false), "IntentResult": o([ - { json: "context", js: "context", typ: u(undefined, r("ContextElement")) }, + { json: "context", js: "context", typ: u(undefined, r("Context")) }, { json: "channel", js: "channel", typ: u(undefined, r("Channel")) }, ], false), "Channel": o([ @@ -5872,11 +5885,6 @@ const typeMap: any = { "RaiseIntentResultBridgeResponsePayload": o([ { json: "intentResult", js: "intentResult", typ: r("IntentResult") }, ], false), - "Context": o([ - { json: "id", js: "id", typ: u(undefined, m("any")) }, - { json: "name", js: "name", typ: u(undefined, "") }, - { json: "type", js: "type", typ: "" }, - ], "any"), "ResponseErrorDetail": [ "AccessDenied", "AgentDisconnected", @@ -5945,7 +5953,7 @@ const typeMap: any = { "ConnectionStep6ConnectedAgentsUpdateType": [ "connectedAgentsUpdate", ], - "ErrorMessage": [ + "FindInstancesErrors": [ "AgentDisconnected", "DesktopAgentNotFound", "IntentDeliveryFailed", @@ -5984,7 +5992,7 @@ const typeMap: any = { "GetAppMetadataAgentRequestType": [ "getAppMetadataRequest", ], - "OpenErrorMessage": [ + "OpenErrorResponsePayload": [ "AgentDisconnected", "AppNotFound", "AppTimeout", diff --git a/src/index.ts b/src/index.ts index 3a2d997db..26aca3e69 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,10 +5,13 @@ import { DesktopAgent } from './api/DesktopAgent'; import * as BridgingTypes from './bridging/BridgingTypes'; +import * as BrowserTypes from './api/BrowserTypes'; +//import in order to create a local export that overwrites type exported via ContextTypes +import * as AppIdentifier from './api/AppIdentifier'; export * from './context/ContextTypes'; -//explicit overwrite of conflicting & equivalent export from ContextTypes -export {AppIdentifier} from './api/AppIdentifier'; + +export { AppIdentifier }; export * from './api/AppIntent'; export * from './api/AppMetadata'; export * from './api/Channel'; @@ -16,6 +19,7 @@ export * from './api/ContextMetadata'; export * from './api/DesktopAgent'; export * from './api/DisplayMetadata'; export * from './api/Errors'; +export * from './api/GetAgent'; export * from './api/Icon'; export * from './api/Image'; export * from './api/ImplementationMetadata'; @@ -26,16 +30,19 @@ export * from './api/Methods'; export * from './api/PrivateChannel'; export * from './api/RecommendedChannels'; export * from './api/Types'; +export * from './api/Events' + export * from './context/ContextType'; + export * from './intents/Intents'; -export * from './api/Events' -/* Workaround for conflicts between bridging types and API types +/* Workaround for conflicts between bridging types, browser type and API types and prettier issue with `export * as`. */ export { BridgingTypes }; +export { BrowserTypes }; declare global { interface Window { - fdc3: DesktopAgent; + fdc3?: DesktopAgent; } } diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index b12f05e8e..13cadf52a 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -51,7 +51,8 @@ module.exports={ "plugins": [], "themeConfig": { "prism": { - "additionalLanguages": ["json","csharp"] + "additionalLanguages": ["typescript","javascript","json","csharp"], + "theme": require('prism-react-renderer/themes/vsDark') }, "algolia": { "appId": "YW91L9TW76", @@ -209,6 +210,27 @@ module.exports={ "width": 50, "href": "https://finos.org" } + }, + "mermaid": { + "options": { + "htmlLabels": true, + "markdownAutoWrap": true, + "wrap": true, + "wrappingWidth": 50, + "flowchart": { + "titleTopMargin": 30, + "subGraphTitleMargin": { + "top": 30, + "bottom": 30 + }, + "nodeSpacing": 30, + "rankSpacing": 50, + "diagramPadding": 5, + "useMaxWidth": true, + "htmlLabels": true, + "wrappingWidth": 50 + } + } } } } diff --git a/website/sidebars.json b/website/sidebars.json index 9f3e0d1c6..3b26ad7eb 100644 --- a/website/sidebars.json +++ b/website/sidebars.json @@ -16,13 +16,24 @@ "items": [ "api/spec", "api/supported-platforms", + "api/ref/GetAgent", "api/ref/DesktopAgent", "api/ref/Channel", "api/ref/PrivateChannel", "api/ref/Types", "api/ref/Metadata", "api/ref/Errors", - "api/ref/Events" + "api/ref/Events", + { + "type": "category", + "label": "Desktop Agent Specs", + "items": [ + "api/specs/preloadDesktopAgents", + "api/specs/browserDesktopAgents", + "api/specs/webConnectionProtocol", + "api/specs/desktopAgentCommunicationProtocol" + ] + } ] }, {