efriend
Version:
EFriend Node Library
291 lines (290 loc) • 13.7 kB
JavaScript
"use strict";
/**
* 한국투자증권 EFriendExpert API
*
* @file packages/EFriendExpert/efriends/efriend.ts
* @version 0.0.1
* @license GNU General Public License v3.0
* @copyright 2017~2023, EFriendExport Community Team
* @author gye hyun james kim <pnuskgh@gmail.com>
*/
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.EFriend = exports.limit = void 0;
const moment_1 = __importDefault(require("moment")); //--- format : YYYYMMDDHHmmss.SSS ZZ - 20191220172919.083 +0900
const index_js_1 = require("../common/error/index.js");
const efriend_limit_js_1 = require("./efriend.limit.js");
const efriend_limit_constant_js_1 = require("./efriend.limit.constant.js");
// import EFriend_JSON_TRID, { METADATA } from './efriend.constant.js';
const efriendRest_js_1 = require("./efriendRest.js");
exports.limit = new efriend_limit_js_1.EFriendLimit();
class EFriend {
// private indexQuery: number = -1;
// private indexOrder: number = -1;
// private limit = new EFriendLimit();
constructor({ logger }) {
this.secrets = [];
this.logger = logger !== null && logger !== void 0 ? logger : console;
this.efriendRest = new efriendRest_js_1.EFriendRest({ logger: this.logger });
this.initialize();
}
isOperatingTime(today = (0, moment_1.default)()) {
const day = today.day(); //--- 요일, 0. 일요일, 1. 월요일, ..., 6. 토요일
if ((day < 1) || (5 < day)) {
return { code: 1, message: '평일에만 작업 가능 합니다.' };
}
const hhmm = today.format('HH:mm'); //--- 시간과 분
if ((hhmm < '09:00') || ('15:30' < hhmm)) {
return { code: 2, message: '오전 9시부터 오후 5시 30분까지만 작업 가능 합니다.' };
}
return { code: 0, message: '운영 시간' };
}
initialize() {
//--- To-Do: EFriendRest 함수를 EFriend에 구현
//--- To-Do: EFriend에서 EFriendRest 함수를 호출할 때, 장애 발생시 재시도 또는 복구 작업 추가
//--- To-Do: EFriend에서 EFriendRest 함수를 호출할 때, secret 생략
// for (const [_key, value] of Object.entries(EFriend_JSON_TRID)) {
// const trid: string = value.info.trid;
// this[trid] = async function(secret, requestHeader, requestBody, responseHeader) {
// return await this.efriendRest.request(secret, trid, requestHeader, requestBody, responseHeader);
// };
// }
//--- To-Do: EFriendWs의 함수를 EFriend에 구현
//--- To-Do: EFriend에서 EFriendWs의 함수를 호출할 때, 장애 발생시 재시도 또는 복구 작업 추가
//--- To-Do: EFriend에서 EFriendWs의 함수를 호출할 때, secret 생략
}
get rest() {
return this.efriendRest;
}
getSecrets() {
return this.secrets;
}
tokenToSecret(secret) {
if ((typeof (secret.tokens) != 'undefined') && (0 < secret.tokens.length)) {
secret.access_token = secret.tokens[0].access_token;
secret.token_type = secret.tokens[0].token_type;
secret.expires_in = secret.tokens[0].expires_in;
secret.access_token_token_expired = secret.tokens[0].access_token_token_expired;
}
return secret;
}
tokenToSecrets(secrets) {
for (let idx = 0; idx < secrets.length; idx++) {
secrets[idx] = this.tokenToSecret(secrets[idx]);
}
return secrets;
}
setLimit(secrets) {
exports.limit.initialize(secrets);
}
setSecrets(secrets, isSimpleSet = false) {
return __awaiter(this, void 0, void 0, function* () {
try {
if (isSimpleSet) {
this.secrets = secrets;
}
else {
this.setLimit(secrets);
this.secrets = yield this.getActiveSecrets(secrets, true, true);
}
this.secrets = this.tokenToSecrets(this.secrets);
return this.secrets;
}
catch (ex) {
throw ex;
}
});
}
getActiveSecrets(secrets = this.secrets, refresh = true, isWaiting = false) {
return __awaiter(this, void 0, void 0, function* () {
try {
const today = (0, moment_1.default)().format('YYYY-MM-DD');
const results = [];
for (let secret of secrets) {
if (today <= secret.periodTo) {
if (refresh) {
try {
secret.tokens = yield this.getActiveTokens(secret, refresh, isWaiting);
results.push(this.tokenToSecret(secret));
}
catch (ex) {
console.error(ex);
}
}
else {
results.push(secret);
}
}
}
return results;
}
catch (ex) {
throw ex;
}
});
}
getActiveTokens(secret, refresh = true, isWaiting = false) {
var _a, _b, _c, _d, _e, _f;
return __awaiter(this, void 0, void 0, function* () {
try {
const now = (0, moment_1.default)().format('YYYY-MM-DD HH:mm:ss');
const secretTokens = (_a = secret.tokens) !== null && _a !== void 0 ? _a : [];
const tokens = [];
for (const token of secretTokens) {
if ((token.access_token_token_expired != null) && (token.access_token_token_expired != '') && (now <= token.access_token_token_expired)) {
tokens.push(token);
}
else {
if (token.access_token != '') {
yield this.fetchTokenRemove(secret, token);
}
}
}
if ((0 == secretTokens.length) || (secretTokens[0].access_token != secret.access_token)) {
const token = {
id: -1,
access_token: (_b = secret.access_token) !== null && _b !== void 0 ? _b : '',
token_type: (_c = secret.token_type) !== null && _c !== void 0 ? _c : '',
expires_in: (_d = secret.expires_in) !== null && _d !== void 0 ? _d : 0,
access_token_token_expired: (_e = secret.access_token_token_expired) !== null && _e !== void 0 ? _e : '',
secretId: (_f = secret.id) !== null && _f !== void 0 ? _f : -1
};
if ((token.access_token_token_expired != null) && (token.access_token_token_expired != '') && (now <= token.access_token_token_expired)) {
tokens.push(token);
}
else {
if (token.access_token != '') {
yield this.fetchTokenRemove(secret, token);
}
}
}
if ((refresh) && (tokens.length == 0)) {
tokens.push(yield this.fetchToken(secret, isWaiting));
}
return tokens;
}
catch (ex) {
throw ex;
}
});
}
fetchToken(secret, isWaiting = false) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
return __awaiter(this, void 0, void 0, function* () {
try {
yield exports.limit.waitingTokenP(secret, isWaiting);
const requestHeader = {};
const requestBody = {
grant_type: 'client_credentials',
appkey: secret.appkey || secret.appKey,
appsecret: secret.appsecret || secret.appSecret
};
const response = yield this.efriendRest.tokenP(secret, requestHeader, requestBody);
if (response.code == 0) {
if (typeof (response.body) != 'undefined') {
const token = {
id: -1,
access_token: (_b = (_a = response.body) === null || _a === void 0 ? void 0 : _a.access_token) !== null && _b !== void 0 ? _b : '',
token_type: (_d = (_c = response.body) === null || _c === void 0 ? void 0 : _c.token_type) !== null && _d !== void 0 ? _d : '',
expires_in: (_f = (_e = response.body) === null || _e === void 0 ? void 0 : _e.expires_in) !== null && _f !== void 0 ? _f : 0,
access_token_token_expired: (_h = (_g = response.body) === null || _g === void 0 ? void 0 : _g.access_token_token_expired) !== null && _h !== void 0 ? _h : '',
secretId: (_j = secret.id) !== null && _j !== void 0 ? _j : -1
};
return token;
}
else {
throw new index_js_1.BaseError({ code: index_js_1.ERROR_CODE.REQUIRED, data: `tokenP: ${response.message}.` });
}
}
else {
throw new index_js_1.BaseError({ code: index_js_1.ERROR_CODE.REQUIRED, data: `tokenP: ${response.message}` });
}
}
catch (ex) {
throw ex;
}
});
}
fetchTokenRemove(secret, token) {
return __awaiter(this, void 0, void 0, function* () {
try {
const requestHeader = {};
const requestBody = {
appkey: secret.appkey || secret.appKey,
appsecret: secret.appsecret || secret.appSecret,
token: token.access_token
};
const response = yield this.efriendRest.revokeP(secret, requestHeader, requestBody);
if (response.code == 0) {
return true;
}
else {
console.log('Error : fetchTokenRemove', response);
// throw new BaseError({ code: ERROR_CODE.REQUIRED, data: `revokeP: ${response.message}` });
return true;
}
}
catch (ex) {
console.error(ex);
return false;
}
});
}
//--- 접속키 유효기간: 24시간
//--- 접속키는 세션 연결시 초기 1회만 사용
resetApprovalKey(secret) {
return __awaiter(this, void 0, void 0, function* () {
try {
const [approval_key, approval_key_expired] = yield this.fetchApprovalKey(secret);
secret.approval_key = approval_key;
secret.approval_key_expired = approval_key_expired;
return secret;
}
catch (ex) {
throw ex;
}
});
}
fetchApprovalKey(secret) {
var _a, _b, _c, _d;
return __awaiter(this, void 0, void 0, function* () {
try {
const requestHeader = {
"content-type": 'application/json; charset=utf-8',
};
const requestBody = {
grant_type: 'client_credentials',
appkey: secret.appkey || secret.appKey,
secretkey: secret.appsecret || secret.appSecret
};
const response = yield this.efriendRest.Approval(secret, requestHeader, requestBody);
if (response.code == 0) {
secret.approval_key = (_b = (_a = response.body) === null || _a === void 0 ? void 0 : _a.approval_key) !== null && _b !== void 0 ? _b : undefined;
if (typeof (secret.approval_key) != 'undefined') {
secret.approval_key_expired = (0, moment_1.default)().add(efriend_limit_constant_js_1.EFriend_LIMIT.ws_api.expiration_period, 'hours').format('YYYY-MM-DD HH:mm:ss');
}
return [(_c = secret.approval_key) !== null && _c !== void 0 ? _c : '', (_d = secret.approval_key_expired) !== null && _d !== void 0 ? _d : ''];
}
else {
throw new index_js_1.BaseError({ code: index_js_1.ERROR_CODE.REQUIRED, data: `Approval: ${response.message}` });
}
}
catch (ex) {
throw ex;
}
});
}
}
exports.EFriend = EFriend;
exports.default = EFriend;