Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement a strictly typed service client for comms between services #7358

Closed
wants to merge 11 commits into from
38 changes: 38 additions & 0 deletions .github/workflows/check-schema-definitions.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
#
# OpenCRVS is also distributed under the terms of the Civil Registration
# & Healthcare Disclaimer located at http://opencrvs.org/license.
#
# Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS.

name: Ensure API schema definitions are up-to-date

on: [pull_request]

jobs:
test:
runs-on: ubuntu-22.04
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Use Node.js from .nvmrc
uses: actions/setup-node@v4
with:
node-version-file: .nvmrc

- name: Install dependencies
run: yarn install && yarn dev:secrets:gen

- name: Generate schema definitions
run: cd packages/commons && bash generate-api-types.sh

- name: Verify no changed files in git
run: |
if [[ -n $(git status --porcelain) ]]; then
echo "There are changes in the git repository. Stopping pipeline."
echo "Ensure the GraphQL types and internal API JSON schemas are generated properly"
exit 1
fi
3 changes: 2 additions & 1 deletion license-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@
"packages/dashboards/*.jar",
"packages/dashboards/plugins/*.jar",
"packages/dashboards/data/metabase/*.db",
"packages/client/dev-dist"
"packages/client/dev-dist",
"packages/commons/src/api-types/*.ts"
],
"license": "license-header.txt",
"licenseFormats": {
Expand Down
3 changes: 2 additions & 1 deletion packages/auth/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export async function createServer() {
if (HOSTNAME[0] !== '*') {
whitelist = [COUNTRY_CONFIG_URL, LOGIN_URL, CLIENT_APP_URL]
}
logger.info(`Whitelist: ${JSON.stringify(whitelist)}`)

const server = new Hapi.Server({
host: AUTH_HOST,
port: AUTH_PORT,
Expand Down Expand Up @@ -398,6 +398,7 @@ export async function createServer() {
async function start() {
await server.start()
await database.start()
logger.info(`Whitelist: ${JSON.stringify(whitelist)}`)
server.log('info', `server started on ${AUTH_HOST}:${AUTH_PORT}`)
}

Expand Down
12 changes: 12 additions & 0 deletions packages/commons/bin/export-json-schema.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env node
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* OpenCRVS is also distributed under the terms of the Civil Registration
* & Healthcare Disclaimer located at http://opencrvs.org/license.
*
* Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS.
*/
require('../build/dist/export-json-schema.js')
66 changes: 66 additions & 0 deletions packages/commons/generate-api-types.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
#
# OpenCRVS is also distributed under the terms of the Civil Registration
# & Healthcare Disclaimer located at http://opencrvs.org/license.
#
# Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS.

#!/bin/bash

set -euo pipefail

BASE_DIR="$(dirname "$(dirname "$(realpath "$0")")")"
OUTPUT_DIR="$(dirname "$(realpath "$0")")/src/api-types"

mkdir -p "$OUTPUT_DIR"

# List to keep track of directories
declare -a DIR_LIST

for dir in "$BASE_DIR"/*/; do
echo "$dir"

if [[ "$dir" == *"/gateway/"* ]]; then
continue
fi

if [[ -f "${dir}src/server.ts" ]]; then
DIR_NAME=$(basename "$dir")
DIR_LIST+=("$DIR_NAME")
(cd "$dir" && yarn --silent export-json-schema src/server.ts | yarn --silent json2ts --strictIndexSignatures | yarn --silent prettier --stdin-filepath types.ts > "$OUTPUT_DIR/${DIR_NAME}.ts")
fi
done

# Create src/api-types/index.ts file
INDEX_FILE="$OUTPUT_DIR/index.ts"

cat << EOF > $INDEX_FILE
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* OpenCRVS is also distributed under the terms of the Civil Registration
* & Healthcare Disclaimer located at http://opencrvs.org/license.
*
* Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS.
*/
EOF


for dir in "${DIR_LIST[@]}"; do
CLEANED_DIR_NAME=$(echo "$dir" | tr '-' '_')
echo "import { HapiRoutes as ${CLEANED_DIR_NAME}Routes } from './${dir}'" >> "$INDEX_FILE"
done

echo -e "\nexport type AllRoutes = {" >> "$INDEX_FILE"
for dir in "${DIR_LIST[@]}"; do
CLEANED_DIR_NAME=$(echo "$dir" | tr '-' '_')
echo " '${dir}': ${CLEANED_DIR_NAME}Routes;" >> "$INDEX_FILE"
done
echo "}" >> "$INDEX_FILE"

yarn prettier --write $INDEX_FILE

11 changes: 9 additions & 2 deletions packages/commons/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
"description": "OpenCRVS common modules and utils",
"license": "MPL-2.0",
"main": "./build/dist/index.js",
"bin": {
"export-json-schema": "bin/export-json-schema.js"
},
"exports": {
".": "./build/dist/index.js",
"./monitoring": "./build/dist/monitoring.js",
Expand Down Expand Up @@ -34,16 +37,19 @@
"@types/node-fetch": "^2.5.12",
"@types/uuid": "^9.0.3",
"date-fns": "^2.28.0",
"ts-node": "^6.1.1",
"elastic-apm-node": "^3.29.0",
"jest": "27.5.1",
"joi-to-json": "^4.3.0",
"json-schema-to-typescript": "^14.1.0",
"jwt-decode": "^2.2.0",
"lint-staged": "^15.2.2",
"lodash": "^4.17.10",
"node-fetch": "^2.6.7",
"pino": "^7.0.0",
"pkg-up": "^3.1.0",
"typescript": "4.9.5",
"uuid": "^9.0.0",
"pino": "^7.0.0"
"uuid": "^9.0.0"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^4.5.0",
Expand All @@ -53,6 +59,7 @@
"eslint-plugin-import": "^2.17.3",
"eslint-plugin-prettier": "^4.0.0",
"jest-fetch-mock": "^2.1.2",
"json2ts": "^0.0.7",
"pino-pretty": "^11.0.0",
"ts-jest": "27.1.4"
},
Expand Down
162 changes: 162 additions & 0 deletions packages/commons/src/api-types/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
/* eslint-disable */
/**
* This file was automatically generated by json-schema-to-typescript.
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
* and run json-schema-to-typescript to regenerate this file.
*/

export interface HapiRoutes {
get: {
'/.well-known': {
request: never
response: never
params: never
}
'/anonymous-token': {
request: never
response: {
token?: string
}
params: never
}
'/ping': {
request: never
response: never
params: never
}
}
post: {
'/authenticate': {
request: {
username?: string
password?: string
}
response: {
nonce?: string
mobile?: string
email?: string
status?: string
token?: string
}
params: never
}
'/authenticate-super-user': {
request: {
username?: string
password?: string
}
response: {
nonce?: string
mobile?: string
email?: string
status?: string
token?: string
}
params: never
}
'/changePassword': {
request: {
newPassword?: string
nonce?: string
}
response: never
params: never
}
'/invalidateToken': {
request: {
token?: string
}
response: never
params: never
}
'/refreshToken': {
request: {
nonce?: string
token?: string
}
response: {
token?: string
}
params: never
}
'/resendAuthenticationCode': {
request: {
nonce?: string
notificationEvent: string
retrievalFlow?: boolean
}
response: {
nonce?: string
}
params: never
}
'/sendUserName': {
request: {
nonce: string
}
response: never
params: never
}
'/token': {
request: never
response: never
params: never
}
'/verifyCode': {
request: {
nonce?: string
code?: string
}
response: {
token?: string
}
params: never
}
'/verifyNumber': {
request: {
nonce: string
code: string
}
response: {
nonce?: string
securityQuestionKey?: string
}
params: never
}
'/verifySecurityAnswer': {
request: {
answer: string
nonce: string
}
response: {
matched: boolean
securityQuestionKey?: string
nonce: string
}
params: never
}
'/verifyToken': {
request: {
token?: string
}
response: {
valid?: boolean
}
params: never
}
'/verifyUser': {
request: {
mobile?: string
email?: string
retrieveFlow: 'username' | 'password'
}
response: {
nonce: string
securityQuestionKey?: string
}
params: never
}
}
put?: {}
delete?: {}
}
Loading
Loading