diff --git a/CHANGELOG.md b/CHANGELOG.md index 42b64b232..50d0764e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [0.13.1-next.1](https://github.com/rdkcentral/firebolt-apis/compare/v0.13.0...v0.13.1-next.1) (2023-06-15) + + +### Bug Fixes + +* **governance:** Add governance process docs ([a80ab53](https://github.com/rdkcentral/firebolt-apis/commit/a80ab53c5cdd914b5acbce1effbdb464475bed63)) + # [0.13.0](https://github.com/rdkcentral/firebolt-apis/compare/v0.12.0...v0.13.0) (2023-06-12) diff --git a/package-lock.json b/package-lock.json index 5d9d443a0..4aa0550f9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@firebolt-js/sdks", - "version": "0.13.0", + "version": "0.13.1-next.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@firebolt-js/sdks", - "version": "0.13.0", + "version": "0.13.1-next.1", "license": "Apache-2.0", "workspaces": [ "src/sdks/core", @@ -18,7 +18,7 @@ "devDependencies": { "@commitlint/cli": "^17.0.3", "@commitlint/config-conventional": "^17.0.3", - "@firebolt-js/openrpc": "2.0.1", + "@firebolt-js/openrpc": "rdkcentral/firebolt-openrpc#next", "@firebolt-js/schemas": "0.9.0", "@semantic-release/changelog": "^6.0.1", "@semantic-release/git": "^10.0.1", @@ -989,10 +989,10 @@ "link": true }, "node_modules/@firebolt-js/openrpc": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@firebolt-js/openrpc/-/openrpc-2.0.1.tgz", - "integrity": "sha512-94pGEcq1BfTECqJCS8fA1KC/zTMK+cFUJc8lPbay3QGq0LXsT36gIj5wO/kutEHp4s/eA/2yIQcNolPXEDzYUg==", + "version": "2.0.2-next.2", + "resolved": "git+ssh://git@github.com/rdkcentral/firebolt-openrpc.git#1b69051e21eb7a772a339e96621ff41757cbe143", "dev": true, + "license": "Apache-2.0", "dependencies": { "ajv": "^8.3.0", "ajv-formats": "^2.1.0", @@ -12608,7 +12608,7 @@ }, "src/sdks/core": { "name": "@firebolt-js/sdk", - "version": "0.12.0-next.16", + "version": "0.13.1-governance.17", "license": "Apache-2.0", "devDependencies": { "jest": "^28.1.0", @@ -12629,7 +12629,7 @@ }, "src/sdks/manage": { "name": "@firebolt-js/manage-sdk", - "version": "0.12.0-next.16", + "version": "0.13.1-governance.17", "license": "Apache-2.0", "devDependencies": { "jest": "^28.1.0", @@ -13384,10 +13384,9 @@ } }, "@firebolt-js/openrpc": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@firebolt-js/openrpc/-/openrpc-2.0.1.tgz", - "integrity": "sha512-94pGEcq1BfTECqJCS8fA1KC/zTMK+cFUJc8lPbay3QGq0LXsT36gIj5wO/kutEHp4s/eA/2yIQcNolPXEDzYUg==", + "version": "git+ssh://git@github.com/rdkcentral/firebolt-openrpc.git#1b69051e21eb7a772a339e96621ff41757cbe143", "dev": true, + "from": "@firebolt-js/openrpc@rdkcentral/firebolt-openrpc#next", "requires": { "ajv": "^8.3.0", "ajv-formats": "^2.1.0", diff --git a/package.json b/package.json index 81d40548a..6c7ea9c16 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@firebolt-js/sdks", - "version": "0.13.0", + "version": "0.13.1-next.1", "description": "The Firebolt JS SDK", "type": "module", "bin": { @@ -44,7 +44,7 @@ "devDependencies": { "@commitlint/cli": "^17.0.3", "@commitlint/config-conventional": "^17.0.3", - "@firebolt-js/openrpc": "2.0.1", + "@firebolt-js/openrpc": "rdkcentral/firebolt-openrpc#next", "@firebolt-js/schemas": "0.9.0", "@semantic-release/changelog": "^6.0.1", "@semantic-release/git": "^10.0.1", diff --git a/requirements/glossary.md b/requirements/glossary.md new file mode 100644 index 000000000..5f8d7d4c8 --- /dev/null +++ b/requirements/glossary.md @@ -0,0 +1,77 @@ +# Glossary + +Document Status: Working Draft + +| Contributor | Organization | +| -------------- | -------------- | +| Jeremy LaCivita | Comcast | + +## 1. Overview +This document describes various terms used as part of Firebolt APIs, e.g. method names or parameters, and how they are used by Firebolt, for consistency. + +The terms are this document are commonly used across multiple modules. However, new APIs should be deferential to all existing APIs, not just words listed here. + +The key words "**MUST**", "**MUST NOT**", "**REQUIRED**", "**SHALL**", "**SHALL NOT**", "**SHOULD**", "**SHOULD NOT**", "**RECOMMENDED**", "**NOT RECOMMENDED**", "**MAY**", and "**OPTIONAL**" in this document are to be interpreted as described in [BCP 14](https://www.rfc-editor.org/rfc/rfc2119.txt) [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here. + +## 2. Table of Contents +- [1. Overview](#1-overview) +- [2. Table of Contents](#2-table-of-contents) +- [3. Firebolt Terms](#3-firebolt-terms) + - [3.1. app](#31-app) + - [3.2. available](#32-available) + - [3.3. availability](#33-availability) + - [3.4. capability](#34-capability) + - [3.5. closed captions](#35-closed-captions) + - [3.6. content](#36-content) + - [3.7. entitlement](#37-entitlement) + - [3.8. granted](#38-granted) + - [3.9. lifecycle](#39-lifecycle) + - [3.10. media](#310-media) + - [3.11. permitted](#311-permitted) + - [3.12. policy](#312-policy) + - [3.13. user grant](#313-user-grant) + - [3.14. supported](#314-supported) + +## 3. Firebolt Terms + +### 3.1. app +noun. - A Firebolt app. Any component that calls [Firebolt APIs](https://github.com/rdkcentral/firebolt-apis), either directly, or by running inside of a container that calls Firebolt APIs, is a Firebolt app. + +### 3.2. available +adj. - Used in the context of a [capability](#34-capability) to denote that the capability *could* be leveraged now if it is [permitted](#311-permitted) and either [granted](#38-granted) or is not gated by a [user grant](#313-user-grant). Available capabilities are, by definition, [supported](#314-supported). + +### 3.3. availability +noun. - Used in the context of [content](#36-content) to denote that the content *could* be consumed if either the device has an [entitlement](#37-entitlement) to the content, or the content does not require any entitlement. + +### 3.4. capability +noun. - A discrete unit of functionality that a Firebolt device might be able to perform. It is granular enough to enable appropriate access controls across all Firebolt Apps, but useful enough to be a meaningful functional unit that an App might care about. + +### 3.5. closed captions +noun. - Closed Captions are text tracks rendered over or near [content](#36-content) with the intention of making the audio track of the content more accessible, for example to deaf or hard-of-hearing individuals. + +### 3.6. content +noun. - Content consumed on Firebolt platforms, e.g. video, games, music, etc. + +### 3.7. entitlement +noun. - Used in the context of [content](#36-content) to denote that the device or user has acquired the *right* to consume the content. Content may also have [availability](#33-availability) requirements for consumption, e.g. a user may have pre-orded a piece of content, and therefor have an entitlement to it, that becomes available in the future. + +### 3.8. granted +adj. - Used in the context of a [capability](#34-capability) to denote that the capability has been granted to an app by the user. Capabilities that are gated by [user grant](#313-user-grant) cannot be leveraged by any app w/out being granted. + +### 3.9. lifecycle +noun. - Used to describe the life, from being loaded to unloaded, of a Firebolt [app](#31-app). The app lifecycle has many states that inform the app how it is being percieved and how it should behave. + +### 3.10. media +noun. - [Content](#36-content) that that plays back over time without requiring interaction from the user, e.g. video or music. Media must have a start-time, or a duration, or both. + +### 3.11. permitted +adj. - Used in the context of a [capability](#34-capability) to denote that the capability has been permitted to an app by the distributor of the device. + +### 3.12. policy +noun. - A group of user, device, and/or distributor settings that affect a particular domain, e.g. Advertising. + +### 3.13. user grant +noun. - A secure process in which a user of a device grants an app on the device access to a capability. + +### 3.14. supported +adj. - Used in the context of a [capability](#34-capability) to denote that the capability *could* be leveraged at some point on this device, because the distributor offers it as part of this device's feature set. Leveraging a capability also requires that it is [available](#32-available), [permitted](#311-permitted), and either [granted](#38-granted) or is not gated by a [user grant](#313-user-grant). diff --git a/requirements/governance.md b/requirements/governance.md new file mode 100644 index 000000000..076867815 --- /dev/null +++ b/requirements/governance.md @@ -0,0 +1,225 @@ +# Requirements Governance +This document outlines the governance model for the Firebolt® Open-Source Project, including the structure of an Advisory Committee and Working Groups, as well as the process used to codify Requirements Specifications and Architectural Decision Records. + +## 1. Overview +The Firebolt Open-Source Project is governed by an Advisory Committee that creates and delegates work to Working Groups, which then create proposals for Requirements Specifications and Architectural Decision Records. + +![Governance Structure](./images/governance/structure.png) + +## 2. Table of Contents +- [1. Overview](#1-overview) +- [2. Table of Contents](#2-table-of-contents) +- [3. Goals](#3-goals) +- [4. Governance](#4-governance) + - [4.1. Scope](#41-scope) + - [4.2. Firebolt Version](#42-firebolt-version) + - [4.3. Advisory Committee](#43-advisory-committee) + - [4.4. Advisory Committee Members](#44-advisory-committee-members) + - [4.5. Working Group](#45-working-group) + - [4.6. Requirements Specification](#46-requirements-specification) + - [4.7. Architectural Decision Record](#47-architectural-decision-record) + - [4.8. Approval Stages](#48-approval-stages) + - [4.8.1. Draft](#481-draft) + - [4.8.2. Working Draft](#482-working-draft) + - [4.8.3. Candidate Specification](#483-candidate-specification) + - [4.8.4. Candidate Specification Draft](#484-candidate-specification-draft) + - [4.8.5. Proposed Specification](#485-proposed-specification) + - [4.8.6. Specification](#486-specification) + - [4.9. Requirements Repository](#49-requirements-repository) + - [4.10. Requirements Repository Branching](#410-requirements-repository-branching) + - [4.11. Sanctioned Forks](#411-sanctioned-forks) + - [4.12. Release Versions](#412-release-versions) + +## 3. Goals +The goal of the Firebolt Open-Source Project is to provide a Distributor-configurable set of integration APIs and functional requirements for those APIs so that Apps can integrate with the APIs once and run their app on every Firebolt platform (regardless of distributor) consistently. + +Specifically, Firebolt provides: + + - Write Apps once, run on all Firebolt distributors + - Discovery and launching of Apps + - Detection of, and access control for, Firebolt APIs and features + - Discovery of app content and metrics once discovered + - Platform integration APIs, (e.g. captions, media info, etc.) + - Device and account management + - Integration APIs for broader eco-system integrations +(e.g. user experience, advertising, voice, etc.) + +While enabling Distributors to: + + - Provide differentiating Discovery and Settings experiences + - Configure Firebolt features to meet their business needs + - Configure Firebolt user privacy & opt-in settings + - Decide which set of optional Firebolt features to support + - Negotiate access to features and APIs with each app + +## 4. Governance +The Firebolt Open-Source Project is governed by an Advisory Committee. The purpose of the Advisory Committee is to ensure that each major, minor, and patch version of the Firebolt Requirements is aligned with the goals of the Firebolt Open-Source Project. + +The Firebolt Requirements are the collection of all Requirements Specifications and all Architectural Decision Records that are ratified by the Advisory Committee (and contained in this repository). + +### 4.1. Scope +This document describes the governance model for the following components: + + - Firebolt RPC APIs & SDKs + - Firebolt Media Pipeline (aka Rialto) + - Firebolt API Reference Implementation (Ripple) + +### 4.2. Firebolt Version +A Firebolt Version is a snapshot of the Firebolt Requirements that has been ratified as an official release of the requirements. Note that the requirements are decoupled from any implementation of those requirements, and iterations to the requirements will occur with input from any teams implementing them. + +Firebolt Versions **MUST** follow Semantic Versioning. + +### 4.3. Advisory Committee +The Advisory Committee oversees all aspects of Firebolt Requirements Governance. + +Advisory Committee decisions should aim to be unanimous whenever possible, but in cases of deadlock, may be decided by simple majority. + +The Advisory Committee is responsible for: + + - Prioritization of Working Groups needed + - Creation of balanced Working Groups with relevant subject matter experts + - Solicitation of peer review by SMEs that are not from the working group + - Ratification of requirements into the official Firebolt Requirements + - Determination of when to tag a new minor version release of the Firebolt Requirements + - Determination of when to tag a new major version release of the Firebolt Requirements + - Determination of when a sanctioned fork is warranted + +### 4.4. Advisory Committee Members +The Firebolt Advisory Committee is currently being formed and will be published soon. + +Contact the `rdkcentral/firebolt-apis` maintainer, [Jeremy LaCivita](https://github.com/jlacivita), to submit proposals to the Advisory Committee. + +### 4.5. Working Group +Working Groups build consensus on requirements for Firebolt features or architectural solutions. They should ideally be three to five individuals spanning technical and product experts. Further recommendations on working group composition are left to the Advisory Committee. + +As new features are prioritized, Working Groups should be formed to gather and document requirements for those features. Working groups may be self-forming or selected by the Advisory Committee, but all working groups must have their membership reviewed and approved by the committee to ensure that they are well balanced. + +The Advisory Committee **MAY** appoint a Working Group Chair or instruct the Working Group to select a chair amongst themselves. + +The Working Group Chair is responsible for driving consensus and reporting back to the Advisory Committee + +### 4.6. Requirements Specification +A Requirements Specification includes all details necessary for multiple, disassociated teams to build a consistent implementation of a feature, including API signatures, validation, and functionality, as well as functional and behavioral requirements of the feature that are not directly exposed by an API. + +Requirements and APIs may be targeted towards traditional 3rd party apps, as well as more foundational 1st party apps. + +The level of detail in an acceptable Requirements Specification should be such that any App should run consistently on any implementation of the feature that is based on the Specification. + +Requirements Specifications are written using the [IETF Best Common Practice 14](https://www.rfc-editor.org/rfc/rfc2119.txt) and should include the following at the end of the Overview: + +The key words "**MUST**", "**MUST NOT**", "**REQUIRED**", "**SHALL**", "**SHALL NOT**", "**SHOULD**", "**SHOULD NOT**", "**RECOMMENDED**", "**NOT RECOMMENDED**", "**MAY**", and "**OPTIONAL**" in this document are to be interpreted as described in [BCP 14](https://www.rfc-editor.org/rfc/rfc2119.txt) [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here. + +Requirements Specification move through several [stages](#48-approval-stages) from being a draft, to being an official versioned requirements specification. + +### 4.7. Architectural Decision Record +An Architectural Decision Record includes all details necessary to ensure that Firebolt Requirements are fulfilled with an architecturally sound design. This is often used in cases where listing out explicit requirements, e.g. performance or operational requirements, is not possible or realistic, e.g. Requiring use of a well-known open source component to fulfill some aspect of the platform, or requiring adherence to a high level modular breakdown of concerns to keep platform maintenance manageable. + +Since ADRs included in the Firebolt Requirements **MUST** be adhered to, not every architectural decision made in order to fulfill the Firebolt Requirements needs to have a formal ADR in the Firebolt Requirements repository. It is up to the Advisory Committee which ADRs warrent a formal inclusion in the Firebolt Requirements. + +ADRs move through the same [stages](#48-approval-stages) as Requirements Specifications. + +### 4.8. Approval Stages +Requirements specifications and ADRs are written by working groups and go through several stages of approval before becoming official requirements documents. + +![Approval Track](./images/governance/approval-track.png) + +#### 4.8.1. Draft +This is any first draft of a requirements specification submitted by an individual or individuals to a Working Group. + +Artifacts: + + - A markdown document, ready to be presented to the Working Group + +Note that a Draft **MUST** not be committed to any public location, e.g. the Requirements Repository, because it has not yet been reviewed by the Working Group and could mistakenly contain sensative, private information related to a specific Firebolt distributor. + +#### 4.8.2. Working Draft +A version of the requirements specification that is approved by the Working Group for feedback and review by individuals not on the Working Group. Individuals are selected for review at the discretion of the Working Group. Working drafts may or may not satisfy all requirements of the feature and should not be used for derivative works. + +Artifacts: + + - Markdown specification in a named feature branch of the Requirements Repository + - Working Group members identified + - Working Group progress is being tracked via GitHub project in the Requirements Repository + +#### 4.8.3. Candidate Specification +A version of the requirements specification that is approved by the Working Group for proof-of-concept implementations and peer-review by the larger Community. Candidate Specifications have been through significant review by the Working Group and are ready for feedback from the larger community. + +Once this is published to the peer group for review, they’ll have two weeks to add their comments, make amendments requests, etc. + +Artifacts: + + - Markdown specification in a named feature branch of the Requirements Repository + - Domain experts for peer-review identified and notified + - Repeat process for any C.S. Drafts that are formalized into the C.S. (see below) + - JSON-Schema API changes outlined by the document are in the OpenRPC schemas + +#### 4.8.4. Candidate Specification Draft +A fork of the current Candidate Specification that has changes requested, but not yet approved, by the Working Group. + +Artifacts: + + - A Pull Request into the feature branch containing in-progress changes + - Previous Candidate Specification does not include changes until approved by W.G. + +#### 4.8.5. Proposed Specification +A version of the requirements specification that is considered, by the Working Group, to be the final Candidate Specification, and has been submitted to the Advisory Committee for final approval. This version may be used for experimental implementations and final peer-review by the larger community. + +Artifacts: + + - Markdown specification merged into the #proposed branch of the Requirements Repository + - A Pull Request into the #next branch of Requirements Repository + - JSON-Schema API changes outlined by the document are in the OpenRPC schemas + - Unit tests for any API changes + +#### 4.8.6. Specification +An official versioned stage of the requirements specification that is done and will not change until a future version is created. This version may be used for official production implementations. + +Artifacts: + + - Markdown specification merged into the #main branch of the Requirements Repository + - Spec Review notes and green light from implementation teams of all member organizations with a vested interest in the specification + - Status tracking link for any Open Source implementations of the spec, if appropriate + +### 4.9. Requirements Repository +A public GitHub repository used to manage the progress of a requirements specification. Requirements Specification **MUST** live in their own repository, and not along side of the code that is implementing them. + +The Requirements Repository **MUST** be located at: + +[https://github.com/rdkcentral/firebolt-apis](https://github.com/rdkcentral/firebolt-apis) + +### 4.10. Requirements Repository Branching +The Requirements Repository **MUST** have the following branches: + +| Branch | Purpose | +| ------ | ------- | +| main | For officially approved specifications that have been released under a version. | +| next | For all approved specifications, even those that have not been released under a version. | +| proposed | An experimental branch containing all proposed specifications. | + +Working Drafts and Candidate Specification Drafts **MUST** be housed in a named feature branch in the Requirements Repository (see below). + +Branches are merged based on the approval process: + +![Branching](./images/governance/branching.png) + +### 4.11. Sanctioned Forks +From time to time an organization with access to the Requirements Repository may want to spearhead a new feature without going through the formal approval process. + +In this case the member may submit a request to the Approval Committee for a sanctioned fork inside the Requirements Repository, so that research and development can be done on the feature. + +The Approval Committee **MAY** grant or deny the request for a sanctioned fork. + +After the R&D is complete, the forking organization **MUST** submit the resulting requirements to the formal process and work to have them approved. + +The organization requesting the fork **MUST** be willing to migrate to the approved APIs, which may be different than the API in the fork. + +The Advisory Committee, and selected Working Group, **SHOULD** be willing to avoid unnecessary changes to make migration as easy as possible, without sacrificing the integrity of the Firebolt Open-Source Project’s goals. + +### 4.12. Release Versions +The Advisory Committee has ownership of when to do major, minor, and patch releases of the Firebolt Requirements. + +Releases **MUST** follow Semantic Versioning. + +Approved changes are all housed in the next branch until the Advisory Committee decides that the next branch warrants an officially released version of the requirements. + +If a feature that requires a major version increment, i.e. a breaking change, is proposed, the Advisory Committee may decide to keep it unapproved so that any features requiring a minor version change can be pushed through the process. Management of this is the responsibility of the Advisory Committee. diff --git a/requirements/images/governance/approval-track.png b/requirements/images/governance/approval-track.png new file mode 100644 index 000000000..696954781 Binary files /dev/null and b/requirements/images/governance/approval-track.png differ diff --git a/requirements/images/governance/branching.png b/requirements/images/governance/branching.png new file mode 100644 index 000000000..a61b11909 Binary files /dev/null and b/requirements/images/governance/branching.png differ diff --git a/requirements/images/governance/structure.png b/requirements/images/governance/structure.png new file mode 100644 index 000000000..32bb2763a Binary files /dev/null and b/requirements/images/governance/structure.png differ diff --git a/requirements/style-guide-and-template.md b/requirements/style-guide-and-template.md new file mode 100644 index 000000000..2a9a1ed1d --- /dev/null +++ b/requirements/style-guide-and-template.md @@ -0,0 +1,92 @@ +# Requirements Style Guide + +Document Status: Working Draft + +See [Firebolt Requirements Governance](./governance.md) for more info. + +**NOTE**: Update this link based on your directory depth ^^ + +| Contributor | Organization | +| -------------- | -------------- | +| TBD | TBD | + +## 1. Overview +This document is both a style guide *and* a template for Firebolt Requirements Specifications. + +The Overview section is a non-normative or informative introduction to the contents and subject matter of the document. This is included to introduce the reader to the overall problem, solution, and scope. No formal requirements will be included here, as it will often be skipped by readers that are already familiar with the document. + +Overviews can be as long or short as appropriate for the subject matter, and should have a target audience ranging from technical product managers to engineering teams that may be testing, implementing, or integrating with the functionality described in the document. + +The overview must contain the following towards the end: + +Requirements documents are written using the [IETF Best Common Practice 14](https://www.rfc-editor.org/rfc/rfc2119.txt) and should include the following summary in the Overview section: + +The key words "**MUST**", "**MUST NOT**", "**REQUIRED**", "**SHALL**", "**SHALL NOT**", "**SHOULD**", "**SHOULD NOT**", "**RECOMMENDED**", "**NOT RECOMMENDED**", "**MAY**", and "**OPTIONAL**" in this document are to be interpreted as described in [BCP 14](https://www.rfc-editor.org/rfc/rfc2119.txt) [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here. + +## 2. Table of Contents +- [1. Overview](#1-overview) +- [2. Table of Contents](#2-table-of-contents) +- [3. Specification Style Requirements](#3-specification-style-requirements) + - [3.1. General Style Requirements](#31-general-style-requirements) + - [3.2. Firebolt Style Requirements](#32-firebolt-style-requirements) + - [3.3. Firebolt Method Templates](#33-firebolt-method-templates) +- [4. Example Section](#4-example-section) + - [4.1. Example Feature](#41-example-feature) + +**NOTE**: This is a simple table of contents. It should include links to all headers in the document, except for the top-level header (i.e. `# Title`). It is recommended to use a Markdown plugin to generate this based on headers ranging from level two to level six. Delete this note from your actual spec :) + +## 3. Specification Style Requirements +Firebolt uses method templates in order to code-generate consistent APIs. For example, methods with the `"property"` tag only need to have the `getter` editorially defined. The Firebolt OpenRPC tools will auto-generate the `setter` and `subscriber` as OpenRPC methods with matching types. Additionally, the Firebolt OpenRPC tools wil then code-generate the getter, setter, and subscriber as APIs in various languages using templates. + +This enables both consistent APIs (all properties have a recongnizable pattern) and consistent SDK implementation, which reduces the code that needs to be tested. + +### 3.1. General Style Requirements +All headers **MUST** be numbered, and have the parent header as the prefix, separated with '.' + +Module and method names, as well as constants **MUST** be in monospace font, e.g. the `Foo` module **MUST** have a `bar` method that returns `true`. Specs should use JavaScript notation for any code examples if the spec is not targeting another specific language binding, e.g. a spec about Event listeners in C++ would use C++ syntax. + +String constants and values **MUST** be wrapped in quotes for clarity, e.g. `"Hello World"`. + +### 3.2. Firebolt Style Requirements +All Firebolt APIs exposed for building Firebolt Apps **MUST** be exposed as JSON-RPC methods on a WebSocket accessible to the device, typically running locally. + +Parameters and return values for all APIs **MUST** be described using JSON-Schema schemas. + +Methods **MUST** be grouped into “modules” or “packages” of functionality. + +The JSON-RPC method name of any method **MUST** follow the template: + +``` +. +``` + +e.g. + +``` +lifecycle.ready +``` + +JSON-RPC method names are case sensitive. + +Methods **MUST** have at least one capability used, managed, or provided by the method. + +Methods **MAY** require the use of more than one capability, but this means that the app must have permission to all of them. In order to enable App permissions to be evaluated in an isolated layer, separate from the method implementation itself, a Firebolt method **MUST NOT** be specified to add or remove fields based on the caller's permissions. + +The words used in method and parameter names **SHOULD** be used as consistently as possible across the Firebolt API surface. See the [Firebolt API Glossary](./glossary.md) for words that Firebolt uses and how they are used. + +### 3.3. Firebolt Method Templates +Methods **SHOULD** consider using the existing Firebolt method tags, in order to have a level of consistency across APIs. + +If a Firebolt method is specified such that it requires a non-existant template, then a new Requirements Specification **MUST** be written and referenced by the specification that inspired it. Method templates **MUST** be designed with re-use in mind. + +## 4. Example Section +A section describes group of closely related features. Many specifications have only one section, however, more complicated specifications may have many. The first paragraph of a section is typically a non-normative introduction to that section, and therefor does not contain any formal requirements. + +### 4.1. Example Feature +Each feature under a section will have it's own heading. Non-normative introductions to features are not typically needed, as the reader is ready to get into requirements at this point. It is recommended that all Feature headings under each Section contain only sentences or short paragraphs with formal requirements, e.g. MUST, SHOULD, MAY, MUST NOT, SHOULD NOT, etc. These sentences should be separated by blank lines for readability, e.g.: + +This requirement **MUST** be satisifed. + +This requirement **SHOULD** be satisfied. + +This requirement **MUST** be satisfied. The requirement **MUST** be satisifed in this particular way. diff --git a/src/js/github.io/index.mjs b/src/js/github.io/index.mjs index ec296302a..9a1c91997 100644 --- a/src/js/github.io/index.mjs +++ b/src/js/github.io/index.mjs @@ -1,6 +1,6 @@ import nopt from 'nopt' import path from 'path' -import { readJson, readDir, readFiles, readText, writeFiles, writeText } from '../../../node_modules/@firebolt-js/openrpc/src/shared/filesystem.mjs' +import { readJson, readDir, readFiles, readText, writeFiles, writeText, writeJson } from '../../../node_modules/@firebolt-js/openrpc/src/shared/filesystem.mjs' const knownOpts = { 'output': [String] @@ -20,6 +20,60 @@ const signOff = () => console.log('\nThis has been a presentation of \x1b[38;5;2 const packageJson = await readJson(process.env.npm_package_json) const version = channel(packageJson.version) +const requirements = await readFiles(await readDir(path.join('.', 'requirements'), { recursive: true }), path.join('.', 'requirements')) + +const processFiles = (docs, base, dir, subdir, category, setType) => { + Object.keys(docs).forEach(ref => { + let data = docs[ref] + const source = ref + delete docs[ref] + let type = '' + + if (setType && category === 'requirements') { + const parts = ref.split(path.sep) + if (parts.length >= 3) { + type = ref.split(path.sep)[1].replace(/.$/,''); + } + } + + if (ref.endsWith('.md')) { + const filename = ref.split(path.sep).pop() + if (filename !== 'index.md') { + const dirname = filename.split('.').shift() + const parts = ['index.md'] + // if the dirname is the same as parent dir, don't insert it + if (dirname != ref.split(path.sep).slice(-2, -1)[0]) { + parts.unshift(dirname) + data = data.replace(/\]\(\.\.\//g, '](../../') + data = data.replace(/\]\(\.\//g, '](../') + } + data = data.replace(/\]\((.*?)\.md([\)#])/g, ']($1$2') + data = data.replace(/\]\((.*?)\/(.*?)\/\2([\)#])/g, ']($1/$2$3') + ref = ref.split(path.sep).slice(0, -1).concat(parts).join(path.sep) + } + + docs[path.join(parsedArgs.output, dir, version, subdir, ref)] = frontmatter(data, version, subdir, category, type) + } + else { + docs[path.join(parsedArgs.output, dir, version, subdir, ref)] = data + } + + console.log(`Will copy ${path.join(base, source)} to ${path.join(parsedArgs.output, dir, version, subdir, ref)}`) + + if (version === 'latest') { + if (ref.endsWith('.md')) { + docs[path.join(parsedArgs.output, dir, packageJson.version, subdir, ref)] = frontmatter(data, packageJson.version, subdir, category, type) + } + else { + docs[path.join(parsedArgs.output, dir, packageJson.version, subdir, ref)] = data + } + console.log(`Will copy ${path.join(base, source)} to ${path.join(parsedArgs.output, dir, packageJson.version, subdir, ref)}`) + } + }) +} + +processFiles(requirements, path.join('.', 'requirements'), 'requirements', '', 'requirements', true) +writeFiles(requirements) packageJson.workspaces.forEach(async workspace => { const docs = await readFiles(await readDir(path.join(workspace, 'build', 'docs', 'markdown'), { recursive: true }), path.join(workspace, 'build', 'docs', 'markdown')) @@ -28,30 +82,32 @@ packageJson.workspaces.forEach(async workspace => { docs['changelog.md'] = '---\ntitle: Change Log\n---\n' + (await readText(path.join(workspace, 'CHANGELOG.md'))) // point to new output location - Object.keys(docs).forEach(ref => { - const data = docs[ref] - const sdk = workspace.split(path.sep).pop() - delete docs[ref] - docs[path.join(parsedArgs.output, version, sdk, ref)] = frontmatter(data, version, sdk) - - console.log(`Will copy ${path.join(workspace, 'build', 'docs', 'markdown', ref)} to ${path.join(parsedArgs.output, version, sdk, ref)}`) - - if (version === 'latest') { - docs[path.join(parsedArgs.output, packageJson.version, sdk, ref)] = frontmatter(data, packageJson.version, sdk) - console.log(`Will copy ${path.join(workspace, 'build', 'docs', 'markdown', ref)} to ${path.join(parsedArgs.output, packageJson.version, sdk, ref)}`) - } - }) + processFiles(docs, path.join(workspace, 'build', 'docs', 'markdown'), 'apis', workspace.split(path.sep).pop()) writeFiles(docs) }) // This is the main README, and goes in a few places... -console.log(`Will copy ${path.join('.', 'README.md')} to ${path.join(parsedArgs.output, 'index.md')}`) +console.log(`Will copy ${path.join('.', 'README.md')} to ${path.join(parsedArgs.output, 'apis', 'index.md')}`) const index = frontmatter(await readText(path.join('README.md')), null, null) -writeText(path.join(parsedArgs.output, 'index.md'), index) +writeText(path.join(parsedArgs.output, 'apis', 'index.md'), index) if (version === 'latest') { console.log(`Will copy ${path.join('.', 'README.md')} to ${path.join(parsedArgs.output, packageJson.version, 'index.md')}`) - writeText(path.join(parsedArgs.output, packageJson.version, 'index.md'), index) + writeText(path.join(parsedArgs.output, 'apis', packageJson.version, 'index.md'), index) +} + +// this is the firebolt spec JSON +const specification = await readJson(path.join('dist', 'firebolt-specification.json')) +writeJson(path.join(parsedArgs.output, 'requirements', version, 'specifications', 'firebolt-specification.json'), specification) +if (version === 'latest') { + writeJson(path.join(parsedArgs.output, 'requirements', packageJson.version, 'specifications', 'firebolt-specification.json'), specification) +} + +// this is the firebolt OpenRPC spec JSON +const openrpc = await readJson(path.join('dist', 'firebolt-open-rpc.json')) +writeJson(path.join(parsedArgs.output, 'requirements', version, 'specifications', 'firebolt-open-rpc.json'), openrpc) +if (version === 'latest') { + writeJson(path.join(parsedArgs.output, 'requirements', packageJson.version, 'specifications', 'firebolt-open-rpc.json'), openrpc) } function channel(version) { @@ -73,7 +129,7 @@ function channel(version) { } } -function frontmatter(data, version, sdk) { +function frontmatter(data, version, sdk, category, type) { let matter = '' if (data.startsWith('---')) { matter = data = data.substring(4) @@ -91,10 +147,22 @@ function frontmatter(data, version, sdk) { matter += `layout: default\n` } + if (matter.toLowerCase().indexOf('title:') === -1) { + matter += `title: ${data.match(/\# (.*?)\n/)[1]}\n` + } + if (sdk && matter.indexOf('sdk:') === -1) { matter += `sdk: ${sdk}\n` } + if (category && matter.indexOf('category:') === -1) { + matter += `category: ${category}\n` + } + + if (type && matter.indexOf('type:') === -1) { + matter += `type: ${type}\n` + } + matter += '---\n' return matter + data.replace(/\/g, '
') diff --git a/src/sdks/core/package.json b/src/sdks/core/package.json index ed9496d59..cf6df69d1 100644 --- a/src/sdks/core/package.json +++ b/src/sdks/core/package.json @@ -1,6 +1,6 @@ { "name": "@firebolt-js/sdk", - "version": "0.13.0", + "version": "0.13.1-next.1", "description": "The Firebolt JS SDK", "main": "./dist/lib/firebolt.mjs", "types": "./dist/lib/firebolt.d.ts", diff --git a/src/sdks/manage/package.json b/src/sdks/manage/package.json index 39df8182d..af165dc9d 100644 --- a/src/sdks/manage/package.json +++ b/src/sdks/manage/package.json @@ -1,6 +1,6 @@ { "name": "@firebolt-js/manage-sdk", - "version": "0.13.0", + "version": "0.13.1-next.1", "description": "The Firebolt Manage JS SDK", "main": "./dist/lib/firebolt-manage.mjs", "types": "./dist/lib/firebolt-manage.d.ts",