From def230bf302ee3a2dde709c9da2ed87f1fa4c9e6 Mon Sep 17 00:00:00 2001 From: hide_d Date: Wed, 29 Dec 2021 03:55:40 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20ts=20APICall=EC=9D=84=20=EA=B0=95?= =?UTF-8?q?=EC=A0=9C=ED=99=94.=20-=20=EC=98=A4=EB=B2=84=20=EC=97=94?= =?UTF-8?q?=EC=A7=80=EB=8B=88=EC=96=B4=EB=A7=81=EC=9D=98=20=EC=A0=95?= =?UTF-8?q?=EC=84=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hwe/ts/APIPath.ts | 34 --------------- hwe/ts/PageChiefCenter.vue | 11 +++-- hwe/ts/PageInheritPoint.vue | 12 +++--- hwe/ts/PageJoin.vue | 6 +-- hwe/ts/PageNationStratFinan.vue | 9 ++-- hwe/ts/PartialReservedCommand.vue | 10 ++--- hwe/ts/SammoAPI.ts | 46 +++++++++++++++++++++ hwe/ts/SammoRootAPI.ts | 23 +++++++++++ hwe/ts/components/ChiefReservedCommand.vue | 4 +- hwe/ts/components/TipTap.vue | 4 +- hwe/ts/gateway/login.ts | 8 ++-- hwe/ts/util/APIPathGen.ts | 48 +++++++++++++--------- hwe/ts/util/callSammoAPI.ts | 35 ++++++++++++++++ hwe/ts/util/sammoAPI.ts | 35 ---------------- hwe/ts/v_processing.ts | 6 +-- src/makeAPIPath.ts | 0 16 files changed, 166 insertions(+), 125 deletions(-) delete mode 100644 hwe/ts/APIPath.ts create mode 100644 hwe/ts/SammoAPI.ts create mode 100644 hwe/ts/SammoRootAPI.ts create mode 100644 hwe/ts/util/callSammoAPI.ts delete mode 100644 hwe/ts/util/sammoAPI.ts create mode 100644 src/makeAPIPath.ts diff --git a/hwe/ts/APIPath.ts b/hwe/ts/APIPath.ts deleted file mode 100644 index 76145b53..00000000 --- a/hwe/ts/APIPath.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { APIPathGen } from "./util/APIPathGen"; - -const apiRealPath = { - Command: { - GetReservedCommand: '', - PushCommand: '', - RepeatCommand: '', - ReserveCommand: '', - }, - General: { - Join: '', - }, - InheritAction: { - BuyHiddenBuff: '', - BuyRandomUnique: '', - BuySpecificUnique: '', - ResetSpecialWar: '', - ResetTurnTime: '', - SetNextSpecialWar: '', - }, - Misc: { UploadImage: '' }, - NationCommand: { - GetReservedCommand: '', - PushCommand: '', - RepeatCommand: '', - ReserveCommand: '', - }, - Nation: { - SetNotice: '', - SetScoutMsg: '', - }, -} as const; - -export const APIPath = APIPathGen(apiRealPath); \ No newline at end of file diff --git a/hwe/ts/PageChiefCenter.vue b/hwe/ts/PageChiefCenter.vue index 6a60bc6e..6fdaef9f 100644 --- a/hwe/ts/PageChiefCenter.vue +++ b/hwe/ts/PageChiefCenter.vue @@ -242,7 +242,6 @@ import TopBackBar from "@/components/TopBackBar.vue"; import VueTypes from "vue-types"; import { isString, range } from "lodash"; import { mb_strwidth } from "./util/mb_strwidth"; -import { sammoAPI } from "./util/sammoAPI"; import { entriesWithType } from "./util/entriesWithType"; import { addMilliseconds } from "date-fns"; import { formatTime } from "./util/formatTime"; @@ -251,6 +250,7 @@ import { getNpcColor } from "./common_legacy"; import TopItem from "@/ChiefCenter/TopItem.vue"; import BottomItem from "@/ChiefCenter/BottomItem.vue"; import { ChiefResponse, OptionalFull } from "./defs"; +import { SammoAPI } from "./SammoAPI"; function isDropdownChildren(e?: Event): boolean { if (!e) { @@ -323,7 +323,7 @@ export default defineComponent({ }, async repeatNationCommand(amount: number) { try { - await sammoAPI(`NationCommand/RepeatCommand`, { amount }); + await SammoAPI.NationCommand.RepeatCommand({ amount }); } catch (e) { console.error(e); alert(`실패했습니다: ${e}`); @@ -333,7 +333,7 @@ export default defineComponent({ }, async pushNationCommand(amount: number) { try { - await sammoAPI("NationCommand/PushCommand", { amount }); + await SammoAPI.NationCommand.PushCommand({ amount }); } catch (e) { console.error(e); alert(`실패했습니다: ${e}`); @@ -390,9 +390,8 @@ export default defineComponent({ async function reloadTable(): Promise { try { - const response = await sammoAPI( - "NationCommand/GetReservedCommand" - ); + const response = + await SammoAPI.NationCommand.GetReservedCommand(); console.log(response); for (const [key, value] of entriesWithType(response)) { if (key === "result") { diff --git a/hwe/ts/PageInheritPoint.vue b/hwe/ts/PageInheritPoint.vue index b620d35d..9518c036 100644 --- a/hwe/ts/PageInheritPoint.vue +++ b/hwe/ts/PageInheritPoint.vue @@ -262,10 +262,8 @@ import "@scss/common/bootstrap5.scss"; import "@scss/game_bg.scss"; import TopBackBar from "@/components/TopBackBar.vue"; import _ from "lodash"; -import { InvalidResponse } from "@/defs"; -import axios from "axios"; import NumberInputWithInfo from "@/components/NumberInputWithInfo.vue"; -import { sammoAPI } from "./util/sammoAPI"; +import { SammoAPI } from "./SammoAPI"; type InheritanceType = | "previous" @@ -507,7 +505,7 @@ export default defineComponent({ } try { - await sammoAPI("InheritAction/BuyHiddenBuff", { + await SammoAPI.InheritAction.BuyHiddenBuff({ type: buffKey, level, }); @@ -550,7 +548,7 @@ export default defineComponent({ } try { - await sammoAPI(`InheritAction/${type}`, {}); + await SammoAPI.InheritAction[type]({}); } catch (e) { console.error(e); alert(`실패했습니다: ${e}`); @@ -584,7 +582,7 @@ export default defineComponent({ } try { - await sammoAPI(`InheritAction/SetNextSpecialWar`, { + await SammoAPI.InheritAction.SetNextSpecialWar({ type: this.nextSpecialWar, }); } catch (e) { @@ -616,7 +614,7 @@ export default defineComponent({ } try { - await sammoAPI(`InheritAction/BuySpecificUnique`, { + await SammoAPI.InheritAction.BuySpecificUnique({ item: this.specificUnique, amount, }); diff --git a/hwe/ts/PageJoin.vue b/hwe/ts/PageJoin.vue index 78ec6133..0f301023 100644 --- a/hwe/ts/PageJoin.vue +++ b/hwe/ts/PageJoin.vue @@ -315,10 +315,8 @@ import { abilityRand, } from "@util/generalStats"; import { clone, shuffle, sum } from "lodash"; -import axios from "axios"; -import { InvalidResponse } from "@/defs"; import NumberInputWithInfo from "@/components/NumberInputWithInfo.vue"; -import { sammoAPI } from "./util/sammoAPI"; +import { SammoAPI } from "./SammoAPI"; declare const nationList: { nation: number; @@ -536,7 +534,7 @@ export default defineComponent({ //검증은 언제 되어야 하는가? const args = clone(this.args); try { - await sammoAPI(["General", "Join"], args); + await SammoAPI.General.Join(args); } catch (e) { console.error(e); alert(`실패했습니다: ${e}`); diff --git a/hwe/ts/PageNationStratFinan.vue b/hwe/ts/PageNationStratFinan.vue index ef472860..f38fcbd8 100644 --- a/hwe/ts/PageNationStratFinan.vue +++ b/hwe/ts/PageNationStratFinan.vue @@ -56,10 +56,9 @@ import "@scss/common_legacy.scss"; import "@scss/editor_component.scss"; import TipTap from "./components/TipTap.vue"; import { defineComponent, reactive, ref, toRefs } from "vue"; -import { sammoAPI } from "./util/sammoAPI"; import { isString } from "lodash"; import { diplomacyState, NationStaticItem } from "./defs"; - +import { SammoAPI } from "./SammoAPI"; type NationItem = NationStaticItem & { cityCnt: number; diplomacy: { @@ -123,10 +122,12 @@ export default defineComponent({ self.nationMsg = oldNationMsg; } + console.log(SammoAPI.Nation.SetScoutMsg); + async function saveNationMsg() { const msg = self.nationMsg; try { - await sammoAPI("Nation/SetNotice", { + await SammoAPI.Nation.SetNotice({ msg, }); oldNationMsg = msg; @@ -152,7 +153,7 @@ export default defineComponent({ async function saveScoutMsg() { const msg = self.scoutMsg; try { - await sammoAPI("Nation/SetScoutMsg", { + await SammoAPI.Nation.SetScoutMsg({ msg, }); oldScoutMsg = msg; diff --git a/hwe/ts/PartialReservedCommand.vue b/hwe/ts/PartialReservedCommand.vue index 0a5b34b1..3b8358c2 100644 --- a/hwe/ts/PartialReservedCommand.vue +++ b/hwe/ts/PartialReservedCommand.vue @@ -260,9 +260,9 @@ import { joinYearMonth } from "@util/joinYearMonth"; import { mb_strwidth } from "@util/mb_strwidth"; import { parseTime } from "@util/parseTime"; import { parseYearMonth } from "@util/parseYearMonth"; -import { sammoAPI } from "@util/sammoAPI"; import { convertSearch초성 } from "./util/convertSearch초성"; import DragSelect from "@/components/DragSelect.vue"; +import { SammoAPI } from "./SammoAPI"; type commandItem = { value: string; @@ -404,7 +404,7 @@ export default defineComponent({ }, async repeatGeneralCommand(amount: number) { try { - await sammoAPI(`Command/RepeatCommand`, { amount }); + await SammoAPI.Command.RepeatCommand({ amount }); } catch (e) { console.error(e); alert(`실패했습니다: ${e}`); @@ -414,7 +414,7 @@ export default defineComponent({ }, async pushGeneralCommand(amount: number) { try { - await sammoAPI("Command/PushCommand", { amount }); + await SammoAPI.Command.PushCommand({ amount }); } catch (e) { console.error(e); alert(`실패했습니다: ${e}`); @@ -439,7 +439,7 @@ export default defineComponent({ async reloadCommandList() { let result: ReservedCommandResponse; try { - result = await sammoAPI("Command/GetReservedCommand"); + result = await SammoAPI.Command.GetReservedCommand(); } catch (e) { console.error(e); alert(`실패했습니다: ${e}`); @@ -524,7 +524,7 @@ export default defineComponent({ } try { - await sammoAPI("Command/ReserveCommand", { + await SammoAPI.Command.ReserveCommand({ turnList, action: commandName, }); diff --git a/hwe/ts/SammoAPI.ts b/hwe/ts/SammoAPI.ts new file mode 100644 index 00000000..31f9dada --- /dev/null +++ b/hwe/ts/SammoAPI.ts @@ -0,0 +1,46 @@ +import { InvalidResponse } from "./defs"; +import { APIPathGen } from "./util/APIPathGen"; +import { callSammoAPI, ValidResponse } from "./util/callSammoAPI"; +export type { ValidResponse, InvalidResponse }; + +async function done(args?: Record): Promise; +async function done(args: Record | undefined, returnError: false): Promise; +async function done(args: Record | undefined, returnError: true): Promise; + +async function done(args?: Record, returnError = false): Promise{ + console.error(`Can't directly call. ${args}, ${returnError}. Use auto-generated path API.`); + return callSammoAPI([], args, true); +} + +const apiRealPath = { + Command: { + GetReservedCommand: done, + PushCommand: done, + RepeatCommand: done, + ReserveCommand: done, + }, + General: { + Join: done, + }, + InheritAction: { + BuyHiddenBuff: done, + BuyRandomUnique: done, + BuySpecificUnique: done, + ResetSpecialWar: done, + ResetTurnTime: done, + SetNextSpecialWar: done, + }, + Misc: { UploadImage: done }, + NationCommand: { + GetReservedCommand: done, + PushCommand: done, + RepeatCommand: done, + ReserveCommand: done, + }, + Nation: { + SetNotice: done, + SetScoutMsg: done, + }, +} as const; + +export const SammoAPI = APIPathGen(apiRealPath); \ No newline at end of file diff --git a/hwe/ts/SammoRootAPI.ts b/hwe/ts/SammoRootAPI.ts new file mode 100644 index 00000000..4fb8a075 --- /dev/null +++ b/hwe/ts/SammoRootAPI.ts @@ -0,0 +1,23 @@ +import { InvalidResponse } from "./defs"; +import { APIPathGen } from "./util/APIPathGen"; +import { callSammoAPI, ValidResponse } from "./util/callSammoAPI"; +export type { ValidResponse, InvalidResponse }; + +async function done(args?: Record): Promise; +async function done(args: Record | undefined, returnError: false): Promise; +async function done(args: Record | undefined, returnError: true): Promise; + +async function done(args?: Record, returnError = false): Promise{ + console.error(`Can't directly call. ${args}, ${returnError}. Use auto-generated path API.`); + return callSammoAPI([], args, true); +} + +const apiRealPath = { + Login: { + LoginByID: done, + LoginByToken: done, + ReqNonce: done, + }, +} as const; + +export const SammoRootAPI = APIPathGen(apiRealPath); \ No newline at end of file diff --git a/hwe/ts/components/ChiefReservedCommand.vue b/hwe/ts/components/ChiefReservedCommand.vue index ecf8dcc3..8e64b1ac 100644 --- a/hwe/ts/components/ChiefReservedCommand.vue +++ b/hwe/ts/components/ChiefReservedCommand.vue @@ -151,11 +151,11 @@ import { joinYearMonth } from "@util/joinYearMonth"; import { mb_strwidth } from "@util/mb_strwidth"; import { parseTime } from "@util/parseTime"; import { parseYearMonth } from "@util/parseYearMonth"; -import { sammoAPI } from "@util/sammoAPI"; import { convertSearch초성 } from "@util/convertSearch초성"; import VueTypes from "vue-types"; import DragSelect from "@/components/DragSelect.vue"; import { isString } from "lodash"; +import { SammoAPI } from "@/SammoAPI"; type commandItem = { value: string; @@ -375,7 +375,7 @@ export default defineComponent({ } try { - await sammoAPI("NationCommand/ReserveCommand", { + await SammoAPI.NationCommand.ReserveCommand({ turnList, action: commandName, }); diff --git a/hwe/ts/components/TipTap.vue b/hwe/ts/components/TipTap.vue index a94281cd..db0ea843 100644 --- a/hwe/ts/components/TipTap.vue +++ b/hwe/ts/components/TipTap.vue @@ -351,9 +351,9 @@ import { import { v4 as uuidv4 } from "uuid"; import { unwrap } from "@/util/unwrap"; import { getBase64FromFileObject } from "@/util/getBase64FromFileObject"; -import { sammoAPI } from "@/util/sammoAPI"; import { isObject, isString } from "lodash"; import { AxiosError } from "axios"; +import { SammoAPI } from "@/SammoAPI"; const compoment = defineComponent({ components: { @@ -403,7 +403,7 @@ const compoment = defineComponent({ }; try { const base64Binary = await getBase64FromFileObject(targetImage); - imageResult = await sammoAPI("Misc/UploadImage", { + imageResult = await SammoAPI.Misc.UploadImage({ imageData: base64Binary, }); } catch (e) { diff --git a/hwe/ts/gateway/login.ts b/hwe/ts/gateway/login.ts index b1cd3641..a88665eb 100644 --- a/hwe/ts/gateway/login.ts +++ b/hwe/ts/gateway/login.ts @@ -12,8 +12,8 @@ import { InvalidResponse } from '@/defs'; import { delay } from '@util/delay'; import { Modal } from 'bootstrap'; import '@/gateway/common'; -import { sammoAPI } from '@/util/sammoAPI'; import { isString } from 'lodash'; +import { SammoRootAPI } from '@/SammoRootAPI'; type LoginResponse = { result: true, @@ -101,7 +101,7 @@ async function tryAutoLogin() { const [tokenID, token] = tokenInfo; - const result = await sammoAPI(["Login", "ReqNonce"], {}, true); + const result = await SammoRootAPI.Login.ReqNonce({}, true); if (!result) { //api 에러. @@ -116,7 +116,7 @@ async function tryAutoLogin() { const nonce = result.loginNonce; const hashedToken = sha512(token + nonce); - const loginResult = await sammoAPI(["Login", "LoginByToken"], { + const loginResult = await SammoRootAPI.Login.LoginByToken({ 'hashedToken': hashedToken, 'token_id': tokenID, }, true); @@ -312,7 +312,7 @@ $(async function ($) { let result: LoginResponse | LoginFailed; try { - result = await sammoAPI(["Login", "LoginByID"], { + result = await SammoRootAPI.Login.LoginByID({ username: values.username, password: hash_pw, diff --git a/hwe/ts/util/APIPathGen.ts b/hwe/ts/util/APIPathGen.ts index e0f6b291..7ba5bed7 100644 --- a/hwe/ts/util/APIPathGen.ts +++ b/hwe/ts/util/APIPathGen.ts @@ -1,30 +1,40 @@ -type SubValue = string | { [property: string]: SubValue }; +import { InvalidResponse } from "@/defs"; +import { callSammoAPI, ValidResponse } from "./callSammoAPI"; -const hasKey = >(obj: T, k: string | symbol | number): k is keyof T => - k in obj; +export type CurryCall = + ((args?: Record) => Promise) + | ((args: Record | undefined, returnError: false) => Promise) + | ((args: Record | undefined, returnError: true) => Promise); -export function APIPathGen(obj: Record, path?: string[]): Record { +type SubValue = CurryCall | { [property: string]: SubValue }; + +export function APIPathGen },>(obj: T, path?: string[]): T { return new Proxy(obj, { - get(target, key: K) { + get(target, key: string) { + let nextPath: string[]; if (path === undefined) { - path = [key]; + nextPath = [key]; } - else { - path.push(key); + else{ + nextPath = path; + nextPath.push(key); } - - if (hasKey(target, key)) { - const next: V = target[key]; - if (typeof (next) === 'string') { - return path.join('/'); - } - if (typeof (next) === 'object') { - return APIPathGen(next, path); - } - throw 'unknown'; + if (!(key in target)) { + throw `${nextPath.join('/')} is not exists`; } - throw `${path.join('/')} is not exists`; + + const next = target[key]; + if (typeof (next) === 'function') { + const callAPI: CurryCall = (args: Record | undefined, returnError?: boolean) => { + if (returnError) { + return callSammoAPI(nextPath.join('/'), args, returnError); + } + return callSammoAPI(nextPath.join('/'), args, false); + } + return callAPI; + } + return APIPathGen(next, nextPath); } }) } \ No newline at end of file diff --git a/hwe/ts/util/callSammoAPI.ts b/hwe/ts/util/callSammoAPI.ts new file mode 100644 index 00000000..2598daee --- /dev/null +++ b/hwe/ts/util/callSammoAPI.ts @@ -0,0 +1,35 @@ +import axios from "axios"; +import { isArray } from "lodash"; +import { InvalidResponse } from '@/defs'; + +export type ValidResponse = { + result: true +} + +export async function callSammoAPI(path: string | string[], args?: Record): Promise; +export async function callSammoAPI(path: string | string[], args: Record | undefined, returnError: false): Promise; +export async function callSammoAPI(path: string | string[], args: Record | undefined, returnError: true): Promise; + +export async function callSammoAPI(path: string | string[], args?: Record, returnError = false): Promise { + if (isArray(path)) { + path = path.join('/'); + } + + const response = await axios({ + url: "api.php", + method: "post", + responseType: "json", + data: { + path, + args, + }, + }); + const result: ErrorType | ResultType = response.data; + if (!result.result) { + if (returnError) { + return result; + } + throw result.reason; + } + return result; +} \ No newline at end of file diff --git a/hwe/ts/util/sammoAPI.ts b/hwe/ts/util/sammoAPI.ts deleted file mode 100644 index e92db5f9..00000000 --- a/hwe/ts/util/sammoAPI.ts +++ /dev/null @@ -1,35 +0,0 @@ -import axios from "axios"; -import { isArray } from "lodash"; -import { InvalidResponse } from '@/defs'; - -export type ValidResponse = { - result: true -} - -export async function sammoAPI(path: string | string[], args?: Record): Promise; -export async function sammoAPI(path: string | string[], args: Record | undefined, returnError: false): Promise; -export async function sammoAPI(path: string | string[], args: Record | undefined, returnError: true): Promise; - -export async function sammoAPI(path: string | string[], args?: Record, returnError = false): Promise { - if (isArray(path)) { - path = path.join('/'); - } - - const response = await axios({ - url: "api.php", - method: "post", - responseType: "json", - data: { - path, - args, - }, - }); - const result: ErrorType | ResultType = response.data; - if (!result.result) { - if (returnError) { - return result; - } - throw result.reason; - } - return result; -} \ No newline at end of file diff --git a/hwe/ts/v_processing.ts b/hwe/ts/v_processing.ts index 9b11e17b..28384d85 100644 --- a/hwe/ts/v_processing.ts +++ b/hwe/ts/v_processing.ts @@ -9,12 +9,12 @@ import { App, createApp } from 'vue'; import { auto500px } from './util/auto500px'; import { isString } from 'lodash'; import { Args, testSubmitArgs } from './processing/args'; -import { sammoAPI, ValidResponse } from './util/sammoAPI'; +import { SammoAPI, ValidResponse } from './SammoAPI'; declare const turnList: number[]; async function submitCommand(isChiefTurn: boolean, turnList: number[], action: string, arg: Args): Promise { - const target = isChiefTurn ? 'NationCommand/ReserveCommand' : 'Command/ReserveCommand'; + const targetAPI = isChiefTurn ? SammoAPI.NationCommand.ReserveCommand : SammoAPI.Command.ReserveCommand; try { const testResult = testSubmitArgs(arg); @@ -22,7 +22,7 @@ async function submitCommand(isChiefTurn: boolean, turn throw new TypeError(`Invalied Type ${testResult[0]}, ${testResult[2]} should be ${testResult[1]}`); } console.log('trySubmit', arg); - const response = await sammoAPI(target, { + const response = await targetAPI({ action, turnList, arg, diff --git a/src/makeAPIPath.ts b/src/makeAPIPath.ts new file mode 100644 index 00000000..e69de29b