diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..27d2dae2b --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +*/node_modules +*.log diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..5395ea795 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +.DS_Store + +node_modules + +lib/core/metadata.js +lib/core/MetadataBlog.js + +website/translated_docs +website/build/ +website/yarn.lock +website/node_modules +website/i18n/* diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..c6a649a2a --- /dev/null +++ b/.travis.yml @@ -0,0 +1,14 @@ +# .travis.yml +language: node_js +node_js: + - '8' +branches: + only: + - master +cache: + yarn: true +script: + - git config --global user.name "${GH_NAME}" + - git config --global user.email "${GH_EMAIL}" + - echo "machine github.com login ${GH_NAME} password ${GH_TOKEN}" > ~/.netrc + - cd website && yarn install && GIT_USER="${GH_NAME}" yarn run publish-gh-pages \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..d369844d5 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,10 @@ +FROM node:8.11.4 + +WORKDIR /app/website + +EXPOSE 3000 35729 +COPY ./docs /app/docs +COPY ./website /app/website +RUN yarn install + +CMD ["yarn", "start"] diff --git a/README.md b/README.md index 41802a5b5..764923a76 100644 --- a/README.md +++ b/README.md @@ -1,38 +1,108 @@ -# FDC3 Charter +# Example Single FDC3 Repository and Website -### Summary -The mission of the Financial Desktop Connectivity and Collaboration Consortium (FDC3) is to develop specific protocols and taxonomies to advance the ability of desktop applications in financial workflows to interoperate in a plug-and-play fashion and without prior, bi-lateral agreements. +[![Build Status](https://travis-ci.com/rikoe/FDC3.svg?branch=master)](https://travis-ci.com/rikoe/FDC3) +[![FINOS - Incubating](https://cdn.rawgit.com/finos/contrib-toolbox/master/images/badge-incubating.svg)](https://finosfoundation.atlassian.net/wiki/display/FINOS/Incubating) -### Scope -Financial Desktop applications include any desktop application used in common financial workflows: +This repository demonstrates using [Docusaurus](https://docusaurus.io) to author and host the FDC3 website and documentation, based on markdown files. -* Traditional native applications implemented in C++, .NET, Java, Python, etc -* Hybrid web/native applications - stand alone native apps embedding Chromium (e.g. Electron, CEF, NW.js) -* Desktop Web Applications - platform based apps extending Chromium (e.g. OpenFin, Hosted Web Apps) -* Common desktop applications not specific to finance, but critical to workflows - such as Excel, Outlook, etc. -* Web Applications running in a commercial browser +## Plan -This standards group is focused specifically on the desktop. Activities of the desktop interoperability group do not include: +- [x] Try out Docusaurus +- [x] Host on GitHub Pages +- [x] Attempt to apply styling and assets from https://fdc3.finos.org to this website +- [x] Copy docs from other FDC3 repositories into this single repository +- [x] Setup CI +- [ ] Copy code/examples from other FDC3 repositories +- [ ] Add docs from use cases +- [ ] Integrate OpenAPI docs for app directory (redoc?) +- [ ] Integrate generated TS docs for API +- [ ] API reference +- [ ] Intent reference +- [ ] Versioning +- [ ] About page +- [ ] Community page +- [ ] Extra documentation content +- [ ] Tutorial content +- [ ] FINOS/Working group info +- [ ] Finalise styling and assets +- [ ] GitHub README must adhere to FINOS standard +- [ ] Present to PMC -* Defining financial objects - where existing standards are well established -* Interoperability between mobile apps -* Interoperability via REST or other client to server communication -Note: While these areas are out of scope, compatibility with Mobile and/or REST are still valid points of consideration for the FDC3. +For more detail, see the [FINOS FDC3 1.0 Release Public Launch Documentation Sub-Plan](https://finosfoundation.atlassian.net/wiki/spaces/FDC3/pages/711950361/FDC3+1.0+Release+Public+Launch+Documentation+Sub-Plan). -### Success Criteria -* Commitment from major banks and application vendors to support the standards set by the FDC3 -* Workflow integrations in the wild leveraging the standards +## Developer Information -### Deliverables -* Define criteria and mechanics for secure communication between apps -* Define key functions that require specific standards for interoperability -* Create an agreed taxonomy for common app “intents” within financial desktop workflows -* Create an agreed taxonomy for common data to be shared across apps within financial desktop workflows -* Provide reference implementations of all standards -* Maintain the above standards and reference implementations +The included example website was generated by following the [Docusaurus installation steps](https://docusaurus.io/docs/en/installation). -### Participation -To be successful, the FDC3 is expected to have a critical mass of active participants for its duration. Effective participation in the FDC3 means participation in the form of research, authoring, editing, and development activities outside the scope of attending regular meetings. +### Required tools -### Licensing -The FDC3 will use Apache2 license or similar for all deliverables. +* NodeJS 8+ [[Install](https://nodejs.org/en/download/)] +* Yarn 1.5+ [[Install](https://yarnpkg.com/lang/en/docs/install/)] +* Docker (for running locally) [[Install](https://www.docker.com/get-started)] + +### Structure + +The repository follows the standard Docusaurus website structure. For more information, see [Creating your site](https://docusaurus.io/docs/en/site-creation). + +``` +root-directory +├── docs +└── website + ├── blog + ├── core + │ └── Footer.js + ├── package.json + ├── pages + ├── sidebars.json + ├── siteConfig.js + └── static +``` + +### Running the website locally + +1. Navigate to the `website` folder: + ``` + cd website + ``` + +2. Run the local web server: + ``` + yarn start + ``` + +3. Navigate to the website: http://localhost:3000 + +### Publishing to GitHub Pages + +The following properties were added to `website/siteConfig.js`: + +```js +const siteConfig = { + url: 'https://rikoe.github.io', + baseUrl: '/FDC3/', + projectName: 'FDC3', + organizationName: 'rikoe' +} +``` + +To publish the website, follow this steps: + +1. Navigate to the `website` folder: + ``` + cd website + ``` + +2. Publish: + ``` + GIT_USER= USE_SSH=true yarn run publish-gh-pages + ``` + +This will publish to the `gh-pages` branch of the repository, which will automatically be hosted on GitHub Pages. + +### Continuous Integration + +The CI build is hosted on Travis CI at https://travis-ci.com/rikoe/FDC3. When new changes are committed to `master`, Travis will automatically deploy an updated version of the website to GitHub Pages. + +> For full documentation about publishing Docusaurus websites, see [Publishing your site](https://docusaurus.io/docs/en/publishing). + +> For more information about GitHub Pages, see [GitHub's FAQ](https://help.github.com/articles/user-organization-and-project-pages/). \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..6711192ae --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,18 @@ +version: "3" + +services: + docusaurus: + build: . + ports: + - 3000:3000 + - 35729:35729 + volumes: + - ./docs:/app/docs + - ./website/blog:/app/website/blog + - ./website/core:/app/website/core + - ./website/i18n:/app/website/i18n + - ./website/pages:/app/website/pages + - ./website/static:/app/website/static + - ./website/sidebars.json:/app/website/sidebars.json + - ./website/siteConfig.js:/app/website/siteConfig.js + working_dir: /app/website diff --git a/docs/api-findIntent.md b/docs/api-findIntent.md new file mode 100644 index 000000000..6d4fbe541 --- /dev/null +++ b/docs/api-findIntent.md @@ -0,0 +1,7 @@ +--- +id: api-findIntent +sidebar_label: findIntent +title: findIntent +hide_title: true +--- +# `findIntent` diff --git a/docs/api-intro.md b/docs/api-intro.md new file mode 100644 index 000000000..df15c0889 --- /dev/null +++ b/docs/api-intro.md @@ -0,0 +1,19 @@ +--- +id: api-intro +sidebar_label: API Overview +title: API Overview +hide_title: true +--- +# API Overview + +API Working Group repository. + +See the [specification draft](api-spec.md) for the current working documentation, and the [FDC3 Confluence page](https://finosfoundation.atlassian.net/wiki/spaces/FDC3) for further information. + +## Development + +``` +yarn install +``` + +When making changes to the TypeScript interfaces, run `yarn test` to ensure there are no syntax errors, and `yarn run doc` to regenerate the documentation. \ No newline at end of file diff --git a/docs/api-spec.md b/docs/api-spec.md new file mode 100644 index 000000000..65c6614f9 --- /dev/null +++ b/docs/api-spec.md @@ -0,0 +1,144 @@ +--- +id: api-spec +sidebar_label: API Specification +title: API Specification +hide_title: true +--- + +# API Specification (Draft) + +## Overview +FDC3 API standards support the following goals: +- Create consistent developer interface for working with FDC3 +- Standardize interfaces for reference implementations +- Standardize interfaces between Desktop Agents + +The role of FDC3 API standards is to establish a baseline interface for interoperability between applications. Because FDC3 is largely an agreement between existing platforms and applications - standards should be optimized for ease of adoption rather than functional completeness. Functionality absent from a FDC3 specification is in no way commentary its importance. + +## 1. Components +### 1.1 Desktop Agent +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. A Desktop Agent can be connected to one or more App Directories and will use directories for application identity and discovery. Typically, a Desktop Agent will contain the proprietary logic of a given platform, handling functionality like explicit application interop workflows where security, consistency, and implementation requirements are proprietary. + +Examples of Desktop Agents include: + +- OpenFin +- Autobahn +- ThomsonReuters Eikon + +Desktop Agents expose an FDC3 standard API to applications they have launched. When an App is launched by a Desktop Agent and is given access to the Agent's API to interoperate, it is running in that Desktop Agent's *context*. + +![Desktop Agent - Standards Schematic](assets/api-1.png) + +The surface area of FDC3 standardization (shown in *white* above) itself is quite small in comparison to the extent of a typical desktop agent implementation (in *grey*). + +For example: +- 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. + +#### 1.1.1 Inter-Agent Communication +A goal of FDC3 standards is that applications running in different Desktop Agent contexts on the same desktop 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. + +![Desktop Agent - Interop](assets/api-2.png) + +Desktop Agent interop is supported by common standards for APIs for App discovery and launching. So, an App in one Desktop Agent context would not need to know a different syntax to call an App in another Desktop Agent context. + +The actual connection protocol between Desktop Agents is not currently in scope for FDC3 standards. Given that there are a relatively small number of Desktop Agents, and that any given desktop will have a finite and relatively static number of Desktop Agents installed at any given time, the connectivity between different Agents can be adequetly handled for the time being on a case-by-case basis. + +### 1.2 Application +An application is any endpoint on the desktop that is: +- Registered with/known by a Desktop Agent +- Launchable by a Desktop Agent +- Addressable by a Desktop Agent + +Examples of End Points include: +- Native Applications +- PWA/Web Applications +- Headless “services” running on the desktop + +## 2. Functional Use Cases +### 2.1 Open an Application by Name +Linking from one application to another is a critical basic workflow that the web revolutionized via the hyperlink. Supporting semantic addressing of applications across different technologies and platform domains greatly reduces friction in linking different applications into a single workflow. + +### 2.2 Raising Intents +Often, we want to link from one app to another to dynamically create a workflow. Enabling this without requiring prior knowledge between apps is a key goal of FDC3. + +Intents provide a way for an app to request functionality from another app and defer the discovery and launching of the destination app to the Desktop Agent. There are multiple models for interop that Intents can support. + +- **Chain**: In this case the workflow is completely handed off from one app to another (similar to linking). Currently, this is the primary focus in FDC3 +- **Client-Service**: A Client invokes a Service via the Intent, the Service performs some function, then passes the workflow back to the Client. Typically, there is a data payload type associated with this intent that is published as the standard contract for the intent. +- **Remote API**: An app wants to remote an entire API that it owns to another App. In this case, the API for the App cannot be standardized. However, the FDC3 API can address how an App connects to another App in order to get access to a proprietary API. + +#### 2.2.1 Intent Resolution +Raising an Intent will return a Promise-type object that will resolve/reject based on a number of factors. + +##### 2.2.1.1 Resolve +- Intent was resolved unambigiously and the recieving app was launched successfully. +- Intent was ambigious, a resolution was chosen by the end user and the chosen application was launched succesfully. + +##### 2.2.1.2 Reject +- An app matching the intent was not found. +- A match was found, but the recieving app failed to launch. +- The intent was ambiguous and the resolver experienced an error. + +##### 2.2.1.3 Resolution Object +If the raising of the intent resolves (or rejects), a standard object will be passed into the resolver function with the following format: + +```javascript +{ + source: String; + data?: Object; + version: String; +} +``` +- *source* = identifier for the Application resolving the intent (null if the intent could not be resolved) +- *data* = return data structure - if one is provided for the given intent +- *version* = the version number of the Intents schema being used + +For example + +```javascript +try { + let result = await agent.raiseIntent('StageOrder'); + if (result.data){ + let orderId = result.data.id; + } +} +catch (er){ + console.log(er.message); +} + +``` + +##### 2.2.1.4 Upgrading to a Remote API Connection +There are a wide range of workflows where decoupled intents and/or context passing do not provide rich enough interactivity and applications are better off exposing proprietary APIs. In these cases, an App can use the *source* propoerty on the resolution of an intent to connect directly to another App and from there, call remote APIs using the methods available in the Desktop Agent context for the App. For example: + +```javascript + let chart = await agent.raiseIntent('ViewChart'); + //construct an OpenFin wrapper for the App + let chartApp = fin.Application.wrap(chart.source); + //do some OpenFin specific stuff +``` +![Upgrading Connection to Remote API](assets/api-3.png) + +### 2.3 Register an Intent +Applications need to let the system know the Intents they can support. Typically, this is done via registration with the App Directory. It is also possible for Intents to be registered at the application level as well to support ad-hoc registration which may be helpful at development time. While, dynamic registration is not part of this specification, a Desktop Agent agent may choose to support any number of registration paths. + +#### 2.3.1 Compliance with Intent Standards +Intents represent a contract with expected behavior if an app asserts that it supports the intent. Where this contract is enforcable by schema (for example, return object types),the FDC3 API implementation should enforce compliance and return an error if the interface is not met. + +It is expected that App Directories will also curate listed apps and ensure that they are complying with declared intents. + +Like FDC3 Context Data, the Intent schemas need to be versioned. Desktop Agents will be responsible to declare which version of the Intent schema they are using. Applications may also assert a specific version requirement when raising an Intent. Version negotation may be supported by a given Desktop Agent. + +### 2.4 Send/broadcast context +On the financial desktop, applications often want to broadcast context to any number of applications. Context sharing needs to support concepts of different groupings of applications as well as data privacy concerns. Each Desktop Agent will have its own rules for supporting these features. + +## 3. Resolvers +Intents functionality is dependent on resolver functionality to map the intent to a specific App. This will often require end-user input. Resolution can either be performed by the Desktop Agent (raising UI to pick the desired App for the intent) or by the app launching the intent - in which case the calling App will handle the resolution itself (using the findIntents API below) and then invoke an explicit Intent object. + +## 4. APIs +The APIs are defined in TypeScript in the [src](/src), with documentation generated in the [docs](/docs) folder. \ No newline at end of file diff --git a/docs/appd-discovery.md b/docs/appd-discovery.md new file mode 100644 index 000000000..d9ab567b1 --- /dev/null +++ b/docs/appd-discovery.md @@ -0,0 +1,151 @@ +--- +id: appd-discovery +sidebar_label: App Directory Discovery +title: App Directory Discovery +hide_title: true +--- + +# App Directory Discovery + +## Simple Definition + +The App Directory (AppD) is a service that provides a financial application definition that includes a trusted identifier(s) and associated metadata. The information registered as part of an application definition supports discovery, launch configuration, intents and context data supporting the use and interoperability of financial applications. + +## Topology + +AppD services shall support a distributed or detached model to managing application data servicing, where there are (N) AppD services on a network providing information related to a subset of namespace "zones" that align with the financial application identifiers. This approach encourages independence, scale and responsive provisioning of application definitions. This is modeled from a subset of the public name service "Domain Name System", which has proven reliable and conceptually fit for discovery. + +## Service Discovery Approach + +In order to support the discovery of application data stored in a given directory, name space concepts are introduced to both identify the realm of application definitions and AppD service locations that host data. In simple terms, there has to be a way of discovering the location of the AppD service itself and the associated application definitions that are available from that service. + +### Application Identifier + +- Application data discovery through nested namespace approach and email address construction (**name@fqdn**) defining the application identifier as the name part and AppD location as the fully qualified domain name part. The entire address should be considered the fully qualified application ID. + +### Resolving host system + +- AppD service host discovery implementations should support the following requirements; + 1. Discovery of the AppD location using the fully qualified application ID domain name. This would be the fqdn part of the email structure. + 2. Discovery of the AppD location using the fully qualified application ID domain name to lookup DNS SRV records identifying the host server location and access TCP port. ([RFC2782](https://tools.ietf.org/html/rfc2782) ) + 3. Statically defined URI records for use within client applications directly. This is similar to #1 above, but provides explicit protocol, port and url definitions as part of the defintion. + +**Examples:** + +*AppD service through DNS / SRV records:* + +![img](https://finosfoundation.atlassian.net/wiki/download/thumbnails/129597550/appd_srv.png?version=1&modificationDate=1530189735237&cacheVersion=1&api=v2&width=958&height=250) + +AppD Service distribution visual: + +![img](https://finosfoundation.atlassian.net/wiki/download/thumbnails/129597550/AppDServiceDistribution.png?version=1&modificationDate=1526307911273&cacheVersion=1&api=v2&width=498&height=250) + +## Application data discovery + +Application data discovery shall be accessible through a unique application identifier (AppId) representing a single application represented by a nested namespace syntax using dot notation and email address construction (**name@fqdn**) defining the application identifier as the name part and AppD location as the fully qualified domain name part. The entire address should be considered the fully qualified application ID. + +**Example:** + +``` + +getAppData("app@sub.root") + + Application { + "appId": "app@sub.root", + "name": "App Name", + "manifest": "https://sub.root/app_manifest.json", + "manifestType": "vendor_type", + "version": "1", + "title": "A very cool App", + "tooltip": "A very cool app really", + "description": "Yes..this is the coolest app ever..", + "images": [ + { + "url": "string" + } + ], + "contactEmail": "string", + "supportEmail": "string", + "publisher": "string", + "icons": [ + { + "icon": "string" + } + ], + "customConfig": [ + { + "name": "string", + "value": "string" + } + ], + "intents": [ + { + "name": "string", + "displayName": "string", + "contexts": [ + "string" + ], + "customConfig": {} + } + ] + } + + +``` + +## Service Discovery (Expanded) + +The following represents the three ways AppD service instances should be discovered over a given network. Again, the view is that AppD services are distributed/decoupled based on associated application namespace on a given network. This takes into account the use of the application identifiers described in previous section. A launcher is required to use a URI (e.g. "https://appd.foo.com/api/appd/app1@appd.foo.com") to query a given directory instance for data. In order to construct a URI, the host location and port of a given AppD service instance is required. This proposal focuses on the following approaches to achieve this resolution. + +### Application ID namespace syntax host resolution + +An application directory URI can be constructed using a fully qualified application ID (email address syntax) by using fqdn part of the ID as the host location and the name part as the application name. Given an application name "app1" with a fully qualified identifier of "app1@appd.foo.com" an application directory host location can be derived by simply extracting the fqdn "appd.foo.com" from the email syntax. The extracted fqdn "app.foo.com" may resolve to the actual host location where the application directory is running. + +A launcher can then easily construct a URI by; + +1. URI protocol is defaulted to https, but can be overridden by the launcher. +2. URI hostname is the fully qualified domain of the application ID. +3. URI port is default https/443, but can be overridden by the launcher +4. URI url is by default "/api/**(service)/(version)" .** It is recommended that we identify service label as "**appd**" with version being optional. Calls that are made without version automatically default to latest "/api/appd/app1" vs "/api/appd/v1/app1" + +The resulting URI to retrieve application data for "app1" would be "[https://appd.foo.com/api/appd/v1/app1@appd.foo.com](https://appd.foo.com/api/appd/v1/app1.appd.foo.com)" + +### Application identifiers, Shrinking the URI and AppdD defaults + +Although the concept of fully qualified application IDs are useful in resolving the actual host of the application directory, there is no requirement for an application directory to use this fully qualified application ID as the resolver for a record. An application ID is unique to given application directory, but there is no requirement to use the fully qualified representation when querying an interface. Taking the prior example, the fully qualified application ID "app1@appd.foo.com" is represented as "app1" within the application directory. As a result a launcher can use a shortened URI construct "" to resolve the application data vs "https://appd.foo.com/api/appd/app1@appd.foo.com". + +### DNS/SRV Records + +Another approach to support AppD service discovery (resolution) is through use of existing domain name service (DNS) implementations that are broadly used on the Internet today (see: [RFCs](https://www.isc.org/community/rfcs/dns/)). Name service implementations can be considered critical infrastructure and are proven stable with over twenty years of use. Name services can be used both through public Internet or locally deployed intranet, which provides optionality to deployment schemes. + +More specifically, resolution of an AppD service instance (host location) can be implemented using DNS "service records" (SRV) providing the host instance, protocol and associated port. The following is a well known description of a SRV record ([RFC2782](https://tools.ietf.org/html/rfc2782)): + +``` + zone name { _service._proto.name. TTL class SRV priority weight port target.} +``` + +- *service*: the symbolic name of the desired service. For AppD service, this mus be identified as "**_appd**" +- *proto*: the transport protocol of the desired service; this is usually either [TCP](https://en.wikipedia.org/wiki/Transmission_Control_Protocol) or [UDP](https://en.wikipedia.org/wiki/User_Datagram_Protocol). For AppD service **_tcp** must be used. +- *name*: the domain name for which this record is valid, ending in a dot. For AppD service, the name should directly map to the application identifier domain. +- *TTL*: standard DNS [time to live](https://en.wikipedia.org/wiki/Time_to_live) field. +- *class*: standard DNS class field (this is always *IN*). +- *priority*: the priority of the target host, lower value means more preferred. +- *weight*: A relative weight for records with the same priority, higher value means more preferred. +- *port*: the TCP or UDP port on which the service is to be found. For AppD service, TCP should always be used. +- *target*: the canonical hostname of the machine providing the service, ending in a dot. This would be the host where the AppD service is running. + +For AppD Service the SRV record **must use** the following definitions: + +- service = **_appd** +- proto = **_tcp** +- name = must map to the domain of the application identifier . Example: the **name** for application identifier **"app1.appd.foo.com"** would be **"appd.foo.com"** + +**Known domains:** + +Although SRV records provide the means of resolving the location of an AppD service for a specific domain, there could be a need to know what domains exist in the universe. This would be a list of domains representing all known directory instances. It is recommended that the FDC3/FINOS organization publish a list of known domains which support AppD services. This publication can be handled in multiple ways, such as structured files or API endpoints. This proposal shall not provide a qualified solution to achieve this, but rather draw attention to a potential requirement. + +### Static configuration + +As the name implies, a static configuration for the AppD service location is predefined within the launcher following the same domain:URI model mentioned in previous sections. + +![img](https://finosfoundation.atlassian.net/wiki/download/thumbnails/129597550/StaticConfig.png?version=1&modificationDate=1526330937517&cacheVersion=1&api=v2&width=800&height=376) \ No newline at end of file diff --git a/docs/appd-intro.md b/docs/appd-intro.md new file mode 100644 index 000000000..797869ac7 --- /dev/null +++ b/docs/appd-intro.md @@ -0,0 +1,24 @@ +--- +id: appd-intro +sidebar_label: App Directory Overview +title: App Directory Overview +hide_title: true +--- + +# App Directory Overview + +The FDC3 App Directory provides trusted identity for financial desktop apps. This identity can be used to prevent spoofing and man-in-the-middle attacks when apps communicate with one another and exchange data. The App Directory also enables service discovery. Apps are registered with a declaration of the intents and context data that can be used when interoperating. + +## Core features + +- Provide verification of identity for an application running on a desktop - whether it is Native, Web, or Hybrid. +- Resolve human readable names for applications to the location of and instructions for launching +- Serve as a repository for application metadata supporting discoverability by intent, context, and other workflow driven facets. + +## Sections to review + +- [Application Directory Discovery](appd-discovery.md) describes how to resolve the location of the Application Directory using an application identifier. +- [Application Directory Use](appd-use.md) provides a simple view on how application directories can be used. This also includes links to a reference implementation. +- [API specification](/appd-specification) is the interface definition required to support a compatible application directory. + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14, [RFC 2119](https://tools.ietf.org/id/draft-faltstrom-uri-11.html#RFC2119) [RFC2119]. \ No newline at end of file diff --git a/docs/appd-spec.md b/docs/appd-spec.md new file mode 100644 index 000000000..28ef5ded2 --- /dev/null +++ b/docs/appd-spec.md @@ -0,0 +1,8 @@ +--- +id: appd-spec +sidebar_label: App Directory Specification +title: App Directory Specification +hide_title: true +--- + +# App Directory Specification (Draft) \ No newline at end of file diff --git a/docs/appd-use.md b/docs/appd-use.md new file mode 100644 index 000000000..c74ce01d4 --- /dev/null +++ b/docs/appd-use.md @@ -0,0 +1,98 @@ +--- +id: appd-use +sidebar_label: App Directory Use +title: App Directory Use +hide_title: true +--- + +# App Directory Use + +An application directory (AppD) provides information about an applications +identifiers, intents that provide contexts, and location of metadata providing +information specific to the launching and integration of the application. + + +In the real world the AppD would support many use cases as defined in the +[FDC3 Use Cases](https://finosfoundation.atlassian.net/wiki/spaces/FDC3/pages/551714819/2.+ACCEPTED+Use+Cases) + +The following provides some common use cases and benefits. + +## Embedded Launcher ### +A desktop application has the ability to launch (or initialize) an application +by retrieving all necessary data via a REST call(s) to an AppD service +and metadata location. As described in the [AppD Discovery](/AppD_Discovery) +section, this call requires an application identifier (app1@host.appd.com), +which can be used to both locate the AppD service and key to retrieve the +specific application data. The resulting application data will contain +data describing the application and the metadata URI or the actual +metadata in json format. If the metadata is a URI, the launcher would +retrieve the metadata file from the URI. + +![img](assets/appd_launcher_embedded.png) + + +## Standalone Launcher ### + +In more advanced cases, there could be a need to execute different types +of desktop applications, such as web browser or general native application +(exe, binary). A common approach to support this pattern would be to + create a standalone launcher application that has the ability to query + application data from the AppD and executes the desktop application that + can run the required application. This is also convenient if you wanted + to display all possible applications to launch in a single view. + +![img](assets/appd_launcher_standalone.png) + + +## Aggregated View ### + +There could be many different AppD service instances in the world providing +application data zoned to the provider or enterprise deployment. The +AppD specification allows for unique instances of the service with no +requirement to aggregate data or define a structured hierarchy. With this +said, a launcher might want to construct an aggregated view of applications +from one or more AppD instances. In this case, the launcher would be +required to retrieve multiple application definitions from one or more +AppD instances providing a consolidated view of all applications required. + Today there is no intention to create a single registry of known AppD + instances, so there is an assumption that the launcher will have prior + knowledge of the AppD instance location (FQDN). + +![img](assets/appd_launcher_aggregated.png) + + +## Enhancing controls ### + +The AppD API specification defines the optional use of an access token to +identify the requesting user/launcher and implement authorizations around +AppD actions can be performed. Actions are considered standard CRUD operations. +Again the specification does not define or make mandatory any authorizations +or roles that a provider or enterprise can define. + +With this said, it is highly recommended that the implementation take advantage + and utilize an access token to support these controls. In most cases simple + use of roles like "admin" and "user" would be adequate to create separation + between producer and consumer. + + Alternatively a more open approach can be defined, where producers of a new + definition are automatically set to "owner" of the the definition. + + In more advanced use cases, actual entitlements can be applied to limit + access to specific applications and associated actions based on the source + user/launcher identity. + + In all examples, it is up to the implementation to define and engineer the solution + based on individual requirements. There are too many variations in approach + and technology to define a single specification. + + + +## Reference Implementation ### + +### AppD POC #### +Please view readme on the [AppD POC GitHub](https://github.com/FDC3/appd-poc) . + + +### Launcher #### + +TBD \ No newline at end of file diff --git a/docs/assets/api-1.png b/docs/assets/api-1.png new file mode 100644 index 000000000..15b686461 Binary files /dev/null and b/docs/assets/api-1.png differ diff --git a/docs/assets/api-2.png b/docs/assets/api-2.png new file mode 100644 index 000000000..9b1c94900 Binary files /dev/null and b/docs/assets/api-2.png differ diff --git a/docs/assets/api-3.png b/docs/assets/api-3.png new file mode 100644 index 000000000..4b6735bb6 Binary files /dev/null and b/docs/assets/api-3.png differ diff --git a/docs/assets/appd_launcher_aggregated.png b/docs/assets/appd_launcher_aggregated.png new file mode 100644 index 000000000..62071004b Binary files /dev/null and b/docs/assets/appd_launcher_aggregated.png differ diff --git a/docs/assets/appd_launcher_embedded.png b/docs/assets/appd_launcher_embedded.png new file mode 100644 index 000000000..8283fc102 Binary files /dev/null and b/docs/assets/appd_launcher_embedded.png differ diff --git a/docs/assets/appd_launcher_standalone.png b/docs/assets/appd_launcher_standalone.png new file mode 100644 index 000000000..8742e06cc Binary files /dev/null and b/docs/assets/appd_launcher_standalone.png differ diff --git a/docs/context-intro.md b/docs/context-intro.md new file mode 100644 index 000000000..070729680 --- /dev/null +++ b/docs/context-intro.md @@ -0,0 +1,68 @@ +--- +id: context-intro +sidebar_label: Context Data Overview +title: Context Data Overview +hide_title: true +--- + +# Context Data Overview + +Context data object specifications, schemas, and examples: + +* Extending APIs from one App to another is powerful... +* However, it requires building to a specific API ahead of time +* Standard context and intent definitions let us create workflows on the fly + +FDC3 Context Data defines a standard way to pass common identifiers and data between apps to create a seamless workflow. FDC3 Context Data is not a symbology solution and is not specifically focused on modeling financial objects. The focus is on providing a standard payload structure that can be used to establish a lowest common denominator for interoperability. + +Context objects are used when [declaring]() and [raising]() intents, and when [broadcasting]() context to other applications. + +## Context Object + +Context can be summarised as: +* Having a unique _type_ identifier, used for routing. +* Optionally providing a name. +* Optionally providing a map of equivalent identifiers. +* Any other properties or metadata. +```typescript +interface Context { + type: string; + name?: string; + id?: { + [x:string]: string; + }, + [x: string]: any; +} +``` +## Example Context Object + +An instrument could for example be derived as (note that the name is required and the type is fixed): + +```typescript +interface Instrument extends Context { + type: 'fdc3.instrument', + name: string; + id: { + ticker?: string; + ISIN?: string; + CUSIP?: string; + } +} +``` + +E.g. as a JSON payload: + +```json +{ + "type" : "fdc3.instrument", + "name" : "Apple", + "id" : + { + "ticker" : "aapl", + "ISIN" : "US0378331005", + "CUSIP" : "037833100" + }, + "country": "US" +} +``` + It is important to note that the context data specification allows extra identifiers and properties to be added as needed for each interop use case. In the example above, "country" could represent extra metadata in addition to the agreed instrument representation. diff --git a/docs/context-spec.md b/docs/context-spec.md new file mode 100644 index 000000000..e7bacae18 --- /dev/null +++ b/docs/context-spec.md @@ -0,0 +1,159 @@ +--- +id: context-spec +sidebar_label: Context Data Specification +title: Context Data Specification +hide_title: true +--- + +# Context Data Specification (Draft) + +## Introduction + +To interoperate, apps need to exchange commonly recognized context structures that can indicate topic with any number of identifiers or mappings to different systems. + +Exchanging context is the most basic entry point to desktop interoperability. The barriers to adoption for this interaction must be kept as low as possible. + +There are two main use case for exchanging context data: + +* __Transmitting reference data between applications.__ + The source application will send as many known identifiers as possible, and the target application will try to match the entity based on the identifiers. It may then choose to map to its own internal domain representation for rendering purposes. + + An example of this is sending an instrument or contact, when only an ISIN or email is required to reference the same data in another application. + +* __Transferring information between applications.__ + The source application may have data required to compose a workflow with another application, e.g. a list of contacts that have been selected, or a complex object representing an RFQ request. + + In many such cases there isn't any sensible reference identifiers that can be shared, it is instead the data itself being transferred. + +## Assumptions + +1. Context data objects are identified and routed according to their type, which is unique. +2. Any names, identifiers or extra properties are optional. +3. More complex objects can be composed from simpler objects by defining a new type, e.g a position from an instrument and a holding amount. +4. If multiple pieces of data needs to be sent, an embbedded array can be used, identified as a collection type, e.g. "contactList" or "portfolio". This allows for extra metadata and data relationships to be expressed. +5. There needs to be a way to reference or look up the structure of well-known context types, e.g. from a directory. + +## Other Standard + +FDC3 recognizes that there are other object definitions for providing context between applications. Most, if not all of these definitions though are platform-specific. FDC3, as a rule, sets out to be platform-agnostic and focused on creating bridges between the various walled gardens on the financial desktop. + +## The Context Interface + +```ts +interface Context { + type: string; + name?: string; + id?: { + [x:string]: string; + }, + [x: string]: any; +} +``` + +### Examples ### + +__Note:__ The below examples show how the base context data interface can be used to define specific context data objects. It is not the purpose of the specification at this stage to define standard representations for objects. It establishes the framework in which such definitions could be created. + +#### Instrument #### +```json +{ + "type" : "fdc3.instrument", + "name" : "Apple", + "id" : + { + "ticker" : "aapl", + "ISIN" : "US0378331005", + "CUSIP" : "037833100", + "FIGI" : "BBG000B9XRY4", + } +} +``` +#### Contact #### +```json +{ + "type": "fdc3.contact", + "name": "Nick Kolba", + "id":{ + "email": "nick@openfin.co", + "twitter": "nkolba", + "phone": "9171234567" + } +} +``` +#### Organization #### +```json +{ + "type": "fdc3.organization", + "name": "IBM", + "id": { + "PERMID" : "4295904307", + "LEI" : "VGRQXHF3J8VDLUA7XE92" + } +} +``` +#### ContactList #### +```json +{ + "type": "fdc3.contactList", + "contacts": [ + { + "type" : "fdc3.contact", + "name":"Nick Kolba", + "id":{ + "email": "nick@openfin.co" + } + }, + { + "type" : "$fdc3.contact", + "name":"Espen Overbye", + "id":{ + "email": "espen@openfin.co" + } + } + ] +} +``` +#### Position #### +```json +{ + "type": "fdc3.position", + "instrument": { + "type" : "fdc3.instrument", + "name" : "Apple", + "id" : + { + "ISIN" : "US0378331005" + } + }, + "holding": 500 +} +``` + +### Namespacing ### + +All well-known types at FDC3 level should be prefixed with `fdc3`. For private type definitions, or type definitions issued by other organisations, different namespaces can be used, e.g. `blackrock.fund`, etc. + +### Versioning ### + +The specification recognises that evolving context data definitions over time, and helping applications to deal with changes to types, are very important. + +It may be as simple as adding an optional `$version` property to types, but it could also be a set of guidelines for adding new properties, without removing or changing existing ones. For example, web technologies like REST or GraphQL does not take a particular opinion about versioning. + +### Identifiers ### + +Where an identifier is the name of an existing standard, external to FDC3, it is represented in all caps. For example: FIGI, PERMID, CUSIP, ISO-2. When an identifer is a more general concept, it is represented in all lower case. For example: ticker, name, geocode, email. + +All standard identifier names are reserved names. Applications may use their own identifiers ad hoc. For example: +```json +"id": { + "CUSIP":"037833100", + "foo":"bar" +} +``` +The identifier "foo" is proprietary, an application that can use it is free to do so. However, since multiple applications may want to use the "foo" name and may use it to mean different things, there is a need for applications to ensure that their identifiers use naming conventions that will avoid collision. The recommended approach here is to prefix the identifier name with a namespace. For example: +```json +"id": { + "CUSIP":"037833100", + "com.factset.symbology.entity": "000C7F-E" +} +``` \ No newline at end of file diff --git a/docs/fdc3-charter.md b/docs/fdc3-charter.md new file mode 100644 index 000000000..1284dac08 --- /dev/null +++ b/docs/fdc3-charter.md @@ -0,0 +1,45 @@ +--- +id: fdc3-charter +sidebar_label: Charter +title: FDC3 Charter +hide_title: true +--- + +# FDC3 Charter + +## Summary +The mission of the Financial Desktop Connectivity and Collaboration Consortium (FDC3) is to develop specific protocols and taxonomies to advance the ability of desktop applications in financial workflows to interoperate in a plug-and-play fashion and without prior, bi-lateral agreements. + +## Scope +Financial Desktop applications include any desktop application used in common financial workflows: + +* Traditional native applications implemented in C++, .NET, Java, Python, etc +* Hybrid web/native applications - stand alone native apps embedding Chromium (e.g. Electron, CEF, NW.js) +* Desktop Web Applications - platform based apps extending Chromium (e.g. OpenFin, Hosted Web Apps) +* Common desktop applications not specific to finance, but critical to workflows - such as Excel, Outlook, etc. +* Web Applications running in a commercial browser + +This standards group is focused specifically on the desktop. Activities of the desktop interoperability group do not include: + +* Defining financial objects - where existing standards are well established +* Interoperability between mobile apps +* Interoperability via REST or other client to server communication +Note: While these areas are out of scope, compatibility with Mobile and/or REST are still valid points of consideration for the FDC3. + +## Success Criteria +* Commitment from major banks and application vendors to support the standards set by the FDC3 +* Workflow integrations in the wild leveraging the standards + +## Deliverables +* Define criteria and mechanics for secure communication between apps +* Define key functions that require specific standards for interoperability +* Create an agreed taxonomy for common app “intents” within financial desktop workflows +* Create an agreed taxonomy for common data to be shared across apps within financial desktop workflows +* Provide reference implementations of all standards +* Maintain the above standards and reference implementations + +### Participation +To be successful, the FDC3 is expected to have a critical mass of active participants for its duration. Effective participation in the FDC3 means participation in the form of research, authoring, editing, and development activities outside the scope of attending regular meetings. + +### Licensing +The FDC3 will use Apache2 license or similar for all deliverables. \ No newline at end of file diff --git a/docs/fdc3-intro.md b/docs/fdc3-intro.md new file mode 100644 index 000000000..cd69c7199 --- /dev/null +++ b/docs/fdc3-intro.md @@ -0,0 +1,6 @@ +--- +id: fdc3-intro +title: Welcome to FDC3 +sidebar_label: Introduction +--- +This is an introduction to FDC3... \ No newline at end of file diff --git a/docs/intents-intro.md b/docs/intents-intro.md new file mode 100644 index 000000000..c458a2553 --- /dev/null +++ b/docs/intents-intro.md @@ -0,0 +1,60 @@ +--- +id: intents-intro +sidebar_label: Intents Overview +title: Intents Overview +hide_title: true +--- + +# Intents Overview + +FDC3 Intents specifications, schemas, and examples + +* Extending APIs from one App to another is powerful... +* However, it requires building to a specific API ahead of time +* Standard context and intent definitions let us create workflows on the fly + +FDC3 Intents define a standard set of verbs that can be used to put together common cross-application workflows on the financial desktop. +* Applications register the intents & context combination they support +* The registries support app discovery by intents and/or context +* Intents are not full RPC, Apps don’t need to enumerate every function with an intent +* FDC3 Standard intents are a limited set, organizations can create their own intents + +## Using Intents +Combined with FDC3 Context Data and App Directory standards, Intents enable rich service discovery on the the desktop. For example: + +### Directing a market data platform to show a chart +```javascript +fdc3.open("my-platform","ViewChart",{ + object:"fdc3-context", + version:"0.0.1", + definition:"https://fdc3/schema/context/0.0.1", + data:[ + { + type:"instrument", + name:"IBM", + id:{ + ticker:"ibm" + } +} ]}); +``` + +### Discovering an app that can start a chat +```javascript +fdc3.open(null,"StartChat",{ + object:"fdc3-context", + version:"0.0.1", + definition:"https://fdc3/schema/context/0.0.1", + data:[ + { + type:"contact", + name:"Nick Kolba", + id:{ + email:"nick@openfin.co" + } +} ]}); +``` + +### Discovering apps that have intents for context type "contact" +```javascript +let availableContactHandlers = fdc3.resolve(null,"contact"); +``` \ No newline at end of file diff --git a/docs/intents-spec.md b/docs/intents-spec.md new file mode 100644 index 000000000..e2715db3d --- /dev/null +++ b/docs/intents-spec.md @@ -0,0 +1,69 @@ +--- +id: intents-spec +sidebar_label: Intents Specification +title: Intents Specification +hide_title: true +--- + +# Intents Specification (Draft) + +## Introduction + +FDC3 Intents define a standard set of nouns and verbs that can be used to put together common cross-application workflows on the financial desktop. + +* Applications register the Intents & Context combinations they support +* The registries support app discovery by Intent and/or Context +* Intents are not full RPC, apps don’t need to enumerate every function with an Intent +* FDC3 standard Intents are a limited set, organizations can create their own + +### Syntax +* Intent names should be free of non-alphanumeric characters. +* ‘.’ will be used to namespace the intent (see below). +* Strings should be in UpperCamelCase. + +### Characteristics + +Intents shoulde be: +* Recognizable + * Generally self-evident what the thing is +* Repeatable + * Many instances across the industry +* Atomic + * There should be clear lines in a workflow where the object begins and ends +* Stateless + * Workflows should not require callbacks or endpoints to maintain references to each other. Once an Intent is passed to an endpoint - it controls the rest of that workflow. +* Specific + * Terms should not be so open-ended that one endpoint could fulfill the Intent in a completely different way than another +* Distinct + * Granular enough that Intent handlers can communicate key functional differences + +### Namespaces ### +All standard Intent names are reserved. Applications may use their own Intents ad hoc. +However, there is a need for applications to ensure that their Intents avoid collision. The recommended approach here is to use the app name as the noun. For example, the ‘myChart’ App may expose the ‘ViewChart’ intent and the ‘myChart.Foo’ proprietary Intent. + +## Initial Set of Standard Intents ## + +### StartCall + * Expected Context: Contact + * Expected behavior: initiate call with contact(s) +### StartChat + * Expected Context: Contact + * Expected behavior: initiate chat with contact(s) +### ViewChart + * Expected Context: Instrument + * Expected behavior: display a chart for the context +### ViewContact + * Expected Context: Contact + * Expected behavior: display details of a contact +### ViewQuote + * Expected Context: Instrument + * Expected behavior: display pricing for an instrument +### ViewNews + * Expected Context: Instrument, Contact, Organisation, etc. + * Expected behavior: display news for a given context +### ViewInstrument + * Expected Context: Instrument + * Expected behavior: display relevant information for a given instrument +### ViewAnalysis + * Expected Context: Instrument, Organization, etc. + * Expected behavior: Send context to receiving application for displaying analysis \ No newline at end of file diff --git a/docs/tutorial.md b/docs/tutorial.md new file mode 100644 index 000000000..3e2c52ea7 --- /dev/null +++ b/docs/tutorial.md @@ -0,0 +1,6 @@ +--- +id: tutorial +title: Tutorial +sidebar_label: Tutorial +--- +This is a tutorial. \ No newline at end of file diff --git a/website/README.md b/website/README.md new file mode 100644 index 000000000..f3da77ff3 --- /dev/null +++ b/website/README.md @@ -0,0 +1,193 @@ +This website was created with [Docusaurus](https://docusaurus.io/). + +# What's In This Document + +* [Get Started in 5 Minutes](#get-started-in-5-minutes) +* [Directory Structure](#directory-structure) +* [Editing Content](#editing-content) +* [Adding Content](#adding-content) +* [Full Documentation](#full-documentation) + +# Get Started in 5 Minutes + +1. Make sure all the dependencies for the website are installed: + +```sh +# Install dependencies +$ yarn +``` +2. Run your dev server: + +```sh +# Start the site +$ yarn start +``` + +## Directory Structure + +Your project file structure should look something like this + +``` +my-docusaurus/ + docs/ + doc-1.md + doc-2.md + doc-3.md + website/ + blog/ + 2016-3-11-oldest-post.md + 2017-10-24-newest-post.md + core/ + node_modules/ + pages/ + static/ + css/ + img/ + package.json + sidebar.json + siteConfig.js +``` + +# Editing Content + +## Editing an existing docs page + +Edit docs by navigating to `docs/` and editing the corresponding document: + +`docs/doc-to-be-edited.md` + +```markdown +--- +id: page-needs-edit +title: This Doc Needs To Be Edited +--- + +Edit me... +``` + +For more information about docs, click [here](https://docusaurus.io/docs/en/navigation) + +## Editing an existing blog post + +Edit blog posts by navigating to `website/blog` and editing the corresponding post: + +`website/blog/post-to-be-edited.md` +```markdown +--- +id: post-needs-edit +title: This Blog Post Needs To Be Edited +--- + +Edit me... +``` + +For more information about blog posts, click [here](https://docusaurus.io/docs/en/adding-blog) + +# Adding Content + +## Adding a new docs page to an existing sidebar + +1. Create the doc as a new markdown file in `/docs`, example `docs/newly-created-doc.md`: + +```md +--- +id: newly-created-doc +title: This Doc Needs To Be Edited +--- + +My new content here.. +``` + +1. Refer to that doc's ID in an existing sidebar in `website/sidebar.json`: + +```javascript +// Add newly-created-doc to the Getting Started category of docs +{ + "docs": { + "Getting Started": [ + "quick-start", + "newly-created-doc" // new doc here + ], + ... + }, + ... +} +``` + +For more information about adding new docs, click [here](https://docusaurus.io/docs/en/navigation) + +## Adding a new blog post + +1. Make sure there is a header link to your blog in `website/siteConfig.js`: + +`website/siteConfig.js` +```javascript +headerLinks: [ + ... + { blog: true, label: 'Blog' }, + ... +] +``` + +2. Create the blog post with the format `YYYY-MM-DD-My-Blog-Post-Title.md` in `website/blog`: + +`website/blog/2018-05-21-New-Blog-Post.md` + +```markdown +--- +author: Frank Li +authorURL: https://twitter.com/foobarbaz +authorFBID: 503283835 +title: New Blog Post +--- + +Lorem Ipsum... +``` + +For more information about blog posts, click [here](https://docusaurus.io/docs/en/adding-blog) + +## Adding items to your site's top navigation bar + +1. Add links to docs, custom pages or external links by editing the headerLinks field of `website/siteConfig.js`: + +`website/siteConfig.js` +```javascript +{ + headerLinks: [ + ... + /* you can add docs */ + { doc: 'my-examples', label: 'Examples' }, + /* you can add custom pages */ + { page: 'help', label: 'Help' }, + /* you can add external links */ + { href: 'https://github.com/facebook/Docusaurus', label: 'GitHub' }, + ... + ], + ... +} +``` + +For more information about the navigation bar, click [here](https://docusaurus.io/docs/en/navigation) + +## Adding custom pages + +1. Docusaurus uses React components to build pages. The components are saved as .js files in `website/pages/en`: +1. If you want your page to show up in your navigation header, you will need to update `website/siteConfig.js` to add to the `headerLinks` element: + +`website/siteConfig.js` +```javascript +{ + headerLinks: [ + ... + { page: 'my-new-custom-page', label: 'My New Custom Page' }, + ... + ], + ... +} +``` + +For more information about custom pages, click [here](https://docusaurus.io/docs/en/custom-pages). + +# Full Documentation + +Full documentation can be found on the [website](https://docusaurus.io/). diff --git a/website/blog/2016-03-11-blog-post.md b/website/blog/2016-03-11-blog-post.md new file mode 100644 index 000000000..cf2ba2960 --- /dev/null +++ b/website/blog/2016-03-11-blog-post.md @@ -0,0 +1,18 @@ +--- +title: Blog Title +author: Blog Author +authorURL: http://twitter.com/ +authorFBID: 100002976521003 +--- + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus elementum massa eget nulla aliquet sagittis. Proin odio tortor, vulputate ut odio in, ultrices ultricies augue. Cras ornare ultrices lorem malesuada iaculis. Etiam sit amet libero tempor, pulvinar mauris sed, sollicitudin sapien. + + + +Mauris vestibulum ullamcorper nibh, ut semper purus pulvinar ut. Donec volutpat orci sit amet mauris malesuada, non pulvinar augue aliquam. Vestibulum ultricies at urna ut suscipit. Morbi iaculis, erat at imperdiet semper, ipsum nulla sodales erat, eget tincidunt justo dui quis justo. Pellentesque dictum bibendum diam at aliquet. Sed pulvinar, dolor quis finibus ornare, eros odio facilisis erat, eu rhoncus nunc dui sed ex. Nunc gravida dui massa, sed ornare arcu tincidunt sit amet. Maecenas efficitur sapien neque, a laoreet libero feugiat ut. + +Nulla facilisi. Maecenas sodales nec purus eget posuere. Sed sapien quam, pretium a risus in, porttitor dapibus erat. Sed sit amet fringilla ipsum, eget iaculis augue. Integer sollicitudin tortor quis ultricies aliquam. Suspendisse fringilla nunc in tellus cursus, at placerat tellus scelerisque. Sed tempus elit a sollicitudin rhoncus. Nulla facilisi. Morbi nec dolor dolor. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras et aliquet lectus. Pellentesque sit amet eros nisi. Quisque ac sapien in sapien congue accumsan. Nullam in posuere ante. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Proin lacinia leo a nibh fringilla pharetra. + +Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Proin venenatis lectus dui, vel ultrices ante bibendum hendrerit. Aenean egestas feugiat dui id hendrerit. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur in tellus laoreet, eleifend nunc id, viverra leo. Proin vulputate non dolor vel vulputate. Curabitur pretium lobortis felis, sit amet finibus lorem suscipit ut. Sed non mollis risus. Duis sagittis, mi in euismod tincidunt, nunc mauris vestibulum urna, at euismod est elit quis erat. Phasellus accumsan vitae neque eu placerat. In elementum arcu nec tellus imperdiet, eget maximus nulla sodales. Curabitur eu sapien eget nisl sodales fermentum. + +Phasellus pulvinar ex id commodo imperdiet. Praesent odio nibh, sollicitudin sit amet faucibus id, placerat at metus. Donec vitae eros vitae tortor hendrerit finibus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Quisque vitae purus dolor. Duis suscipit ac nulla et finibus. Phasellus ac sem sed dui dictum gravida. Phasellus eleifend vestibulum facilisis. Integer pharetra nec enim vitae mattis. Duis auctor, lectus quis condimentum bibendum, nunc dolor aliquam massa, id bibendum orci velit quis magna. Ut volutpat nulla nunc, sed interdum magna condimentum non. Sed urna metus, scelerisque vitae consectetur a, feugiat quis magna. Donec dignissim ornare nisl, eget tempor risus malesuada quis. diff --git a/website/blog/2017-04-10-blog-post-two.md b/website/blog/2017-04-10-blog-post-two.md new file mode 100644 index 000000000..3ab4637bd --- /dev/null +++ b/website/blog/2017-04-10-blog-post-two.md @@ -0,0 +1,18 @@ +--- +title: New Blog Post +author: Blog Author +authorURL: http://twitter.com/ +authorFBID: 100002976521003 +--- + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus elementum massa eget nulla aliquet sagittis. Proin odio tortor, vulputate ut odio in, ultrices ultricies augue. Cras ornare ultrices lorem malesuada iaculis. Etiam sit amet libero tempor, pulvinar mauris sed, sollicitudin sapien. + + + +Mauris vestibulum ullamcorper nibh, ut semper purus pulvinar ut. Donec volutpat orci sit amet mauris malesuada, non pulvinar augue aliquam. Vestibulum ultricies at urna ut suscipit. Morbi iaculis, erat at imperdiet semper, ipsum nulla sodales erat, eget tincidunt justo dui quis justo. Pellentesque dictum bibendum diam at aliquet. Sed pulvinar, dolor quis finibus ornare, eros odio facilisis erat, eu rhoncus nunc dui sed ex. Nunc gravida dui massa, sed ornare arcu tincidunt sit amet. Maecenas efficitur sapien neque, a laoreet libero feugiat ut. + +Nulla facilisi. Maecenas sodales nec purus eget posuere. Sed sapien quam, pretium a risus in, porttitor dapibus erat. Sed sit amet fringilla ipsum, eget iaculis augue. Integer sollicitudin tortor quis ultricies aliquam. Suspendisse fringilla nunc in tellus cursus, at placerat tellus scelerisque. Sed tempus elit a sollicitudin rhoncus. Nulla facilisi. Morbi nec dolor dolor. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras et aliquet lectus. Pellentesque sit amet eros nisi. Quisque ac sapien in sapien congue accumsan. Nullam in posuere ante. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Proin lacinia leo a nibh fringilla pharetra. + +Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Proin venenatis lectus dui, vel ultrices ante bibendum hendrerit. Aenean egestas feugiat dui id hendrerit. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur in tellus laoreet, eleifend nunc id, viverra leo. Proin vulputate non dolor vel vulputate. Curabitur pretium lobortis felis, sit amet finibus lorem suscipit ut. Sed non mollis risus. Duis sagittis, mi in euismod tincidunt, nunc mauris vestibulum urna, at euismod est elit quis erat. Phasellus accumsan vitae neque eu placerat. In elementum arcu nec tellus imperdiet, eget maximus nulla sodales. Curabitur eu sapien eget nisl sodales fermentum. + +Phasellus pulvinar ex id commodo imperdiet. Praesent odio nibh, sollicitudin sit amet faucibus id, placerat at metus. Donec vitae eros vitae tortor hendrerit finibus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Quisque vitae purus dolor. Duis suscipit ac nulla et finibus. Phasellus ac sem sed dui dictum gravida. Phasellus eleifend vestibulum facilisis. Integer pharetra nec enim vitae mattis. Duis auctor, lectus quis condimentum bibendum, nunc dolor aliquam massa, id bibendum orci velit quis magna. Ut volutpat nulla nunc, sed interdum magna condimentum non. Sed urna metus, scelerisque vitae consectetur a, feugiat quis magna. Donec dignissim ornare nisl, eget tempor risus malesuada quis. diff --git a/website/blog/2017-09-25-testing-rss.md b/website/blog/2017-09-25-testing-rss.md new file mode 100644 index 000000000..b7ff8129c --- /dev/null +++ b/website/blog/2017-09-25-testing-rss.md @@ -0,0 +1,11 @@ +--- +title: Adding RSS Support - RSS Truncation Test +author: Eric Nakagawa +authorURL: http://twitter.com/ericnakagawa +authorFBID: 661277173 +--- +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +This should be truncated. + +This line should never render in XML. diff --git a/website/blog/2017-09-26-adding-rss.md b/website/blog/2017-09-26-adding-rss.md new file mode 100644 index 000000000..eeb4f0477 --- /dev/null +++ b/website/blog/2017-09-26-adding-rss.md @@ -0,0 +1,10 @@ +--- +title: Adding RSS Support +author: Eric Nakagawa +authorURL: http://twitter.com/ericnakagawa +authorFBID: 661277173 +--- + +This is a test post. + +A whole bunch of other information. diff --git a/website/blog/2017-10-24-new-version-1.0.0.md b/website/blog/2017-10-24-new-version-1.0.0.md new file mode 100644 index 000000000..60761c02d --- /dev/null +++ b/website/blog/2017-10-24-new-version-1.0.0.md @@ -0,0 +1,8 @@ +--- +title: New Version 1.0.0 +author: Eric Nakagawa +authorURL: http://twitter.com/ericnakagawa +authorFBID: 661277173 +--- + +This blog post will test file name parsing issues when periods are present. diff --git a/website/core/Footer.js b/website/core/Footer.js new file mode 100644 index 000000000..15c43f51f --- /dev/null +++ b/website/core/Footer.js @@ -0,0 +1,102 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +const React = require('react'); + +class Footer extends React.Component { + docUrl(doc, language) { + const baseUrl = this.props.config.baseUrl; + const docsUrl = this.props.config.docsUrl; + const docsPart = `${docsUrl ? `${docsUrl}/` : ''}`; + const langPart = `${language ? `${language}/` : ''}`; + return `${baseUrl}${docsPart}${langPart}${doc}`; + } + + pageUrl(doc, language) { + const baseUrl = this.props.config.baseUrl; + return baseUrl + (language ? `${language}/` : '') + doc; + } + + render() { + return ( + + ); + } +} + +module.exports = Footer; diff --git a/website/package.json b/website/package.json new file mode 100644 index 000000000..15dbdc59f --- /dev/null +++ b/website/package.json @@ -0,0 +1,14 @@ +{ + "scripts": { + "examples": "docusaurus-examples", + "start": "docusaurus-start", + "build": "docusaurus-build", + "publish-gh-pages": "docusaurus-publish", + "write-translations": "docusaurus-write-translations", + "version": "docusaurus-version", + "rename-version": "docusaurus-rename-version" + }, + "devDependencies": { + "docusaurus": "^1.6.2" + } +} diff --git a/website/pages/en/help.js b/website/pages/en/help.js new file mode 100644 index 000000000..2b790e460 --- /dev/null +++ b/website/pages/en/help.js @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +const React = require('react'); + +const CompLibrary = require('../../core/CompLibrary.js'); + +const Container = CompLibrary.Container; +const GridBlock = CompLibrary.GridBlock; + +function Help(props) { + const {config: siteConfig, language = ''} = props; + const {baseUrl, docsUrl} = siteConfig; + const docsPart = `${docsUrl ? `${docsUrl}/` : ''}`; + const langPart = `${language ? `${language}/` : ''}`; + const docUrl = doc => `${baseUrl}${docsPart}${langPart}${doc}`; + + const supportLinks = [ + { + content: `Learn more using the [documentation on this site.](${docUrl( + 'doc1.html', + )})`, + title: 'Browse Docs', + }, + { + content: 'Ask questions about the documentation and project', + title: 'Join the community', + }, + { + content: "Find out what's new with this project", + title: 'Stay up to date', + }, + ]; + + return ( +
+ +
+
+

Need help?

+
+

This project is maintained by a dedicated group of people.

+ +
+
+
+ ); +} + +module.exports = Help; diff --git a/website/pages/en/index.js b/website/pages/en/index.js new file mode 100644 index 000000000..e2b970496 --- /dev/null +++ b/website/pages/en/index.js @@ -0,0 +1,221 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +const React = require('react'); + +const CompLibrary = require('../../core/CompLibrary.js'); + +const MarkdownBlock = CompLibrary.MarkdownBlock; /* Used to read markdown */ +const Container = CompLibrary.Container; +const GridBlock = CompLibrary.GridBlock; + +class HomeSplash extends React.Component { + render() { + const {siteConfig, language = ''} = this.props; + const {baseUrl, docsUrl} = siteConfig; + const docsPart = `${docsUrl ? `${docsUrl}/` : ''}`; + const langPart = `${language ? `${language}/` : ''}`; + const docUrl = doc => `${baseUrl}${docsPart}${langPart}${doc}`; + + const SplashContainer = props => ( +
+
+
{props.children}
+
+
+ ); + + const Logo = props => ( +
+ Project Logo +
+ ); + + const ProjectTitle = () => ( +

+ {siteConfig.title} + {siteConfig.tagline} +

+ ); + + const PromoSection = props => ( +
+
+
{props.children}
+
+
+ ); + + const Button = props => ( +
+ + {props.children} + +
+ ); + + return ( + + {/* */} +
+ + + + {/* */} + + {/* */} + +
+
+ ); + } +} + +class Index extends React.Component { + render() { + const {config: siteConfig, language = ''} = this.props; + const {baseUrl} = siteConfig; + + const Block = props => ( + + + + ); + + const FeatureCallout = () => ( +
+

Use Cases

+ Identify requirements for workflows across the financial desktop. +
+ ); + + const TryOut = () => ( + + {[ + { + content: 'Talk about trying this out', + image: `${baseUrl}img/docusaurus.svg`, + imageAlign: 'left', + title: 'Try it Out', + }, + ]} + + ); + + const Description = () => ( + + {[ + { + content: + 'This is another description of how this project is useful', + image: `${baseUrl}img/docusaurus.svg`, + imageAlign: 'right', + title: 'Description', + }, + ]} + + ); + + const LearnHow = () => ( + + {[ + { + content: 'Talk about learning how to use this', + image: `${baseUrl}img/docusaurus.svg`, + imageAlign: 'right', + title: 'Learn How', + }, + ]} + + ); + + const Features = () => ( + + {[ + { + content: 'A standard API spec creates consistent developer interfaces for working with FDC3.', + image: `${baseUrl}img/feature-api.svg`, + imageAlign: 'top', + title: 'API', + }, + { + content: 'Share context between apps to eliminate re-keying, streamline workflow and surface intelligence.', + image: `${baseUrl}img/feature-context.svg`, + imageAlign: 'top', + title: 'Context Data', + }, + { + content: 'Provide secure, trusted identity, and intuitive service discovery using standardized app directories.', + image: `${baseUrl}img/feature-appd.svg`, + imageAlign: 'top', + title: 'App Directory', + }, + { + content: 'Use standardized intents to tell other apps to take an action such as showing a chart or news.', + image: `${baseUrl}img/feature-intents.svg`, + imageAlign: 'top', + title: 'Intents', + }, + ]} + + ); + + const Showcase = () => { + if ((siteConfig.users || []).length === 0) { + return null; + } + + const showcase = siteConfig.users + .filter(user => user.pinned) + .map(user => ( + + {user.caption} + + )); + + const pageUrl = page => baseUrl + (language ? `${language}/` : '') + page; + + return ( +
+

Who is Using This?

+

This project is used by all these people

+
{showcase}
+
+ + More {siteConfig.title} Users + +
+
+ ); + }; + + return ( +
+ +
+ + + {/* + + + */} +
+
+ ); + } +} + +module.exports = Index; diff --git a/website/pages/en/users.js b/website/pages/en/users.js new file mode 100644 index 000000000..039dc39ff --- /dev/null +++ b/website/pages/en/users.js @@ -0,0 +1,48 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +const React = require('react'); + +const CompLibrary = require('../../core/CompLibrary.js'); + +const Container = CompLibrary.Container; + +class Users extends React.Component { + render() { + const {config: siteConfig} = this.props; + if ((siteConfig.users || []).length === 0) { + return null; + } + + const editUrl = `${siteConfig.repoUrl}/edit/master/website/siteConfig.js`; + const showcase = siteConfig.users.map(user => ( + + {user.caption} + + )); + + return ( +
+ +
+
+

Who is Using This?

+

This project is used by many folks

+
+
{showcase}
+

Are you using this project?

+ + Add your company + +
+
+
+ ); + } +} + +module.exports = Users; diff --git a/website/sidebars.json b/website/sidebars.json new file mode 100644 index 000000000..9bfcd44e2 --- /dev/null +++ b/website/sidebars.json @@ -0,0 +1,20 @@ +{ + "docs": { + "Getting Started": ["fdc3-intro", "fdc3-charter"], + "API": ["api-intro", "api-spec", + { + "type": "subcategory", + "label": "API Reference", + "ids": [ + "api-findIntent" + ] + }], + "Context Data": ["context-intro", "context-spec"], + "App Directory": ["appd-intro", "appd-discovery", "appd-use", "appd-spec"], + "Intents": ["intents-intro", "intents-spec"], + "Use Cases": [] + }, + "tutorial": { + "Part 1": ["tutorial"] + } +} diff --git a/website/siteConfig.js b/website/siteConfig.js new file mode 100644 index 000000000..47b32138c --- /dev/null +++ b/website/siteConfig.js @@ -0,0 +1,99 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// See https://docusaurus.io/docs/site-config for all the possible +// site configuration options. + +// List of projects/orgs using your project for the users page. +const users = [ + { + caption: 'User1', + // You will need to prepend the image path with your baseUrl + // if it is not '/', like: '/test-site/img/docusaurus.svg'. + image: '/img/docusaurus.svg', + infoLink: 'https://www.facebook.com', + pinned: true, + }, +]; + +const siteConfig = { + title: 'FDC3', // Title for your website. + tagline: 'Open standards for the financial desktop', + url: 'https://rikoe.github.io', + baseUrl: '/FDC3/', + // For publishing to GitHub pages + projectName: 'FDC3', + organizationName: 'rikoe', + // For no header links in the top nav bar -> headerLinks: [], + headerLinks: [ + {doc: 'fdc3-intro', label: 'Docs'}, + {doc: 'tutorial', label: 'Tutorial'}, + {page: 'help', label: 'Community'}, + {page: 'help', label: 'About'}, + {blog: true, label: 'Blog'}, + ], + + // If you have users set above, you add it here: + users, + + /* path to images for header/footer */ + headerIcon: 'img/finos-white.png', + footerIcon: 'img/finos.png', + favicon: 'img/favicon/favicon.ico', + + /* Colors for website */ + colors: { + primaryColor: '#00b5e2', + secondaryColor: '#205C3B', + }, + + /* Custom fonts for website */ + /* + fonts: { + myFont: [ + "Times New Roman", + "Serif" + ], + myOtherFont: [ + "-apple-system", + "system-ui" + ] + }, + */ + + // This copyright info is used in /core/Footer.js and blog RSS/Atom feeds. + copyright: `Copyright © ${new Date().getFullYear()} Your Name or Your Company Name`, + + highlight: { + // Highlight.js theme to use for syntax highlighting in code blocks. + theme: 'default', + }, + + // Add custom scripts here that would be placed in