adapt-authoring-api 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.eslintignore ADDED
@@ -0,0 +1 @@
1
+ node_modules
package/.eslintrc ADDED
@@ -0,0 +1,14 @@
1
+ {
2
+ "env": {
3
+ "browser": false,
4
+ "node": true,
5
+ "commonjs": false,
6
+ "es2020": true
7
+ },
8
+ "extends": [
9
+ "standard"
10
+ ],
11
+ "parserOptions": {
12
+ "ecmaVersion": 2020
13
+ }
14
+ }
@@ -0,0 +1,55 @@
1
+ name: Bug Report
2
+ description: File a bug report
3
+ labels: ["bug"]
4
+ body:
5
+ - type: markdown
6
+ attributes:
7
+ value: |
8
+ Thanks for taking the time to fill out this bug report!
9
+ - type: textarea
10
+ id: description
11
+ attributes:
12
+ label: What happened?
13
+ description: Please describe the issue
14
+ validations:
15
+ required: true
16
+ - type: textarea
17
+ id: expected
18
+ attributes:
19
+ label: Expected behaviour
20
+ description: Tell us what should have happened
21
+ - type: textarea
22
+ id: repro-steps
23
+ attributes:
24
+ label: Steps to reproduce
25
+ description: Tell us how to reproduce the issue
26
+ validations:
27
+ required: true
28
+ - type: input
29
+ id: aat-version
30
+ attributes:
31
+ label: Authoring tool version
32
+ description: What version of the Adapt authoring tool are you running?
33
+ validations:
34
+ required: true
35
+ - type: input
36
+ id: fw-version
37
+ attributes:
38
+ label: Framework version
39
+ description: What version of the Adapt framework are you running?
40
+ - type: dropdown
41
+ id: browsers
42
+ attributes:
43
+ label: What browsers are you seeing the problem on?
44
+ multiple: true
45
+ options:
46
+ - Firefox
47
+ - Chrome
48
+ - Safari
49
+ - Microsoft Edge
50
+ - type: textarea
51
+ id: logs
52
+ attributes:
53
+ label: Relevant log output
54
+ description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
55
+ render: sh
@@ -0,0 +1 @@
1
+ blank_issues_enabled: false
@@ -0,0 +1,22 @@
1
+ name: Feature request
2
+ description: Request a new feature
3
+ labels: ["enhancement"]
4
+ body:
5
+ - type: markdown
6
+ attributes:
7
+ value: |
8
+ Thanks for taking the time to request a new feature in the Adapt authoring tool! The Adapt team will consider all new feature requests, but unfortunately cannot commit to every one.
9
+ - type: textarea
10
+ id: description
11
+ attributes:
12
+ label: Feature description
13
+ description: Please describe your feature request
14
+ validations:
15
+ required: true
16
+ - type: checkboxes
17
+ id: contribute
18
+ attributes:
19
+ label: Can you work on this feature?
20
+ description: If you are able to commit your own time to work on this feature, it will greatly increase the liklihood of it being implemented by the core dev team. Otherwise, it will be triaged and prioritised alongside the core team's current priorities.
21
+ options:
22
+ - label: I can contribute
@@ -0,0 +1,11 @@
1
+ # To get started with Dependabot version updates, you'll need to specify which
2
+ # package ecosystems to update and where the package manifests are located.
3
+ # Please see the documentation for all configuration options:
4
+ # https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
5
+
6
+ version: 2
7
+ updates:
8
+ - package-ecosystem: "npm" # See documentation for possible values
9
+ directory: "/" # Location of package manifests
10
+ schedule:
11
+ interval: "weekly"
@@ -0,0 +1,25 @@
1
+ [//]: # (Please title your PR according to eslint commit conventions)
2
+ [//]: # (See https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-eslint#eslint-convention for details)
3
+
4
+ [//]: # (Add a link to the original issue)
5
+
6
+ [//]: # (Delete as appropriate)
7
+ ### Fix
8
+ * A sentence describing each fix
9
+
10
+ ### Update
11
+ * A sentence describing each udpate
12
+
13
+ ### New
14
+ * A sentence describing each new feature
15
+
16
+ ### Breaking
17
+ * A sentence describing each breaking change
18
+
19
+ [//]: # (List appropriate steps for testing if needed)
20
+ ### Testing
21
+ 1. Steps for testing
22
+
23
+ [//]: # (Mention any other dependencies)
24
+
25
+
@@ -0,0 +1,16 @@
1
+ name: Add labelled PRs to project
2
+
3
+ on:
4
+ pull_request:
5
+ types: [ labeled ]
6
+
7
+ jobs:
8
+ add-to-project:
9
+ if: ${{ github.event.label.name == 'dependencies' }}
10
+ name: Add to main project
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/add-to-project@v0.1.0
14
+ with:
15
+ project-url: https://github.com/orgs/adapt-security/projects/5
16
+ github-token: ${{ secrets.PROJECTS_SECRET }}
@@ -0,0 +1,19 @@
1
+ name: Add to main project
2
+
3
+ on:
4
+ issues:
5
+ types:
6
+ - opened
7
+ pull_request:
8
+ types:
9
+ - opened
10
+
11
+ jobs:
12
+ add-to-project:
13
+ name: Add to main project
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/add-to-project@v0.1.0
17
+ with:
18
+ project-url: https://github.com/orgs/adapt-security/projects/5
19
+ github-token: ${{ secrets.PROJECTS_SECRET }}
@@ -0,0 +1,9 @@
1
+ {
2
+ "module": false,
3
+ "documentation": {
4
+ "enable": true,
5
+ "manualPages": {
6
+ "writing-an-api.md": "basics"
7
+ }
8
+ }
9
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "type": "object",
4
+ "properties": {
5
+ "defaultCacheLifespan": {
6
+ "description": "Default lifespan of data cache",
7
+ "type": "string",
8
+ "isTimeMs": true,
9
+ "default": "5s"
10
+ },
11
+ "defaultPageSize": {
12
+ "description": "Default size of page",
13
+ "type": "number",
14
+ "default": 100
15
+ },
16
+ "maxPageSize": {
17
+ "description": "Maximum page size",
18
+ "type": "number",
19
+ "default": 250
20
+ }
21
+ }
22
+ }
@@ -0,0 +1,135 @@
1
+ # Writing an API
2
+
3
+ _**Note:** before using this functionality, it is worth having an understanding of how to write basic custom modules first. See [this page](`adapt-authoring-api` module) for more._
4
+
5
+ The `adapt-authoring-api` module makes defining custom APIs simple by providing abstract classes and utilities you can use in your own modules to replace the common boilerplate code required when writing an API.
6
+
7
+ By extending the [AbstractAPIModule](../class/adapt_authoring_restructure/adapt-authoring-api/lib/module.js~AbstractApiModule.html) class, you get the following as standard:
8
+ - Boiler-plate code for defining router and endpoints
9
+ - Default handlers for incoming HTTP requests (with support for querying)
10
+ - Support for custom middleware
11
+ - Auto-loading of database schemas
12
+ - Automated (and overridable) database interaction
13
+ - Default permissions
14
+
15
+ ## Defining your API
16
+
17
+ To define an API, all you need to do is override the `setValues` function, making sure to change the values as appropriate.
18
+
19
+ See the below table for all values:
20
+
21
+ | Attribute | Type | Description | Optional |
22
+ | --------- | ---- | ----------- | -------- |
23
+ | `root` | `String` | This value will be used as the route for any URLs (e.g. `/api/mymodule`). For APIs which deal with collections of data, the general rule is to use the plural form (ie. `/api/items`). | `false` |
24
+ | `router` | `Router` | The Router instance used for HTTP requests. If not defined, a new router will be created using the `root` value. | `true` |
25
+ | `routes` | `Array<ApiRoute>` | Definitions for any routes to be added to the API router. | `false` |
26
+ | `collectionName` | `String` | Default DB collection to store data to (can be overridden by individual handlers). | `false` |
27
+
28
+ ### Defining routes
29
+
30
+ Before your API can handle HTTP requests, you must define which routes the router should respond to. If your module extends AbstractApiModule, this is simply a case of setting the [`routes`](../class/node_modules/adapt-authoring-api/lib/abstractApiModule.js~AbstractApiModule.html#instance-member-routes) instance variable:
31
+
32
+ ```js
33
+ this.routes = [
34
+ // route config here
35
+ ]
36
+ ```
37
+
38
+ #### General tips
39
+ The Adapt server module maps to Express functionality as closely as possible, and as such adopts the same middleware/handler concepts (with a few minor changes). It is therefore very useful to have some understanding of how the Express stack works, particularly with regards to the execution order of middleware and handlers. For more details on route handling, see the [official Express documentation](https://expressjs.com/en/guide/routing.html).
40
+
41
+ Here are a few useful notes/tips:
42
+
43
+ - The `route` attribute of each route definition is very powerful, and handles params/queries/etc. in the same way as Express (see [the Express docs](https://expressjs.com/en/guide/routing.html) for more).
44
+ - Use the API's middleware to perform any tasks which are common to all routes, such as checking and formatting the request data
45
+ - You only need to specify route handlers for the routes/HTTP methods you want to enable, access will be blocked to any route/HTTP method combinations you haven't defined
46
+ - You can run route-specific middleware by adding it as a handler to the route config (see example 2. below)
47
+
48
+ #### Using the default route configuration
49
+ Instead of defining each route yourself, the AbstractApiModule class also gives you a set of default routes which you can use if you wish:
50
+ ```js
51
+ [
52
+ // POST, no params
53
+ {
54
+ route: '/',
55
+ modifying: true,
56
+ handlers: {
57
+ post: this.requestHandler()
58
+ }
59
+ },
60
+ // GET, optional _id param
61
+ {
62
+ route: '/:_id?',
63
+ handlers: {
64
+ get: this.requestHandler()
65
+ }
66
+ },
67
+ // PUT/DELETE, mandatory _id param
68
+ {
69
+ route: '/:_id',
70
+ modifying: true,
71
+ handlers: {
72
+ put: this.requestHandler(),
73
+ delete: this.requestHandler()
74
+ }
75
+ },
76
+ // POST custom query handler
77
+ {
78
+ route: '/query',
79
+ validate: false,
80
+ handlers: {
81
+ post: this.queryHandler()
82
+ }
83
+ }
84
+ ];
85
+ ```
86
+ To use the above configuration, you simply need to call the `useDefaultRouteConfig` function:
87
+ ```js
88
+ async setValues() {
89
+ this.useDefaultRouteConfig();
90
+ }
91
+ ```
92
+
93
+ ### Example configurations
94
+ ```js
95
+ /**
96
+ * Basic configuration
97
+ */
98
+ async setValues() {
99
+ const server = await this.app.waitForModule('server');
100
+ this.root = 'myapi';
101
+ this.collectionName = 'mycollection';
102
+ this.router = server.api.createChildRouter('myapi'); // optional
103
+ this.router.addMiddleware(this.myMiddleware);
104
+ this.routes = [
105
+ {
106
+ route: '/',
107
+ handlers: { // if you need reference to 'this' in your handler, remember to bind
108
+ get: this.myRequestHandler.bind(this)
109
+ }
110
+ },
111
+ {
112
+ route: '/two',
113
+ handlers: { // example of route-level middleware
114
+ post: [ this.myOtherMiddleware, this.myPostHandler ]
115
+ }
116
+ }
117
+ ];
118
+ }
119
+ /**
120
+ * Custom route configuration
121
+ */
122
+ async setValues() {
123
+ // @note other values omitted for brevity
124
+ this.routes = [
125
+ {
126
+ route: '/',
127
+ schemaName: 'myschema', // can specify custom schema/collection like this
128
+ collectionName: 'myothercollection',
129
+ handlers: {
130
+ get: this.myRequestHandler.bind(this)
131
+ }
132
+ }
133
+ ];
134
+ }
135
+ ```
@@ -0,0 +1,32 @@
1
+ {
2
+ "API_MODULE_INVALID_CLASS": {
3
+ "data": {
4
+ "name": "Name of the module"
5
+ },
6
+ "description": "Module does not extend AbstractApiModule",
7
+ "statusCode": 500
8
+ },
9
+ "HTTP_METHOD_NOT_SUPPORTED": {
10
+ "data": {
11
+ "method": "The invalid HTTP method"
12
+ },
13
+ "description": "HTTP method for a given request is not supported",
14
+ "statusCode": 404
15
+ },
16
+ "NO_COLL_NAME": {
17
+ "description": "module is missing a collection name",
18
+ "statusCode": 500
19
+ },
20
+ "NO_ROOT_OR_ROUTER_DEF": {
21
+ "description": "module is missing both a root and router definition",
22
+ "statusCode": 500
23
+ },
24
+ "NO_ROUTES_DEF": {
25
+ "description": "module is missing API routes definition",
26
+ "statusCode": 500
27
+ },
28
+ "NO_SCHEMA_DEF": {
29
+ "description": "No json schema has been defined",
30
+ "statusCode": 404
31
+ }
32
+ }
package/index.js ADDED
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Abstract API utilities
3
+ * @namespace api
4
+ */
5
+ export { default as AbstractApiModule } from './lib/AbstractApiModule.js'
6
+ export { default as AbstractApiUtils } from './lib/AbstractApiUtils.js'
7
+ export { default } from './lib/AbstractApiModule.js'