@aciiverse/generator-aciifx-cli v1.1.1
aciiFX-CLI
Simple & Powerful Aciiverse NodeTS Backend
Hier ist die Doku ebenfalls in deutsch.
Developer
Credits
aciiFX
Additionally for the generator
Additionally for the demo app
- html5
- css3
Features
- simple and powerful api basic framework
- user system with middleware
- simple & modular translation module
- types from backend to frontend (Types2FrontendApp)
Generate your own project
What you need
- NodeJS (>= vXX)
- TypeScript
npm install -g typescript
- Erreichbare MySQL Datenbank
Installation
Install Yeoman
npm install -g yo
Install the aciiFX-CLI generator
npm i -g @aciiverse/generator-aciifx-cli
The following options are available for a more detailed selection
- demo directory: Only install it if you want to test aciifx. It generates you a simple html page that should show the main functions of aciiFX.cli. Open the
./demo/index.html
file inside your browser.
Perform the generator in your desired folder (!Attention The generator generates its own folder in your folder!)
yo @aciiverse/aciifx-cli
Now run the command
npm run start:dev
or alternatively you can go to thepackage.json
and find the commandstart:dev
atscripts
Develop with aciiFX
You develop in the
./aciiFX/src/
directoryHere are a few examples of how to use the functions:
Routes
New Route (Modules)
To create a new route, create a new typecript file. Put the new file as follows: ./aciiFX/src/lib/route/{your route}.route.ts
. Replace {your route} with your desired route. Here are a few examples (The /service
route is an exception):
Module | Route | File | Usecase |
---|---|---|---|
Users | /users/login | users.route.ts | Login the Users |
Users | /users/register | users.route.ts | Register the user |
Games | /games | games.route.ts | Display of all games |
Games | /games/:id | games.route.ts | Display of a game |
Games | /games/:id/scoreboard | games.route.ts | Display of the points of a game |
Games | /games/:id/players | games.route.ts | Display of the players of a game |
The content of your routing file should look initially as follows (for example: games.route.ts
):
import express = require("express");
import { db } from "../db";
const router = express.Router();
router.get("/", (req: express.Request, res: express.Response) => {
// Handles GET "/games"
});
router.get("/game/:id", (req: express.Request, res: express.Response) => {
// Handles GET "/game/1", "/game/2", "/game/3", etc...
});
module.exports = router;
Route output (Return) :
A few examples of how you can hand over to Express data to the frontend
A standard output only with a message:
res.status(202).send({ message: "Success", });
An output with message and file:
const result = [ { id: 1, name: "Assassin's Creed Shadows" }, { id: 2, name: "Assassin's Creed Valhallah" } ]; res.status(202).send({ message: "Success", data: result });
An image or other file (saved as a blob):
const image = { data: <...>, type: 'image/png' } res.setHeader('Content-Type', image.type); res.end(image.data, 'binary');
API Types (Types2FrontendApp)
You can automatically make your API types (Request and Response) available for the frontend.
- Create all the requests and response types in
./aciiFX/src/lib/types/api.types.ts
. The name convention of the types is as follows:{Request Art (Get, Post, Put, Delete)}{Name der Route}{Req oder Res}
For example:GetUsersLoginReq
. This includes the following types:
Request Types: All types that map the body data that you get from the frontend:
const body: GetUsersLoginReq = req.body;
Response types: All types that are sent to the frontend:
return res.status(200).send({ <Deine Daten> } as GetUsersLoginRes);
- To make the guys accessible, carry out the command
npm run export:types
- Now the folder
./apiTypes
is generated. These types can now simply be imported from the frontend like modules.
Translation module (Lang)
To always get the current language, you can use the lang module.
- In the folder
./aciiFX/lang
you will find .json files. You can add your own for e.g. french ->fr.lang.json
- In the .env file you set a standard language.
- Which text is taken first is decided as follows:
- the language that is given to the function
- the language that is defined in the
.env
(FX_LANG_DEFAULT_LANGUAGE
) - english
en.lang.json
You can get a text as follows:
// In config file: { "err.test": "Hello World!" } const text = lang.getText("err.test"); console.log(text); // Hello World!
You can also give values as an string:
// In config file: { "err.test": "Hello {0}!" } const text = lang.getText("err.test", { values: "Ezio" }); console.log(text); // Hello World!
or as an array:
// In config file: { "err.test": "Hello {0} {1}!" } const text = lang.getText("err.test", { values: ["Ezio", "Auditore"] }); console.log(text); // Hello Ezio Auditore!
The requested language can also be defined with
options
:// In de.lang.json config file: { "err.test": "Hello World!" } // In en.lang.json config file: { "err.test": "Hallo Welt!" } // In .env: FX_LANG_DEFAULT_LANGUAGE=en const text = lang.getText("err.test", { lang: 'de' }); console.log(text); // Hallo Welt!
SQL Queries
SQL Queries are through the db
module simplified. As in this example, you can carry out an SQL query without tanging yourself into promise nesting
a query looks like this:
try { const result: GamesResult = await db.query("SELECT * FROM games WHERE gameId = ?;", [gameId]); } catch (error) { // -> error inside sql query console.error(error); }
the queries can be combined as desired:
router.get("/games/:id", async (req, res) => { const gameId = req.params.id; try { // execute sql query const games: GamesResult = await db.query("SELECT * FROM games WHERE gameId = ?;", [gameId]); // validate if (!games) { // -> games are undefined throw Error; // go into catch block } else if (Array.isArray(games) && !games.length) { // -> No data founded throw Error; // go into catch block } // optional second, third, etc... query BEGIN const players: GamesResult = await db.query("SELECT * FROM players WHERE gameId = ?;", [gameId]); // validate if (!players) { // -> games are undefined throw Error; // go into catch block } else if (Array.isArray(players) && !players.length) { // -> No data founded return res.status(401).send({ message: lang.getText("err.noPlayers founded"), }); } // optional second, third, etc... query END // success res.status(202).send({ message: lang.getText("suc.gamesFounded"), data: games }); } catch (error) { // error occured console.error(error); res.status(401).send({ message: lang.getText("err.insideSQLQuery"), }); } });