Skip to content

Commit beb4e43

Browse files
authored
Auto-generated JS API docs & TS cleanup (#2313)
1 parent 2efb4d5 commit beb4e43

25 files changed

Lines changed: 396 additions & 558 deletions

.azure-pipelines-gh-pages.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ jobs:
3434
pip install wheel
3535
pip install -U -r doc/requirements.txt
3636
pip install -U -e ./python
37+
npm install typescript typedoc@0.19.2
38+
NPM_BIN=$(pwd)/node_modules/.bin
39+
export PATH="$NPM_BIN:$PATH"
3740
sphinx-multiversion doc build/html
3841
displayName: Sphinx
3942

doc/build_apps/js_app_bundle.rst

Lines changed: 30 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -112,48 +112,43 @@ Globals
112112
JavaScript provides a set of built-in
113113
`global functions, objects, and values <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects>`_.
114114

115-
CCF provides the following additional globals:
116-
117-
- ``tables``:
118-
Provides access to the Key-Value Store of the network.
119-
``tables`` is an object that maps table names to ``Table`` objects.
120-
A ``Table`` object has ``get(k)``/``put(k,v)``/``remove(k)`` functions.
121-
Keys and values currently have to be strings, although this will change in the near future.
122-
123-
Example: ``tables['msg'].put('123', 'Hello world!')``
115+
CCF provides the additional global variable ``ccf`` to access native CCF functionality.
116+
It is an object implementing the :js:class:`CCF <CCF>` interface documented below.
124117

125118
.. note::
126119
`Web APIs <https://developer.mozilla.org/en-US/docs/Web/API>`_ are not available.
127120

121+
.. js:autoclass:: CCF
122+
:members:
123+
124+
.. js:autoclass:: KVMap
125+
:members:
126+
127+
.. js:autoclass:: WrapAlgoParams
128+
:members:
129+
130+
.. js:autoclass:: RsaOaepParams
131+
:members:
132+
133+
.. js:autoclass:: AESKWPParams
134+
:members:
135+
136+
.. js:autoclass:: RsaOaepAESKWPParams
137+
:members:
138+
139+
.. js:autoclass:: CryptoKeyPair
140+
:members:
141+
128142
Endpoint handlers
129143
~~~~~~~~~~~~~~~~~
130144

131-
An endpoint handler is an exported function that receives a ``Request`` object, returns a ``Response`` object,
132-
and is referenced in the ``app.json`` file of the app bundle (see above).
133-
134-
A ``Request`` object has the following fields:
135-
136-
- ``headers``: An object mapping lower-case HTTP header names to their values.
137-
- ``params``: An object mapping URL path parameter names to their values.
138-
- ``query``: The query string of the requested URL.
139-
- ``body``: An object with ``text()``/``json()``/``arrayBuffer()`` functions to access the
140-
request body in various ways.
141-
- ``caller``: An object describing the authenticated identity retrieved by this endpoint's authentication policies.
142-
``caller.policy`` is a string indicating which policy accepted this request, for use when multiple policies are
143-
listed. The other fields depend on which policy accepted; most set ``caller.id``, ``caller.data``, and ``caller.cert``,
144-
while the ``"jwt"`` policy sets ``caller.jwt``.
145-
146-
A ``Response`` object can contain the following fields (all optional):
147-
148-
- ``statusCode``: The HTTP status code to return (default ``200``, or ``500`` if an exception is raised).
149-
- ``headers``: An object mapping lower-case HTTP header names to their values.
150-
The type of ``body`` determines the default value of the ``content-type`` header, see below.
151-
- ``body``: Either
152-
a `string <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String>`_ (``text/plain``),
153-
an `ArrayBuffer <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer>`_ (``application/octet-stream``),
154-
a `TypedArray <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray>`_ (``application/octet-stream``),
155-
or as fall-back any `JSON-serializable <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify>`_ value (``application/json``).
156-
The content type in parentheses is the default and can be overridden in ``headers``.
145+
An endpoint handler is an exported function that receives a :js:class:`Request <Request>` object, returns a :js:class:`Response <Response>` object, and is referenced in the ``app.json`` file of the app bundle (see above).
146+
147+
.. js:autoclass:: Request
148+
:members:
149+
150+
.. js:autoclass:: Response
151+
:members:
157152

158153
See the following handler from the example app bundle in the
159154
`tests/js-app-bundle <https://github.com/microsoft/CCF/tree/main/tests/js-app-bundle>`_

doc/build_apps/js_app_ts.rst

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@ The sample app has the following folder layout:
3030
│ │ ├── crypto.ts
3131
│ │ ├── partition.ts
3232
│ │ └── proto.ts
33-
│ └── types
34-
│ └── ccf.ts
33+
│ └── ccf
34+
│ ├── builtin.ts
35+
│ └── util.ts
3536
├── app.json
3637
├── package.json
3738
├── rollup.config.js
@@ -40,7 +41,8 @@ The sample app has the following folder layout:
4041
It contains these files:
4142

4243
- ``src/endpoints/*.ts``: :ref:`build_apps/js_app_ts:Endpoint handlers`.
43-
- ``src/types/ccf.ts``: :ref:`build_apps/js_app_ts:Type definitions` for CCF objects.
44+
- ``src/ccf/builtin.ts``: :ref:`build_apps/js_app_ts:Type definitions` for CCF objects.
45+
- ``src/ccf/util.ts``: Utilities for working with CCF's Key Value Store.
4446
- ``app.json``: :ref:`App metadata <build_apps/js_app_ts:Metadata>`.
4547
- ``package.json``: Dependencies and build command.
4648
- ``rollup.config.js``: Rollup configuration, see :ref:`build_apps/js_app_ts:Conversion to an app bundle` for more details.
@@ -70,7 +72,7 @@ An endpoint handler, here named ``abc``, has the following structure:
7072
...
7173
}
7274
73-
export function abc(request: ccf.Request<AbcRequest>): ccf.Response<AbcResponse> {
75+
export function abc(request: Request<AbcRequest>): Response<AbcResponse> {
7476
// access request details
7577
const data = request.body.json();
7678
@@ -86,7 +88,7 @@ An endpoint handler, here named ``abc``, has the following structure:
8688
}
8789
8890
``AbcRequest`` and ``AbcResponse`` define the JSON schema of the request and response body, respectively.
89-
If an endpoint has no request or response body, the type parameters of ``ccf.Request``/``ccf.Response`` can be omitted.
91+
If an endpoint has no request or response body, the type parameters of :js:class:`Request`/:js:class:`Response` can be omitted.
9092

9193
As an example, the ``/partition`` endpoint of the sample app is implemented as:
9294

@@ -111,7 +113,7 @@ CCF currently does not provide an npm package with TypeScript definitions
111113
for :ref:`CCF's JavaScript API <build_apps/js_app_bundle:JavaScript API>`.
112114

113115
Instead, the definitions are part of the sample app in
114-
`src/types/ccf.ts <https://github.com/microsoft/CCF/tree/main/tests/npm-app/src/types/ccf.ts>`_.
116+
`src/ccf/builtin.ts <https://github.com/microsoft/CCF/tree/main/tests/npm-app/src/ccf/builtin.ts>`_.
115117
See `src/endpoints <https://github.com/microsoft/CCF/tree/main/tests/npm-app/src/endpoints>`_
116118
on how the types can be imported and used.
117119

doc/build_apps/js_app_tsoa.rst

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,9 @@ The sample app has the following folder layout:
4141
│ │ └── site.ts
4242
│ ├── models
4343
│ │ └── poll.ts
44-
│ ├── types
45-
│ │ └── ccf.ts
44+
│ ├── ccf
45+
│ │ ├── builtin.ts
46+
│ │ └── util.ts
4647
│ ├── authentication.ts
4748
│ └── error_handler.ts
4849
├── tsoa-support
@@ -59,7 +60,8 @@ It contains these files:
5960

6061
- ``src/controllers/*.ts``: :ref:`build_apps/js_app_tsoa:Controllers`.
6162
- ``src/models/*.ts``: Data models shared between endpoint handlers.
62-
- ``src/types/ccf.ts``: :ref:`build_apps/js_app_tsoa:Type definitions` for CCF objects.
63+
- ``src/ccf/builtin.ts``: :ref:`build_apps/js_app_tsoa:Type definitions` for CCF objects.
64+
- ``src/ccf/util.ts``: Utilities for working with CCF's Key Value Store.
6365
- ``src/authentication.ts``: `authentication module <https://tsoa-community.github.io/docs/authentication.html>`_.
6466
See also :ref:`build_apps/auth/jwt_ms_example:JWT Authentication example using Microsoft Identity Platform`.
6567
- ``src/error_handler.ts``: global error handler.
@@ -110,18 +112,18 @@ CCF currently does not provide an npm package with TypeScript definitions
110112
for :ref:`CCF's JavaScript API <build_apps/js_app_bundle:JavaScript API>`.
111113

112114
Instead, the definitions are part of the sample app in
113-
`src/types/ccf.ts <https://github.com/microsoft/CCF/tree/samples/apps/forum/src/types/ccf.ts>`_.
115+
`src/ccf/builtin.ts <https://github.com/microsoft/CCF/tree/samples/apps/forum/src/ccf/builtin.ts>`_.
114116

115-
Using CCF's ``Response`` object is not needed when using tsoa because the return value always has to be the body itself.
117+
Using CCF's :js:class:`Response` object is not needed when using tsoa because the return value always has to be the body itself.
116118
Headers and the status code can be set using `Controller methods <https://tsoa-community.github.io/reference/classes/_tsoa_runtime.controller-1.html>`_.
117119

118-
Sometimes though it is necessary to access CCF's ``Request`` object, for example when the request body is not JSON.
119-
In this case, instead of using ``@Body() body: MyType`` as function argument, ``@Request() request: ccf.Request`` can be used.
120+
Sometimes though it is necessary to access CCF's :js:class:`Request` object, for example when the request body is not JSON.
121+
In this case, instead of using ``@Body() body: MyType`` as function argument, ``@Request() request: CCF.Request`` can be used.
120122
See `src/controllers/csv.ts <https://github.com/microsoft/CCF/tree/main/samples/apps/forum/src/controllers/csv.ts>`_
121123
for a concrete example.
122124

123125
.. warning::
124-
Requesting CCF's ``Request`` object via ``@Request()`` instead of using ``@Body()`` disables automatic schema validation.
126+
Requesting CCF's :js:class:`Request` object via ``@Request()`` instead of using ``@Body()`` disables automatic schema validation.
125127

126128
Metadata
127129
--------

doc/conf.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@
5454
"sphinx_copybutton",
5555
"sphinx.ext.autodoc",
5656
"sphinxcontrib.openapi",
57-
"sphinx_panels"
57+
"sphinx_panels",
58+
"sphinx_js"
5859
]
5960

6061
autosectionlabel_prefix_document = True
@@ -227,6 +228,10 @@
227228
tokenizer_lang = "en_UK"
228229
spelling_word_list_filename = ["spelling_wordlist.txt"]
229230

231+
# sphinx_js options
232+
js_language = 'typescript'
233+
js_source_path = '../src/js'
234+
jsdoc_config_path = '../tests/npm-app/tsconfig.json'
230235

231236
def setup(self):
232237
import subprocess

doc/requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ pydata-sphinx-theme
1010
sphinx-copybutton
1111
sphinxcontrib.openapi
1212
sphinx-panels
13+
sphinx-js

livehtml.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ fi
1313
source env/bin/activate
1414
pip install --disable-pip-version-check -q -U -e ./python/
1515
pip install --disable-pip-version-check -q -U -r ./doc/requirements.txt
16+
npm install typescript typedoc@0.19.2
17+
NPM_BIN=$(pwd)/node_modules/.bin
18+
export PATH="$NPM_BIN:$PATH"
1619
echo "Python environment successfully setup"
1720

1821
sphinx-autobuild -b html doc doc/html --host localhost --port 8080

samples/apps/forum/src/authentication.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
import { KJUR, KEYUTIL } from "jsrsasign";
55
import jwt_decode from "jwt-decode";
66
import { Base64 } from "js-base64";
7-
import * as ccf from "./types/ccf";
7+
import { ccf, Request } from "./ccf/builtin";
8+
import * as ccfUtil from "./ccf/util";
89
import { UnauthorizedError } from "./error_handler";
910

1011
export interface User {
@@ -33,7 +34,7 @@ export const MS_APP_ID = "1773214f-72b8-48f9-ae18-81e30fab04db";
3334
export const MS_APP_ID_URI = "api://1773214f-72b8-48f9-ae18-81e30fab04db";
3435

3536
export function authentication(
36-
request: ccf.Request,
37+
request: Request,
3738
securityName: string,
3839
scopes?: string[]
3940
): void {
@@ -65,10 +66,10 @@ export function authentication(
6566
}
6667

6768
// Get the stored signing key to validate the token.
68-
const keysMap = new ccf.TypedKVMap(
69+
const keysMap = new ccfUtil.TypedKVMap(
6970
ccf.kv["public:ccf.gov.jwt.public_signing_keys"],
70-
ccf.string,
71-
ccf.typedArray(Uint8Array)
71+
ccfUtil.string,
72+
ccfUtil.typedArray(Uint8Array)
7273
);
7374
const publicKeyDer = keysMap.get(signingKeyId);
7475
if (publicKeyDer === undefined) {
@@ -98,10 +99,10 @@ export function authentication(
9899
}
99100

100101
// Get the issuer associated to the signing key.
101-
const keyIssuerMap = new ccf.TypedKVMap(
102+
const keyIssuerMap = new ccfUtil.TypedKVMap(
102103
ccf.kv["public:ccf.gov.jwt.public_signing_key_issuer"],
103-
ccf.string,
104-
ccf.string
104+
ccfUtil.string,
105+
ccfUtil.string
105106
);
106107
const keyIssuer = keyIssuerMap.get(signingKeyId);
107108

@@ -136,7 +137,7 @@ export function authentication(
136137
throw new Error(`BUG: unknown key issuer: ${keyIssuer}`);
137138
}
138139

139-
request.user = {
140+
request.caller = {
140141
claims: claims,
141142
userId: claims.sub,
142143
} as User;

samples/apps/forum/src/ccf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../../src/js

samples/apps/forum/src/controllers/csv.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import {
2323
UnauthorizedError,
2424
} from "../error_handler";
2525
import { User } from "../authentication";
26-
import * as ccf from "../types/ccf";
26+
import * as CCF from "../ccf/builtin";
2727
import { kv } from "../models/poll";
2828

2929
// GET /csv return all opinions of authenticated user as CSV
@@ -46,8 +46,8 @@ export class CSVController extends Controller {
4646

4747
@SuccessResponse(200, "Opinions of authenticated user in CSV format")
4848
@Get()
49-
public getOpinionsAsCSV(@Request() request: ccf.Request): any {
50-
const user: User = request.user;
49+
public getOpinionsAsCSV(@Request() request: CCF.Request): any {
50+
const user: User = request.caller;
5151

5252
const rows = [];
5353
this.kvPolls.forEach((poll, topic) => {
@@ -69,8 +69,8 @@ export class CSVController extends Controller {
6969
"Opinions were not recorded because either an opinion data type did not match the poll type or a poll with the given topic was not found"
7070
)
7171
@Post()
72-
public submitOpinionsFromCSV(@Request() request: ccf.Request): void {
73-
const user: User = request.user;
72+
public submitOpinionsFromCSV(@Request() request: CCF.Request): void {
73+
const user: User = request.caller;
7474

7575
const rows = parse<any>(request.body.text(), { header: true }).data;
7676

0 commit comments

Comments
 (0)