diff --git a/.gitignore b/.gitignore index fedd203..8312012 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /node_modules /dist yarn-error.log +.DS_Store diff --git a/README.md b/README.md index 936de91..ea577b6 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,17 @@ # OBP-TypeScript -## Usage +#### Install -#### Symlink - -Checkout the obp-typescript library from https://github.com/OpenBankProject/OBP-TypeScript. -Inside the obp-sdk repository folder, execute the **yarn link** command. +##### yarn ``` - yarn link + yarn add obp-typescript ``` -To link the **obp-typescript** library into your app, run the command inside your app. +##### npm ``` - yarn link obp-typescript + npm install obp-typescript ``` #### Example diff --git a/examples/any.ts b/examples/any.ts index 18e7c66..05bb71e 100644 --- a/examples/any.ts +++ b/examples/any.ts @@ -4,16 +4,22 @@ import { DirectLoginAuthentication, Version, get, + create, + update, + discard, Any, GetAny, + CreateAny, + UpdateAny, + DiscardAny, } from "../src/api"; -import { OAuthConfig } from "../src/oauth"; +import { OAuthConfig } from "../src/auth"; -//const directLogin: DirectLoginAuthentication = { -// username: process.env.OBP_USERNAME, -// password: process.env.OBP_PASSWORD, -// consumerKey: process.env.OBP_CONSUMER_KEY, -//}; +const directLogin: DirectLoginAuthentication = { + username: process.env.OBP_USERNAME, + password: process.env.OBP_PASSWORD, + consumerKey: process.env.OBP_CONSUMER_KEY, +}; const oauthConfig: OAuthConfig = { baseUri: "https://apisandbox.openbankproject.com", consumerKey: "qhpewipvmnm3ivjk4eoanjauzac34hm0hlec3tct", @@ -28,17 +34,79 @@ const oauthConfig: OAuthConfig = { const clientConfig: APIClientConfig = { baseUri: "https://apisandbox.openbankproject.com", version: Version.v510, - //authentication: directLogin, - oauthConfig: oauthConfig, + withFixedVersion: true, + authentication: directLogin, + //oauthConfig: oauthConfig, }; (async () => { // Get Resource Docs + //console.log( + // await get(clientConfig, Any)(GetAny)( + // "/resource-docs/v5.1.0/obp?tags=Account" + // ) + //); + //// Get current user login + //console.log(await get(clientConfig, Any)(GetAny)("/users/current")); + + // Create transaction + //const transaction = { + // description: "test transaction full data", + // to: { + // bank_id: "rbs", + // account_id: "9e6b2f45-a449-4e87-b772-e74cc9d42448", + // }, + // value: { + // currency: "EUR", + // amount: 1.0, + // }, + //}; + //console.log( + // await create(clientConfig, Any)(CreateAny)( + // "banks/rbs/accounts/9e6b2f45-a449-4e87-b772-e74cc9d42448/owner/transaction-request-types/ACCOUNT/transaction-requests" + // )(transaction) + //); + // Create transaction attribute + //const transactionAttributeNew = { + // name: "HOUSE_RENT", + // type: "DATE_WITH_DAY", + // value: "123456789", + //}; + //console.log( + // await create(clientConfig, Any)(CreateAny)( + // "banks/rbs/accounts/9e6b2f45-a449-4e87-b772-e74cc9d42448/transaction-requests/12f996cf-d3a9-4df3-8a1e-697a603609dd/attribute" + // )(transactionAttributeNew) + //); + // Update transaction + //const transactionAttributeUpdate = { + // name: "HOUSE_RENT", + // type: "DATE_WITH_DAY", + // value: "0000000", + //}; + //console.log( + // await update(clientConfig, Any)(UpdateAny)( + // "banks/rbs/accounts/9e6b2f45-a449-4e87-b772-e74cc9d42448/transaction-requests/12f996cf-d3a9-4df3-8a1e-697a603609dd/attributes/49ff9d5f-3f7d-4b58-987a-de99cdbf2b39" + // )(transactionAttributeUpdate) + //); + // Create transaction attribute definition + //const transactionAttributeDefinition = { + // name: "SPECIAL_TAX_NUMBER", + // category: "TransactionRequest", + // type: "STRING", + // description: "description", + // alias: "STRING", + // can_be_seen_on_views: ["bank"], + // is_active: true, + //}; + //console.log( + // await update(clientConfig, Any)(UpdateAny)( + // "banks/rbs/attribute-definitions/transaction-request" + // )(transactionAttributeDefinition) + //); + // Delete transaction attribute definition console.log( - await get(clientConfig, Any)(GetAny)( - "/resource-docs/v5.1.0/obp?tags=Account" + await discard(clientConfig, Any)(DiscardAny)( + "banks/rbs/attribute-definitions/06122dff-8575-4ff1-9f42-427d3e44ac88/transaction-request" ) ); - // Get current user login - console.log(await get(clientConfig, Any)(GetAny)("/users/current")); })(); diff --git a/examples/transaction.ts b/examples/transaction.ts index dd9995b..71d4c99 100644 --- a/examples/transaction.ts +++ b/examples/transaction.ts @@ -3,7 +3,7 @@ import { Version, APIClientConfig, DirectLoginAuthentication, - create, + post, get, Transaction, } from "../src/api"; @@ -52,7 +52,7 @@ const viewId = "owner"; amount: 1.0, }, }; - await create( + await post( clientConfig, Transaction )(CreateTransactionRequestAccount)( diff --git a/jest.config.ts b/jest.config.ts index a9075d8..472ed32 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -13,11 +13,9 @@ const jestConfig: JestConfigWithTsJest = { obpUsername: process.env.OBP_USERNAME, obpPassword: process.env.OBP_PASSWORD, obpConsumerKey: process.env.OBP_CONSUMER_KEY, - //obpBaseUri: "https://apisandbox.openbankproject.com", - obpBaseUri: "https://obp-apisandbox.joinfincubator.com", + obpBaseUri: "https://apisandbox.openbankproject.com", obpVersion: "v5.1.0", - //obpTestBank: "rbs", - obpTestBankId: "joinfincubator.01.uk.bk0", + obpTestBank: "obp1", }, }; diff --git a/package.json b/package.json index 78804b0..59e737f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "obp-typescript", - "version": "1.0.0", - "license": "MIT", + "version": "1.0.2", + "license": "Apache-2.0", "scripts": { "build": "tsc && tsc-alias", "test": "jest --setupFiles dotenv/config", @@ -49,5 +49,27 @@ "__tests__/**/*.ts": [ "yarn lint" ] - } + }, + "description": "## Usage", + "main": "index.js", + "directories": { + "doc": "docs", + "example": "examples" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/OpenBankProject/OBP-TypeScript.git" + }, + "keywords": [ + "typescript", + "open banking", + "obp", + "javascript", + "functional" + ], + "author": "", + "bugs": { + "url": "https://github.com/OpenBankProject/OBP-TypeScript/issues" + }, + "homepage": "https://github.com/OpenBankProject/OBP-TypeScript#readme" } diff --git a/src/api/any.ts b/src/api/any.ts index 1879d18..17e5449 100644 --- a/src/api/any.ts +++ b/src/api/any.ts @@ -28,6 +28,7 @@ import { APIRequest, APIClientConfig, apiCallWithCustomURIPath, + apiCallWithCustomBody, } from "./client"; /** @@ -51,6 +52,77 @@ export const GetAny = return await methodCall(config, path); }; +/** + * Create Any Request. + * + * @param config - The APIClientConfig object + * @param methodCall - A higher order function + * @returns A curried function + * + * @see {@link APIClientConfig} + * @see {@link TransactionRequestAccountBody} + * + * @public + */ +export const CreateAny = + ( + config: APIClientConfig, + methodCall: ( + config: APIClientConfig, + path: string, + body: any + ) => Promise + ) => + (path: string) => { + return apiCallWithCustomBody(config, path, methodCall); + }; + +/** + * Update Any Request. + * + * @param config - The APIClientConfig object + * @param methodCall - A higher order function + * @returns A curried function + * + * @see {@link APIClientConfig} + * @see {@link TransactionRequestAccountBody} + * + * @public + */ +export const UpdateAny = + ( + config: APIClientConfig, + methodCall: ( + config: APIClientConfig, + path: string, + body: any + ) => Promise + ) => + (path: string) => { + return apiCallWithCustomBody(config, path, methodCall); + }; + +/** + * Delete Any Request. + * + * @param config - The APIClientConfig object + * @param methodCall - A higher order function + * @returns A curried function + * + * @see {@link APIClientConfig} + * @see {@link TransactionRequestAccountBody} + * + * @public + */ +export const DiscardAny = + ( + config: APIClientConfig, + methodCall: (config: APIClientConfig, path: string) => Promise + ) => + async (path: string) => { + return await methodCall(config, path); + }; + /** * Returns an anonymous function for creating or getting Any data. * @@ -70,4 +142,30 @@ export const Any: APIRequest = { ) => { return apiCallWithCustomURIPath(config, methodCall); }, + create: ( + config: APIClientConfig, + methodCall: ( + config: APIClientConfig, + path: string, + body: any + ) => Promise + ) => { + return apiCallWithCustomURIPath(config, methodCall); + }, + update: ( + config: APIClientConfig, + methodCall: ( + config: APIClientConfig, + path: string, + body: any + ) => Promise + ) => { + return apiCallWithCustomURIPath(config, methodCall); + }, + discard: ( + config: APIClientConfig, + methodCall: (config: APIClientConfig, path: string) => Promise + ) => { + return apiCallWithCustomURIPath(config, methodCall); + }, }; diff --git a/src/api/client.ts b/src/api/client.ts index 581a61d..e581615 100644 --- a/src/api/client.ts +++ b/src/api/client.ts @@ -24,7 +24,7 @@ */ import superagent from "superagent"; -import { OAuth, OAuthConfig } from "../oauth"; +import { OAuth, OAuthConfig } from "../auth"; /** * OBP API Versions. @@ -126,6 +126,8 @@ export type MethodCall = ( export type APIRequest = { get?: (config: APIClientConfig, methodCall: MethodCall) => any; create?: (config: APIClientConfig, methodCall: MethodCall) => any; + update?: (config: APIClientConfig, methodCall: MethodCall) => any; + discard?: (config: APIClientConfig, methodCall: MethodCall) => any; }; /** @@ -254,7 +256,35 @@ const getDirectLoginToken = async ( }; /** - * Send a GET request and returns a response. + * Get the Oauth header. + * + * @param config - The APIClientConfig object + * @returns An {object} value + * + * @see APIClientConfig + */ +const getOauthHeader = async ( + config: APIClientConfig, + path: string, + pathUri: string +): Promise => { + let header: any; + if (config.oauthConfig) { + if (!config.oauthConfig.baseUri) + config.oauthConfig["baseUri"] = config.baseUri; + const oauth = new OAuth(config.oauthConfig); + header = oauth.authHeader(pathUri, "GET"); + } else { + if (!config.token) { + config.token = await getDirectLoginToken(config); + header = config.token; + } + } + return header; +}; + +/** + * Send a GET HTTP request and returns a response. * * @param config - The APIClientConfig object * @returns An {object} value @@ -268,25 +298,19 @@ export const getRequest = async ( path: string ): Promise => { const pathUri = uri(config, path); - let header: any; - if (config.oauthConfig) { - if (!config.oauthConfig.baseUri) - config.oauthConfig["baseUri"] = config.baseUri; - const oauth = new OAuth(config.oauthConfig); - header = oauth.authHeader(pathUri, "GET"); - } else { - if (!config.token) { - config.token = await getDirectLoginToken(config); - header = config.token; - } - } + const header = await getOauthHeader(config, path, pathUri); return JSON.parse( - (await superagent.get(pathUri).set("Authorization", header)).text + ( + await superagent + .get(pathUri) + .set("Authorization", header) + .catch((error) => error.response) + ).text ); }; /** - * Send a POST request and returns a response. + * Send a POST HTTP request and returns a response. * * @param config - The APIClientConfig object * @param path - The URI path @@ -303,15 +327,72 @@ export const postRequest = async ( body: any ): Promise => { const pathUri = uri(config, path); - if (!config.token) { - config.token = await getDirectLoginToken(config); - } + const header = await getOauthHeader(config, path, pathUri); return JSON.parse( ( await superagent .post(pathUri) - .set("Authorization", config.token) + .set("Authorization", header) .send(body) + .catch((error) => error.response) + ).text + ); +}; + +/** + * Send a PUT HTTP request and returns a response. + * + * @param config - The APIClientConfig object + * @param path - The URI path + * @param body - The request body + * @returns An {object} value + * + * @see APIClientConfig + * + * @public + */ +export const putRequest = async ( + config: APIClientConfig, + path: string, + body: any +): Promise => { + const pathUri = uri(config, path); + const header = await getOauthHeader(config, path, pathUri); + return JSON.parse( + ( + await superagent + .put(pathUri) + .set("Authorization", header) + .send(body) + .catch((error) => error.response) + ).text + ); +}; + +/** + * Send a DELETE HTTP request and returns a response. + * + * @param config - The APIClientConfig object + * @param path - The URI path + * @param body - The request body + * @returns An {object} value + * + * @see APIClientConfig + * + * @public + */ +export const deleteRequest = async ( + config: APIClientConfig, + path: string +): Promise => { + const pathUri = uri(config, path); + const header = await getOauthHeader(config, path, pathUri); + return JSON.parse( + ( + await superagent + .delete(pathUri) + .set("Authorization", header) + .catch((error) => error.response) ).text ); }; @@ -353,3 +434,41 @@ export const create = ( ): any => { return request.create(config, postRequest); }; + +/** + * A PUT request function that updates an API data and returns the result. + * + * @param config - The APIClientConfig object + * @param request - The APIRequest object + * @returns An @typeParam {Object} value + * + * @see APIClientConfig + * @see APIRequest + * + * @public + */ +export const update = ( + config: APIClientConfig, + request: APIRequest +): any => { + return request.update(config, putRequest); +}; + +/** + * A DELETE request function that deletes an API data. + * + * @param config - The APIClientConfig object + * @param request - The APIRequest object + * @returns An @typeParam {Object} value + * + * @see APIClientConfig + * @see APIRequest + * + * @public + */ +export const discard = ( + config: APIClientConfig, + request: APIRequest +): any => { + return request.discard(config, deleteRequest); +}; diff --git a/src/api/index.ts b/src/api/index.ts index ab65a11..1326bd2 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -40,7 +40,7 @@ export { CreateTransactionRequestAccount, } from "./transaction"; export { User, Current } from "./user"; -export { Any, GetAny } from "./any"; +export { Any, GetAny, CreateAny, UpdateAny, DiscardAny } from "./any"; export { API, Version, @@ -50,4 +50,6 @@ export { DirectLoginAuthentication, get, create, + update, + discard, } from "./client"; diff --git a/src/oauth/index.ts b/src/auth/index.ts similarity index 85% rename from src/oauth/index.ts rename to src/auth/index.ts index b38ca77..3415a2d 100644 --- a/src/oauth/index.ts +++ b/src/auth/index.ts @@ -79,14 +79,37 @@ export class OAuth { ); } + /** + * Get oauth.OAuth instance. + * + * @returns An {oauth.OAuth} value + * + * @public + */ get(): oauth.OAuth { return this.instance; } + /** + * Get OAuthConfig object. + * + * @returns An {OAuthConfig} value + * + * @public + */ configs(): OAuthConfig { return this.config; } + /** + * Get the Oauth authentication header. + * + * @param pathUri - The the relative path of the URL. + * @param method - The http method. + * @returns An {OAuthConfig} value + * + * @public + */ authHeader(pathUri: string, method: string): string { if (!this.config.accessToken) console.warn("Access token is not set."); diff --git a/src/index.ts b/src/index.ts index 586d675..a26eee6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -40,7 +40,7 @@ export { CreateTransactionRequestAccount, } from "./api/transaction"; export { User, Current } from "./api/user"; -export { Any, GetAny } from "./api/any"; +export { Any, GetAny, CreateAny, UpdateAny, DiscardAny } from "./api/any"; export { API, Version, @@ -50,5 +50,7 @@ export { DirectLoginAuthentication, get, create, + update, + discard, } from "./api/client"; export { OAuth, OAuthConfig } from "./oauth";