Skip to content

Commit

Permalink
feat(components): simplified api, fixed http2 api, changed routing ap…
Browse files Browse the repository at this point in the history
…i parameters

this PR fixes error starting up http2 server, it simplifies routing method parameters

BREAKING CHANGE: routhing method parameters changed, middleware and route callbacks now receive
fourth and third arguments respectively, that contains a pathParams object containing the routes
matched parameters
  • Loading branch information
teclone committed Dec 23, 2023
1 parent cdf4f91 commit 47d114f
Show file tree
Hide file tree
Showing 23 changed files with 961 additions and 1,663 deletions.
3 changes: 3 additions & 0 deletions .husky/commit-msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
yarn commitlint --edit $1
7 changes: 7 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

# run test:precommit when ready
# npx lint-staged && yarn test:precommit

# npx lint-staged
4 changes: 4 additions & 0 deletions .husky/prepare-commit-msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

exec < /dev/tty && npx cz --hook || true
2 changes: 1 addition & 1 deletion .server.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const { createConfig } = require('./build/cjs');
module.exports = createConfig({
https: {
enabled: false,
enforce: true,
enforce: false,
credentials: {
key: '.cert/server.key',
cert: '.cert/server.crt',
Expand Down
1 change: 1 addition & 0 deletions commitlint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = { extends: ['@commitlint/config-conventional'] }
15 changes: 9 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"build"
],
"scripts": {
"commit": "git-cz",
"prepare": "husky install",
"pretest": "bash ./scripts/gen-ssl-cert.sh",
"test": "cross-env BABEL_ENV=test jest --runInBand",
"build": "yarn rollup-all",
Expand Down Expand Up @@ -50,19 +50,20 @@
},
"homepage": "https://github.com/teclone/r-server#readme",
"devDependencies": {
"@commitlint/cli": "^16.2.3",
"@commitlint/config-conventional": "^16.2.1",
"@semantic-release/github": "^8.0.7",
"@teclone/rollup-all": "^1.26.0",
"@teclone/rollup-all": "^1.29.1",
"@types/jest": "24.0.11",
"@types/request-promise": "^4.1.47",
"@typescript-eslint/eslint-plugin": "^5.59.1",
"@typescript-eslint/parser": "^5.59.1",
"babel-jest": "^29.5.0",
"commitizen": "4.0.3",
"coveralls": "3.0.3",
"cross-env": "^7.0.3",
"cz-conventional-changelog": "2.1.0",
"eslint": "^8.39.0",
"eslint-config-prettier": "^8.8.0",
"husky": "^8.0.3",
"jest": "^29.5.0",
"js-beautify": "1.7.5",
"prettier": "^2.8.8",
Expand All @@ -72,11 +73,13 @@
"semantic-release": "^17.4.2",
"semantic-release-cli": "5.2.0",
"source-map-support": "0.5.12",
"typescript": "^4.2.3"
"typescript": "^4.2.3",
"commitizen": "^4.2.4",
"cz-conventional-changelog": "3.3.0"
},
"config": {
"commitizen": {
"path": "cz-conventional-changelog"
"path": "./node_modules/cz-conventional-changelog"
}
},
"dependencies": {
Expand Down
87 changes: 46 additions & 41 deletions src/@types/index.d.ts → src/@types/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { IncomingHttpHeaders } from 'http';
import { ServerRequest } from '../modules/Request';
import { ServerResponse } from '../modules/Response';

Expand Down Expand Up @@ -89,7 +90,7 @@ export type Method =
| 'delete'
| '*';

export type Url = string;
export type Path = string;

export type RouteId = number;

Expand All @@ -99,7 +100,7 @@ export type Parameter = string | number | boolean;

export interface Next {
(): true;
reset: () => boolean;
reset: () => void;
status: () => boolean;
}

Expand All @@ -109,8 +110,7 @@ export type Callback<
> = (
request: Rq,
response: Rs,
params: ObjectOfAny,
options?: ObjectOfAny
options: { pathParams: PathParameters } & Record<string, any>
) => Promise<boolean>;

export type ErrorCallback<
Expand All @@ -130,44 +130,18 @@ export type Middleware<
request: Rq,
response: Rs,
next: Next,
params: ObjectOfAny,
options?: ObjectOfAny
options: { pathParams: PathParameters } & Record<string, any>
) => Promise<boolean> | boolean;

export type ListenerCallback = () => void;

export interface CallbackOptions {
use: Middleware | Middleware[];
options?: ObjectOfAny;
}

export interface MiddlewareOptions {
method: Method | Method[];
options?: ObjectOfAny;
}

export interface ResolvedCallbackOptions {
use: Middleware[];
options?: ObjectOfAny;
}

export interface ResolvedMiddlewareOptions {
method: Method[];
options?: ObjectOfAny;
}

export type RouteInstance = [
RouteId,
Url,
Callback,
null | ResolvedCallbackOptions
];
export type RouteInstance = [RouteId, Path, Callback, Middleware[]];

export type MiddlewareInstance = [
MiddlewareId,
Url,
Path,
Middleware[],
null | ResolvedMiddlewareOptions
Set<Method>
];

export interface FileEntry {
Expand Down Expand Up @@ -232,6 +206,11 @@ export interface Data {
[propName: string]: string | string[];
}

export type PathParameters<T extends string = string> = Record<
T,
string | number | boolean
>;

export interface Headers {
[propName: string]: string;
}
Expand All @@ -256,11 +235,37 @@ export interface RouteParameter {
value: string | number | boolean;
}

export interface Routes {
options: RouteInstance[];
head: RouteInstance[];
get: RouteInstance[];
post: RouteInstance[];
put: RouteInstance[];
delete: RouteInstance[];
export type Routes = Record<Exclude<Method, '*'>, RouteInstance[]>;

export interface RouteResponse<ResponseData = {}> {
status?: 'success' | 'error';
statusCode?: number;
message?: string;
data?: ResponseData;
headers?: IncomingHttpHeaders;
ttl?: number;
}

export interface APIExecutor<RequestBody, ResponseData> {
(arg: {
/**
* request body, should be a combination of parsed post body and url search params
*/
body: RequestBody;

/**
* request http headers
*/
headers: IncomingHttpHeaders;

/**
* request path parameters, as contained in the routing path
*/
pathParams: PathParameters;
}): Promise<RouteResponse<ResponseData> | null>;

/**
* assigned name of the handler
*/
apiName?: string;
}
9 changes: 3 additions & 6 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,8 @@ export { Server } from './modules/Server';
export { Router } from './modules/Router';

export { Http1Request, Http2Request } from './modules/Request';
export {
Http1Response,
Http2Response,
RouteResponse,
APIExecutor,
} from './modules/Response';
export { Http1Response, Http2Response } from './modules/Response';

export * from './@types';

export const createConfig = (config: RServerConfig) => config;
14 changes: 8 additions & 6 deletions src/modules/BodyParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,14 +236,16 @@ export class BodyParser {
}

/**
* parse the query parameters in the given url
* converts url search parameters to object
* @param searchParams
* @returns
*/
parseQueryString(url: string): Data {
if (url.indexOf('?') > -1) {
return this.parseUrlEncoded(url.split('?')[1]);
} else {
return {};
urlSearchParamsToObject(searchParams: URLSearchParams) {
const result: Data = {};
for (const key of searchParams.keys()) {
result[key] = searchParams.get(key);
}
return result;
}

/**
Expand Down
10 changes: 8 additions & 2 deletions src/modules/Constants.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import { Routes } from '../@types';
import { Method, Routes } from '../@types';

// this matches a route token path in the form of {dataType:pathParameterName} or {pathParameterName}
const singleToken = '\\{((?:[a-z]+:)?[a-z]+)\\}';

// single token regex
export const SINGLE_TOKEN_REGEX = new RegExp(singleToken, 'i');

// double token regex, helps capture routh tokens that targets two pairs of from and to values
// eg {dataType:fromPathParameterName}-{dataType:toPathParameterName}
// or {dataType:fromPathParameterName}.{dataType:toPathParameterName}
export const DOUBLE_TOKEN_REGEX = new RegExp(
singleToken + '([-.])' + singleToken,
'i'
Expand All @@ -26,7 +32,7 @@ export const assignRouteId = () => ++routeId;

export const assignMiddlewareId = () => ++middlewareId;

export const ROUTE_KEYS: Array<keyof Routes> = [
export const ALL_METHODS: Method[] = [
'options',
'head',
'get',
Expand Down
Loading

0 comments on commit 47d114f

Please sign in to comment.