Skip to content

Commit

Permalink
feat: add api package
Browse files Browse the repository at this point in the history
  • Loading branch information
njfamirm committed Nov 12, 2022
1 parent c0b6153 commit 118ca37
Show file tree
Hide file tree
Showing 17 changed files with 2,289 additions and 0 deletions.
20 changes: 20 additions & 0 deletions api/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# EditorConfig is awesome: https://EditorConfig.org

root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
max_line_length = 120

[*.{js,ts}]
block_comment_start = /**
block_comment = *
block_comment_end = */

[*.md]
trim_trailing_whitespace = false
7 changes: 7 additions & 0 deletions api/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Reference: https://eslint.org/docs/user-guide/configuring/ignoring-code

# dependencies
node_modules/

# build
dist/
68 changes: 68 additions & 0 deletions api/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
{
"root": true,
"extends": [
"eslint:recommended",
"google",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended",
"plugin:wc/recommended",
"plugin:import/recommended",
"plugin:import/typescript"
],
"env": {
"node": true,
"es2021": true
},
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 2021,
"sourceType": "module"
},
"plugins": ["@typescript-eslint", "import"],
"settings": {
"import/resolver": {
"typescript": {
"alwaysTryTypes": true
}
}
},
"rules": {
"max-len": [
"error",
{
"code": 120
}
],
"no-eval": [
"error",
{
"allowIndirect": true
}
],
"no-floating-decimal": "error",
"space-infix-ops": "error",
"new-cap": [
"error",
{
"capIsNewExceptionPattern": "Mixin$"
}
],
"brace-style": ["error", "stroustrup", {"allowSingleLine": true}],
"operator-linebreak": ["error", "after", {"overrides": {"?": "before", ":": "before"}}],
"@typescript-eslint/explicit-function-return-type": "error",
"import/order": [
"error",
{
"groups": ["builtin", "external", "internal", ["parent", "sibling", "index"], "type"],
"newlines-between": "always",
"alphabetize": {
"order": "asc",
"caseInsensitive": true
}
}
],
"import/no-unresolved": "off",
"require-jsdoc": "off",
"valid-jsdoc": "off"
}
}
31 changes: 31 additions & 0 deletions api/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Specifies intentionally untracked files to ignore when using Git
# http://git-scm.com/docs/gitignore

# OSX
.DS_STORE
.DS_Store
._*

# Windows
Thumbs.db
Desktop.ini

# Logs
*.log*

# Build
dist

# Dependencies
node_modules
package-lock.json

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env
.env.test

# storage
_data
4 changes: 4 additions & 0 deletions api/.prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"singleQuote": true,
"bracketSpacing": false
}
15 changes: 15 additions & 0 deletions api/.vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"recommendations": [
"editorconfig.editorconfig",
"dbaeumer.vscode-eslint",
"streetsidesoftware.code-spell-checker",
"streetsidesoftware.code-spell-checker-persian",
"esbenp.prettier-vscode",
"christian-kohler.path-intellisense",
"jgclark.vscode-todo-highlight",
"redhat.vscode-yaml",
"GitHub.vscode-pull-request-github",
"DavidAnson.vscode-markdownlint",
"humao.rest-client"
]
}
14 changes: 14 additions & 0 deletions api/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"eslint.packageManager": "yarn",
"npm.packageManager": "yarn",
"editor.wordWrapColumn": 120,
"editor.formatOnPaste": false,
"editor.formatOnSave": false,
"editor.codeActionsOnSave": {
"source.fixAll": true
},
"editor.defaultFormatter": "esbenp.prettier-vscode",
"typescript.tsdk": "node_modules\\typescript\\lib",
"cSpell.language": "en,fa,fa-IR",
"cSpell.words": ["alwatr", "mihandoost"]
}
1 change: 1 addition & 0 deletions api/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Alwatr Microservice/Nanoservice Starter Kit
23 changes: 23 additions & 0 deletions api/demo.http
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
@apiUrl = http://localhost:80
@apiVersion = v1

## add job
POST {{apiUrl}}/{{apiVersion}}/add
Content-Type: application/json

{
"origin": "KIH",
"dest": "THR",
"date": "1401/10/10"
}

### === Test other routes and errors ===

# not valid data
POST {{apiUrl}}/{{apiVersion}}/add-job
Content-Type: application/json

{
"origin": "KIH",
"date": "1401/10/10"
}
70 changes: 70 additions & 0 deletions api/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
{
"name": "alwatr-nanoservice-starter",
"version": "0.20.0",
"description": "Alwatr Microservice/Nanoservice Starter Kit",
"type": "module",
"keywords": [
"microservice",
"nanoservice",
"api",
"typescript",
"esm",
"alwatr"
],
"author": "S. Ali Mihandoost <ali.mihandoost@gmail.com> (https://ali.mihandoost.com)",
"license": "MIT",
"private": true,
"repository": {
"type": "git",
"url": "https://github.com/AliMD/alwatr",
"directory": "packages/starter/nanoservice"
},
"homepage": "https://github.com/AliMD/alwatr/tree/main/packages/starter/nanoservice#readme",
"bugs": {
"url": "https://github.com/AliMD/alwatr/issues"
},
"scripts": {
"l": "yarn lint",
"b": "yarn build",
"cb": "npm-run-all --sequential clean build",
"s": "npm-run-all --sequential clean build serve",
"w": "yarn watch",
"f": "yarn format",
"fl": "yarn format:eslint",
"fp": "yarn format:prettier",
"start": "yarn serve",
"lint": "npm-run-all --sequential lint:*",
"lint:ts": "eslint **/*.ts",
"build": "npm-run-all --sequential build:*",
"build:ts": "tsc --build",
"format": "npm-run-all --sequential format:prettier format:eslint",
"format:eslint": "eslint **/*.ts --fix",
"format:prettier": "prettier \"**/*.{html,json,md,ts}\" --ignore-path ./.eslintignore --write",
"clean": "rimraf dist/",
"serve": "node dist/index.js",
"serve:debug": "node --inspect dist/index.js",
"watch": "npm-run-all --parallel watch:ts watch:node",
"watch:node": "nodemon --ignore _data/ dist/index.js",
"watch:debug-node": "nodemon --ignore _data/ --inspect dist/index.js",
"watch:ts": "yarn build:ts --watch --preserveWatchOutput"
},
"dependencies": {
"@alwatr/logger": "^0.20.0",
"@alwatr/math": "^0.20.0",
"@alwatr/nano-server": "^0.20.0"
},
"devDependencies": {
"@types/node": "^18.11.9",
"@typescript-eslint/eslint-plugin": "^5.42.1",
"@typescript-eslint/parser": "^5.42.1",
"eslint": "^8.27.0",
"eslint-config-google": "^0.14.0",
"eslint-import-resolver-typescript": "^3.5.2",
"eslint-plugin-import": "^2.26.0",
"nodemon": "^2.0.20",
"npm-run-all": "^4.1.5",
"prettier": "^2.7.1",
"rimraf": "^3.0.2",
"typescript": "4.8.4"
}
}
4 changes: 4 additions & 0 deletions api/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import './route/echo.js';
import {logger} from './lib/config.js';

logger.logOther('..:: Flight Find API ::..');
14 changes: 14 additions & 0 deletions api/src/lib/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import {createLogger} from '@alwatr/logger';
import {isNumber} from '@alwatr/math';

export const config = {
port: isNumber(process.env.PORT) ? +process.env.PORT! : 80,
host: process.env.HOST ?? 'localhost',
storageApiDomain: process.env.STORAGE_API_DOMAIN ?? 'http://localhost',
storageName: process.env.STORAGE_NAME ?? 'sample',
storageToken: process.env.STORAGE_TOKEN,
};

export const logger = createLogger('api');

logger.logProperty('config', config);
5 changes: 5 additions & 0 deletions api/src/lib/nano-server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import {AlwatrNanoServer} from '@alwatr/nano-server';

import {config} from './config.js';

export const nanoServer = new AlwatrNanoServer({port: config.port, host: config.host});
11 changes: 11 additions & 0 deletions api/src/lib/parser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* validate and parse airline information
* return null if information not valid
*/
export function validateBodyJson(bodyJson: Record<string, unknown>): boolean {
// check have safe type
if (bodyJson.date === undefined || bodyJson.dest === undefined || bodyJson.origin === undefined) return false;

// The data is valid now
return true;
}
76 changes: 76 additions & 0 deletions api/src/route/echo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import {logger, config} from '../lib/config.js';
import {nanoServer} from '../lib/nano-server.js';
import {validateBodyJson} from '../lib/parser.js';

import type {AlwatrConnection} from '@alwatr/nano-server';

// add job API
nanoServer.route('POST', '/add', handler);

async function handler(connection: AlwatrConnection): Promise<void> {
logger.logMethod('handler');

const bodyJson = await connection.requireJsonBody();

if (bodyJson === null) {
connection.reply({
ok: false,
errorCode: 'DATA_REQUIRED',
statusCode: 422,
data: {
app: 'Job API',
message: 'Data required',
},
});
return;
}

// parse and validate data
const isBodyJsonValid = validateBodyJson(bodyJson);
if (isBodyJsonValid === false) {
connection.reply({
ok: false,
errorCode: 'DATA_NOT_VALID',
statusCode: 422,
data: {
app: 'Job API',
message: 'Data not valid',
},
});
return;
}

// add job
const storageReponse = await fetch(`${config.storageApiDomain}/${config.storageName}`, {
method: 'POST',
headers: {
Authorization: `Bearer ${config.storageToken}`,
},
body: JSON.stringify({
_id: Math.random().toString(),
_updatedBy: 'bot',
...bodyJson,
}),
});

if (!storageReponse.ok) {
connection.reply({
ok: false,
statusCode: 500,
errorCode: '',
data: {
app: 'Job API',
message: 'Internal server error',
},
});
return;
}

connection.reply({
ok: true,
data: {
app: 'Job API',
message: 'New job added',
},
});
}
Loading

0 comments on commit 118ca37

Please sign in to comment.