axe-api 0.19.2 → 0.20.0-rc3

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.
Files changed (38) hide show
  1. package/package.json +62 -56
  2. package/readme.md +152 -145
  3. package/.eslintrc.cjs +0 -24
  4. package/.github/PULL_REQUEST_TEMPLATE.md +0 -32
  5. package/.github/workflows/auto-tag.yml +0 -15
  6. package/.github/workflows/npm-publish.yml +0 -18
  7. package/.github/workflows/test-integration.yml +0 -29
  8. package/.github/workflows/test-unit.yml +0 -23
  9. package/CHANGELOG.md +0 -150
  10. package/babel.config.cjs +0 -12
  11. package/index.js +0 -21
  12. package/jest.config.js +0 -4
  13. package/src/Server.js +0 -118
  14. package/src/constants.js +0 -148
  15. package/src/core/Config.js +0 -38
  16. package/src/core/Docs.js +0 -43
  17. package/src/core/HttpResponse.js +0 -10
  18. package/src/core/IoC.js +0 -41
  19. package/src/core/Logger.js +0 -46
  20. package/src/core/Model.js +0 -86
  21. package/src/core/QueryParser.js +0 -544
  22. package/src/handlers/all.js +0 -73
  23. package/src/handlers/destroy.js +0 -50
  24. package/src/handlers/helpers.js +0 -320
  25. package/src/handlers/index.js +0 -9
  26. package/src/handlers/paginate.js +0 -77
  27. package/src/handlers/patch.js +0 -95
  28. package/src/handlers/show.js +0 -81
  29. package/src/handlers/store.js +0 -82
  30. package/src/handlers/update.js +0 -92
  31. package/src/resolvers/checkModelColumns.js +0 -113
  32. package/src/resolvers/detectDbColumns.js +0 -42
  33. package/src/resolvers/getModelInstanceArray.js +0 -27
  34. package/src/resolvers/getModelTree.js +0 -63
  35. package/src/resolvers/index.js +0 -17
  36. package/src/resolvers/setExpressRoutes.js +0 -286
  37. package/src/resolvers/setModelHooks.js +0 -25
  38. package/src/resolvers/setModelRelations.js +0 -41
package/package.json CHANGED
@@ -1,56 +1,62 @@
1
- {
2
- "name": "axe-api",
3
- "version": "0.19.2",
4
- "description": "AXE API is a simple tool which has been created based on Express and Knex.js to create Rest APIs quickly.",
5
- "main": "index.js",
6
- "type": "module",
7
- "directories": {
8
- "test": "tests"
9
- },
10
- "author": "Özgür Adem Işıklı <i.ozguradem@gmail.com>",
11
- "license": "ISC",
12
- "scripts": {
13
- "test": "jest --runInBand",
14
- "test:dev": "jest --watch",
15
- "lint": "eslint src/**",
16
- "lint:watch": "esw --watch --color",
17
- "test:integration:mysql8": "cd ./tests/integrations && node index.js mysql8",
18
- "test:integration:mysql57": "cd ./tests/integrations && node index.js mysql57",
19
- "test:integration:postgres": "cd ./tests/integrations && node index.js postgres"
20
- },
21
- "dependencies": {
22
- "change-case": "^4.1.2",
23
- "dotenv": "^14.2.0",
24
- "express": "^4.17.2",
25
- "knex": "^1.0.1",
26
- "knex-paginate": "^3.0.0",
27
- "knex-schema-inspector": "^1.7.1",
28
- "pluralize": "^8.0.0",
29
- "validatorjs": "^3.22.1"
30
- },
31
- "devDependencies": {
32
- "@babel/cli": "^7.16.8",
33
- "@babel/core": "^7.16.10",
34
- "@babel/node": "^7.16.8",
35
- "@babel/preset-env": "^7.16.11",
36
- "@babel/runtime": "^7.16.7",
37
- "babel-jest": "^27.4.6",
38
- "babel-loader": "^8.2.3",
39
- "babel-plugin-module-resolver": "^4.1.0",
40
- "babel-preset-minify": "^0.5.1",
41
- "eslint": "^7.31.0",
42
- "eslint-config-standard": "^16.0.3",
43
- "eslint-plugin-import": "^2.25.4",
44
- "eslint-plugin-node": "^11.1.0",
45
- "eslint-plugin-promise": "^5.1.0",
46
- "eslint-plugin-standard": "^5.0.0",
47
- "eslint-plugin-unicorn": "^33.0.1",
48
- "eslint-watch": "^7.0.0",
49
- "jest": "^27.4.7",
50
- "mysql": "^2.18.1",
51
- "nodemon": "^2.0.15",
52
- "pg": "^8.7.1",
53
- "set-value": ">=4.1.0",
54
- "sqlite3": "^5.0.2"
55
- }
56
- }
1
+ {
2
+ "name": "axe-api",
3
+ "version": "0.20.0-rc3",
4
+ "description": "AXE API is a simple tool which has been created based on Express and Knex.js to create Rest APIs quickly.",
5
+ "main": "build/index.js",
6
+ "types": "build/index.d.ts",
7
+ "files": [
8
+ "/build"
9
+ ],
10
+ "directories": {
11
+ "test": "tests"
12
+ },
13
+ "author": "Özgür Adem Işıklı <i.ozguradem@gmail.com>",
14
+ "license": "ISC",
15
+ "scripts": {
16
+ "build": "tsc",
17
+ "build:watch": "tsc -w",
18
+ "dev": "ts-node-dev --respawn --clear index.ts",
19
+ "test": "jest --runInBand",
20
+ "test:dev": "jest --watch",
21
+ "lint": "eslint src/**",
22
+ "lint:watch": "esw --watch --color",
23
+ "test:integration:mysql8": "cd ./tests/integrations && node index.js mysql8",
24
+ "test:integration:mysql57": "cd ./tests/integrations && node index.js mysql57",
25
+ "test:integration:postgres": "cd ./tests/integrations && node index.js postgres"
26
+ },
27
+ "dependencies": {
28
+ "change-case": "^4.1.2",
29
+ "dotenv": "^14.2.0",
30
+ "express": "^4.17.2",
31
+ "knex": "^1.0.1",
32
+ "knex-paginate": "^3.0.0",
33
+ "knex-schema-inspector": "^1.7.1",
34
+ "pluralize": "^8.0.0",
35
+ "validatorjs": "^3.22.1"
36
+ },
37
+ "devDependencies": {
38
+ "@babel/cli": "^7.16.8",
39
+ "@babel/core": "^7.16.10",
40
+ "@babel/node": "^7.16.8",
41
+ "@babel/preset-env": "^7.16.11",
42
+ "@babel/runtime": "^7.16.7",
43
+ "babel-jest": "^27.4.6",
44
+ "babel-loader": "^8.2.3",
45
+ "babel-plugin-module-resolver": "^4.1.0",
46
+ "babel-preset-minify": "^0.5.1",
47
+ "eslint": "^7.31.0",
48
+ "eslint-config-standard": "^16.0.3",
49
+ "eslint-plugin-import": "^2.25.4",
50
+ "eslint-plugin-node": "^11.1.0",
51
+ "eslint-plugin-promise": "^5.1.0",
52
+ "eslint-plugin-standard": "^5.0.0",
53
+ "eslint-plugin-unicorn": "^33.0.1",
54
+ "eslint-watch": "^7.0.0",
55
+ "jest": "^27.4.7",
56
+ "mysql": "^2.18.1",
57
+ "nodemon": "^2.0.15",
58
+ "pg": "^8.7.1",
59
+ "set-value": ">=4.1.0",
60
+ "sqlite3": "^5.0.2"
61
+ }
62
+ }
package/readme.md CHANGED
@@ -1,145 +1,152 @@
1
- <h1 align="center">
2
- <br>
3
- <a href="https://axe-api.github.io/">
4
- <img src="https://axe-api.github.io/logo.png" alt="Markdownify" width="200">
5
- </a>
6
- <br>
7
- Axe API
8
- <br>
9
- <a href="https://badge.fury.io/js/axe-api">
10
- <img src="https://badge.fury.io/js/axe-api.svg" alt="npm version" height="18">
11
- </a>
12
- <a href="https://github.com/axe-api/axe-api/actions/workflows/npm-publish.yml" target="_blank">
13
- <img src="https://github.com/axe-api/axe-api/actions/workflows/npm-publish.yml/badge.svg?branch=master">
14
- </a>
15
- <a href="https://sonarcloud.io/dashboard?id=axe-api_axe-api" target="_blank">
16
- <img src="https://sonarcloud.io/api/project_badges/measure?project=axe-api_axe-api&metric=alert_status">
17
- </a>
18
- <a href="https://github.com/axe-api/axe-api/issues" target="_blank">
19
- <img src="https://img.shields.io/github/issues/axe-api/axe-api.svg">
20
- </a>
21
- <a href="https://opensource.org/licenses/MIT" target="_blank">
22
- <img src="https://img.shields.io/badge/license-MIT-blue.svg">
23
- </a>
24
- </h1>
25
-
26
- The fastest way to create Rest API, by defining database models and relations.
27
-
28
- > Axe API has great documentation. Please [check it out in here](https://axe-api.github.io/).
29
-
30
- ## What Is Axe API?
31
-
32
- **Axe API** is the _fastest_ way to create **Rest API** by defining only database models and relationships between them. It is built on [Knex.js](http://knexjs.org), and its awesome active records pattern. On the other hand, you have another familiar thing, [Express](https://expressjs.com/).
33
-
34
- You are going to be able to develop an API **10 times faster** with **Axe API**!
35
-
36
- ## How It Works?
37
-
38
- [Express](https://expressjs.com/) and [Knex.js](http://knexjs.org) are great tools to create [Node.js](https://nodejs.org) based applications. But usually, we code too much the same things to design an API. We aim to reduce code duplication and give you speed by using Axe API.
39
-
40
- Axe API provides you the ability to separate your common tasks to build an API from your business logic. **Axe API** expects model definitions to analyze your routing structure. After you created your models and their relations between them, Axe API can handle all _well-known_ API requests. Creating an API with 5 tables takes almost 15 minutes.
41
-
42
- Shortly, **Axe API** performs three basic functions;
43
-
44
- - **Analyzes** your models and their relationships to create routes.
45
- - **Handles** all HTTP requests.
46
- - **Separate** your business logic from API best practices.
47
-
48
- Let's assume that you have a model like this;
49
-
50
- ```js
51
- import { Model } from "axe-api";
52
-
53
- class User extends Model {}
54
- ```
55
-
56
- With this model, you will have all of the basic API routes for **User** resources. **Axe API** will create **CRUD** routes for you in the _booting_ process and these routes would be completely ready to be handled and processed by Axe API. The following routes will be handled automatically;
57
-
58
- - `POST api/users`
59
- - `GET api/users`
60
- - `GET api/users/:id`
61
- - `PUT api/users/:id`
62
- - `DELETE api/users/:id`
63
-
64
- This is the magic of **Axe API**!
65
-
66
- ## Installation
67
-
68
- Using **Axe API** in an application is very easy. We've created a CLI tool for you; [axe-magic](https://github.com/axe-api/axe-magic).
69
-
70
- You can create a new Axe API project by using [axe-magic](https://github.com/axe-api/axe-magic). But first, you can install it in your development environment. When you installed it, you can be able to access **axe-magic** command via CLI. You can use the following command to install **axe-magic** to your machine;
71
-
72
- ```bash
73
- $ npm i -g axe-magic
74
- $ axe-magic --version
75
- 1.0.0
76
- ```
77
-
78
- After that, creating a new project is very easy. Just you can execute the following command;
79
-
80
- ```bash
81
- $ axe-magic new my-api
82
- ```
83
-
84
- This command will pull [axe-api-template](https://github.com/axe-api/axe-api-template) project to your current directory with a new name, **my-api**.
85
-
86
- To install your project's depencies, you can execute the following commands in the root directory;
87
-
88
- ```bash
89
- $ cd my-api
90
- $ npm install
91
- ```
92
-
93
- To serve this application, you can execute the following command;
94
-
95
- ```bash
96
- $ npm run start:dev
97
- ```
98
-
99
- > `start:dev` command use [nodemon](https://www.npmjs.com/package/nodemon). If you haven't installed it yet, we suggest you install it first.
100
-
101
- After that, your first **Axe API** application will be running in `localhost:3000`.
102
-
103
- You will see the following API response if you visit [localhost:3000](http://localhost:3000).
104
-
105
- ```json
106
- {
107
- "name": "AXE API",
108
- "description": "The best API creation tool in the world.",
109
- "aim": "To kill them all!"
110
- }
111
- ```
112
-
113
- If you can see that response, it means that your project is running properly.
114
-
115
- ## Documentation
116
-
117
- Axe API has great documentation. Please [check it out in here](https://axe-api.github.io/).
118
-
119
- ## How To Run Integration Tests
120
-
121
- > You have to have **Docker** and **Docker Compose** on your local development environment to run integration tests.
122
-
123
- Execute the following commands to prepare the integration app
124
-
125
- ```sh
126
- cd tests/integrations && npm install && npm ci && npm run build --if-present
127
- ```
128
-
129
- Execute the following commands to prepare the database;
130
-
131
- ```sh
132
- docker-compose -f "./tests/integrations/docker-compose.mysql8.yml" up -d --build
133
- ```
134
-
135
- > To down the database, you can use the following command; `docker-compose -f "./tests/integrations/docker-compose.mysql8.yml" up -d --build`
136
-
137
- You can execute the following command to execute tests;
138
-
139
- ```sh
140
- npm run test:integration:mysql8
141
- ```
142
-
143
- ## License
144
-
145
- [MIT License](LICENSE)
1
+ <h1 align="center">
2
+ <br>
3
+ <a href="https://axe-api.github.io/">
4
+ <img src="https://axe-api.github.io/logo.png" alt="Markdownify" width="200">
5
+ </a>
6
+ <br>
7
+ Axe API
8
+ <br>
9
+ <a href="https://badge.fury.io/js/axe-api">
10
+ <img src="https://badge.fury.io/js/axe-api.svg" alt="npm version" height="18">
11
+ </a>
12
+ <a href="https://github.com/axe-api/axe-api/actions/workflows/npm-publish.yml" target="_blank">
13
+ <img src="https://github.com/axe-api/axe-api/actions/workflows/npm-publish.yml/badge.svg?branch=master">
14
+ </a>
15
+ <a href="https://sonarcloud.io/dashboard?id=axe-api_axe-api" target="_blank">
16
+ <img src="https://sonarcloud.io/api/project_badges/measure?project=axe-api_axe-api&metric=alert_status">
17
+ </a>
18
+ <a href="https://github.com/axe-api/axe-api/issues" target="_blank">
19
+ <img src="https://img.shields.io/github/issues/axe-api/axe-api.svg">
20
+ </a>
21
+ <a href="https://opensource.org/licenses/MIT" target="_blank">
22
+ <img src="https://img.shields.io/badge/license-MIT-blue.svg">
23
+ </a>
24
+ </h1>
25
+
26
+ The fastest way to create Rest API, by defining database models and relations.
27
+
28
+ > Axe API has great documentation. Please [check it out in here](https://axe-api.github.io/).
29
+
30
+ ## What Is Axe API?
31
+
32
+ **Axe API** is the _fastest_ way to create **Rest API** by defining only database models and relationships between them. It is built on [Knex.js](http://knexjs.org), and its awesome active records pattern. On the other hand, you have another familiar thing, [Express](https://expressjs.com/).
33
+
34
+ You are going to be able to develop an API **10 times faster** with **Axe API**!
35
+
36
+ ## How It Works?
37
+
38
+ [Express](https://expressjs.com/) and [Knex.js](http://knexjs.org) are great tools to create [Node.js](https://nodejs.org) based applications. But usually, we code too much the same things to design an API. We aim to reduce code duplication and give you speed by using Axe API.
39
+
40
+ Axe API provides you the ability to separate your common tasks to build an API from your business logic. **Axe API** expects model definitions to analyze your routing structure. After you created your models and their relations between them, Axe API can handle all _well-known_ API requests. Creating an API with 5 tables takes almost 15 minutes.
41
+
42
+ Shortly, **Axe API** performs three basic functions;
43
+
44
+ - **Analyzes** your models and their relationships to create routes.
45
+ - **Handles** all HTTP requests.
46
+ - **Separate** your business logic from API best practices.
47
+
48
+ Let's assume that you have a model like this;
49
+
50
+ ```js
51
+ import { Model } from "axe-api";
52
+
53
+ class User extends Model {}
54
+ ```
55
+
56
+ With this model, you will have all of the basic API routes for **User** resources. **Axe API** will create **CRUD** routes for you in the _booting_ process and these routes would be completely ready to be handled and processed by Axe API. The following routes will be handled automatically;
57
+
58
+ - `POST api/users`
59
+ - `GET api/users`
60
+ - `GET api/users/:id`
61
+ - `PUT api/users/:id`
62
+ - `DELETE api/users/:id`
63
+
64
+ This is the magic of **Axe API**!
65
+
66
+ ## Installation
67
+
68
+ Using **Axe API** in an application is very easy. We've created a CLI tool for you; [axe-magic](https://github.com/axe-api/axe-magic).
69
+
70
+ You can create a new Axe API project by using [axe-magic](https://github.com/axe-api/axe-magic). But first, you can install it in your development environment. When you installed it, you can be able to access **axe-magic** command via CLI. You can use the following command to install **axe-magic** to your machine;
71
+
72
+ ```bash
73
+ $ npm i -g axe-magic
74
+ $ axe-magic --version
75
+ 1.0.0
76
+ ```
77
+
78
+ After that, creating a new project is very easy. Just you can execute the following command;
79
+
80
+ ```bash
81
+ $ axe-magic new my-api
82
+ ```
83
+
84
+ This command will pull [axe-api-template](https://github.com/axe-api/axe-api-template) project to your current directory with a new name, **my-api**.
85
+
86
+ To install your project's depencies, you can execute the following commands in the root directory;
87
+
88
+ ```bash
89
+ $ cd my-api
90
+ $ npm install
91
+ ```
92
+
93
+ To serve this application, you can execute the following command;
94
+
95
+ ```bash
96
+ $ npm run start:dev
97
+ ```
98
+
99
+ > `start:dev` command use [nodemon](https://www.npmjs.com/package/nodemon). If you haven't installed it yet, we suggest you install it first.
100
+
101
+ After that, your first **Axe API** application will be running in `localhost:3000`.
102
+
103
+ You will see the following API response if you visit [localhost:3000](http://localhost:3000).
104
+
105
+ ```json
106
+ {
107
+ "name": "AXE API",
108
+ "description": "The best API creation tool in the world.",
109
+ "aim": "To kill them all!"
110
+ }
111
+ ```
112
+
113
+ If you can see that response, it means that your project is running properly.
114
+
115
+ ## Documentation
116
+
117
+ Axe API has great documentation. Please [check it out in here](https://axe-api.github.io/).
118
+
119
+ ## How To Run Integration Tests
120
+
121
+ > You have to have **Docker** and **Docker Compose** on your local development environment to run integration tests.
122
+
123
+ Execute the following commands to prepare the integration app
124
+
125
+ ```sh
126
+ cd tests/integrations && npm install && npm ci && npm run build --if-present
127
+ ```
128
+
129
+ Execute the following commands to prepare the database;
130
+
131
+ ```sh
132
+ docker-compose -f "./tests/integrations/docker-compose.mysql8.yml" up -d --build
133
+ ```
134
+
135
+ > To down the database, you can use the following command; `docker-compose -f "./tests/integrations/docker-compose.mysql8.yml" up -d --build`
136
+
137
+ You can execute the following command to execute tests;
138
+
139
+ ```sh
140
+ npm run test:integration:mysql8
141
+ ```
142
+
143
+ ## License
144
+
145
+ [MIT License](LICENSE)
146
+
147
+ ## Prerelease
148
+
149
+ - Update package.json, set version to a prerelease version, e.g. 2.0.0-rc1, 3.1.5-rc4, ...
150
+ - Run npm pack to create package
151
+ - Run npm publish <package>.tgz --tag next to publish the package under the next tag
152
+ - Run npm install --save package@next to install prerelease package
package/.eslintrc.cjs DELETED
@@ -1,24 +0,0 @@
1
- module.exports = {
2
- env: {
3
- browser: true,
4
- es2021: true,
5
- jest: true,
6
- },
7
- extends: "eslint:recommended",
8
- parserOptions: {
9
- ecmaVersion: 12,
10
- sourceType: "module",
11
- },
12
- plugins: ["unicorn"],
13
- rules: {
14
- "unicorn/filename-case": [
15
- "error",
16
- {
17
- cases: {
18
- camelCase: true,
19
- pascalCase: true,
20
- },
21
- },
22
- ],
23
- },
24
- };
@@ -1,32 +0,0 @@
1
- ## Description
2
-
3
- <!--- Describe your changes in detail -->
4
-
5
- ## Motivation and Context
6
-
7
- <!--- Why is this change required? What problem does it solve? -->
8
- <!--- If it fixes an open issue, please link to the issue here. -->
9
-
10
- ## How has this been tested?
11
-
12
- <!--- Please describe in detail how you tested your changes. -->
13
- <!--- Include details of your testing environment, tests ran to see how -->
14
- <!--- your change affects other areas of the code, etc. -->
15
-
16
- ## Types of changes
17
-
18
- <!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
19
-
20
- - [ ] Bug fix (non-breaking change which fixes an issue)
21
- - [ ] New feature (non-breaking change which adds functionality)
22
- - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
23
-
24
- ## Checklist:
25
-
26
- <!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
27
- <!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
28
-
29
- - [ ] My changes requires documentation change.
30
- - [ ] The changes have been documented in the [axe-api/docs](https://github.com/axe-api/docs) repository. (<!--- Please insert the PR link -->)
31
- - [ ] I added integration tests properly.
32
- - [ ] The changes require [axe-api-template](https://github.com/axe-api/axe-api-template) changes. (<!--- Please insert the PR link -->)
@@ -1,15 +0,0 @@
1
- name: Create Tag
2
-
3
- on:
4
- push:
5
- branches:
6
- - master
7
-
8
- jobs:
9
- build:
10
- runs-on: ubuntu-latest
11
- steps:
12
- - uses: actions/checkout@v2
13
- - uses: butlerlogic/action-autotag@stable
14
- with:
15
- GITHUB_TOKEN: "${{ secrets.AUTO_TAG_TOKEN }}"
@@ -1,18 +0,0 @@
1
- name: NPM Publish
2
- on:
3
- push:
4
- branches:
5
- - master
6
- jobs:
7
- publish:
8
- runs-on: ubuntu-latest
9
- steps:
10
- - uses: actions/checkout@v1
11
- - uses: actions/setup-node@v1
12
- with:
13
- node-version: 14
14
- - run: npm install
15
- - run: npm test
16
- - uses: JS-DevTools/npm-publish@v1
17
- with:
18
- token: ${{ secrets.NPM_TOKEN }}
@@ -1,29 +0,0 @@
1
- name: Integration Tests
2
-
3
- on:
4
- pull_request:
5
- branches:
6
- - master
7
- - develop
8
-
9
- jobs:
10
- build:
11
- runs-on: ubuntu-latest
12
- strategy:
13
- matrix:
14
- node-version: [14.x, 16.x, 17.x]
15
- database: [mysql8, mysql57, "postgres"]
16
- steps:
17
- - uses: actions/checkout@v2
18
- - name: Use Node.js ${{ matrix.node-version }}
19
- uses: actions/setup-node@v1
20
- with:
21
- node-version: ${{ matrix.node-version }}
22
- - name: Start database containers
23
- run: docker-compose -f "./tests/integrations/docker-compose.${{ matrix.database }}.yml" up -d --build
24
- - name: Install integration test dependencies
25
- run: cd tests/integrations && npm install
26
- - run: npm ci
27
- - run: npm run build --if-present
28
- - name: Testing all scenarions
29
- run: npm run test:integration:${{ matrix.database }}
@@ -1,23 +0,0 @@
1
- name: Unit Tests
2
-
3
- on:
4
- pull_request:
5
- branches:
6
- - master
7
- - develop
8
-
9
- jobs:
10
- build:
11
- runs-on: ubuntu-latest
12
- strategy:
13
- matrix:
14
- node-version: [14.x, 16.x, 17.x]
15
- steps:
16
- - uses: actions/checkout@v2
17
- - name: Use Node.js ${{ matrix.node-version }}
18
- uses: actions/setup-node@v1
19
- with:
20
- node-version: ${{ matrix.node-version }}
21
- - run: npm ci
22
- - run: npm run build --if-present
23
- - run: npm run test