refac, feat: API 호출 구조 재작성
- api.php에서 param path 강제 - api.php에서 GET param 허용 - SammoAPI 호출자를 axios에서 fetch 기반(ky)로 변경 - SammoAPI에서 단순 POST대신 REST에 따라 지정 가능하도록 재구성 - SammoAPI에서 NumVar, StrVar를 PathParam으로 변경하도록 변경 - API CallType들을 def/API로 분리 시작 - 일부 API를 시험삼아 변경(login)
This commit is contained in:
@@ -8,5 +8,9 @@ require(__DIR__ . '/vendor/autoload.php');
|
||||
if (!class_exists('\\sammo\\RootDB')) {
|
||||
Json::dieWithReason('No DB');
|
||||
}
|
||||
$eParams = $_GET;
|
||||
if(key_exists('path', $eParams)){
|
||||
unset($eParams['path']);
|
||||
}
|
||||
|
||||
APIHelper::launch(dirname(__FILE__), $_GET['path']??null);
|
||||
APIHelper::launch(dirname(__FILE__), $_GET['path']??'', $eParams, true);
|
||||
+6
-1
@@ -5,4 +5,9 @@ namespace sammo;
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
|
||||
APIHelper::launch(dirname(__FILE__), $_GET['path']??null);
|
||||
$eParams = $_GET;
|
||||
if(key_exists('path', $eParams)){
|
||||
unset($eParams['path']);
|
||||
}
|
||||
|
||||
APIHelper::launch(dirname(__FILE__), $_GET['path']??'', $eParams, true);
|
||||
+40
-34
@@ -1,65 +1,71 @@
|
||||
import type { InvalidResponse, ReserveBulkCommandResponse } from "./defs";
|
||||
import type { BettingDetailResponse, ReserveBulkCommandResponse } from "./defs";
|
||||
import type { Args } from "./processing/args";
|
||||
import { callSammoAPI, done, type CallbackT, type RawArgType, type ValidResponse } from "./util/callSammoAPI";
|
||||
import { callSammoAPI, extractHttpMethod, GET, PATCH, POST, PUT, type APITail, type APICallT, type RawArgType, type ValidResponse, type InvalidResponse } from "./util/callSammoAPI";
|
||||
export type { ValidResponse, InvalidResponse };
|
||||
import { APIPathGen } from "./util/APIPathGen.js";
|
||||
import { APIPathGen, NumVar } from "./util/APIPathGen.js";
|
||||
|
||||
const apiRealPath = {
|
||||
Betting: {
|
||||
Bet: done,
|
||||
GetBettingDetail: done,
|
||||
GetBettingList: done,
|
||||
Bet: PUT,
|
||||
GetBettingDetail: NumVar('betting_id',
|
||||
GET as APICallT<undefined, BettingDetailResponse>
|
||||
),
|
||||
GetBettingList: GET,
|
||||
},
|
||||
Command: {
|
||||
GetReservedCommand: done,
|
||||
PushCommand: done,
|
||||
RepeatCommand: done,
|
||||
ReserveCommand: done,
|
||||
ReserveBulkCommand: done as CallbackT<{
|
||||
GetReservedCommand: GET as APICallT<undefined>,
|
||||
PushCommand: PATCH,
|
||||
RepeatCommand: PATCH,
|
||||
ReserveCommand: PUT,
|
||||
ReserveBulkCommand: PUT as APICallT<{
|
||||
turnList: number[],
|
||||
action: string,
|
||||
arg: Args
|
||||
}[], ReserveBulkCommandResponse>,
|
||||
},
|
||||
General: {
|
||||
Join: done,
|
||||
Join: POST,
|
||||
},
|
||||
InheritAction: {
|
||||
BuyHiddenBuff: done,
|
||||
BuyRandomUnique: done,
|
||||
BuySpecificUnique: done,
|
||||
ResetSpecialWar: done,
|
||||
ResetTurnTime: done,
|
||||
SetNextSpecialWar: done,
|
||||
BuyHiddenBuff: PUT,
|
||||
BuyRandomUnique: PUT,
|
||||
BuySpecificUnique: PUT,
|
||||
ResetSpecialWar: PUT,
|
||||
ResetTurnTime: PUT,
|
||||
SetNextSpecialWar: PUT,
|
||||
},
|
||||
Misc: { UploadImage: done },
|
||||
Misc: { UploadImage: POST },
|
||||
NationCommand: {
|
||||
GetReservedCommand: done,
|
||||
PushCommand: done,
|
||||
RepeatCommand: done,
|
||||
ReserveCommand: done,
|
||||
ReserveBulkCommand: done as CallbackT<{
|
||||
GetReservedCommand: GET,
|
||||
PushCommand: PATCH,
|
||||
RepeatCommand: PATCH,
|
||||
ReserveCommand: PUT,
|
||||
ReserveBulkCommand: PUT as APICallT<{
|
||||
turnList: number[],
|
||||
action: string,
|
||||
arg: Args
|
||||
}[], ReserveBulkCommandResponse>,
|
||||
},
|
||||
Nation: {
|
||||
SetNotice: done,
|
||||
SetScoutMsg: done,
|
||||
SetBill: done,
|
||||
SetRate: done,
|
||||
SetSecretLimit: done,
|
||||
SetBlockWar: done,
|
||||
SetBlockScout: done,
|
||||
SetNotice: PUT,
|
||||
SetScoutMsg: PUT,
|
||||
SetBill: PUT,
|
||||
SetRate: PUT,
|
||||
SetSecretLimit: PUT,
|
||||
SetBlockWar: PUT,
|
||||
SetBlockScout: PUT,
|
||||
},
|
||||
Test: NumVar('id', {
|
||||
SetThis: PUT,
|
||||
})
|
||||
} as const;
|
||||
|
||||
export const SammoAPI = APIPathGen(apiRealPath, (path: string[]) => {
|
||||
export const SammoAPI = APIPathGen(apiRealPath, (path: string[], tail: APITail, pathParam) => {
|
||||
const method = extractHttpMethod(tail);
|
||||
return (args?: RawArgType, returnError?: boolean) => {
|
||||
if (returnError) {
|
||||
return callSammoAPI(path.join('/'), args, true);
|
||||
return callSammoAPI(method, path.join('/'), args, pathParam, true);
|
||||
}
|
||||
return callSammoAPI(path.join('/'), args);
|
||||
return callSammoAPI(method, path.join('/'), args, pathParam);
|
||||
};
|
||||
});
|
||||
+14
-10
@@ -1,21 +1,25 @@
|
||||
import type { InvalidResponse } from "./defs";
|
||||
import type { AutoLoginFailed, AutoLoginNonceResponse, AutoLoginResponse } from "./defs/API/Login";
|
||||
import { APIPathGen } from "./util/APIPathGen";
|
||||
import { callSammoAPI, done, type ValidResponse } from "./util/callSammoAPI";
|
||||
import { callSammoAPI, extractHttpMethod, GET, POST, type APICallT, type APITail, type InvalidResponse, type RawArgType, type ValidResponse } from "./util/callSammoAPI";
|
||||
export type { ValidResponse, InvalidResponse };
|
||||
|
||||
const apiRealPath = {
|
||||
Login: {
|
||||
LoginByID: done,
|
||||
LoginByToken: done,
|
||||
ReqNonce: done,
|
||||
LoginByID: POST,
|
||||
LoginByToken: POST as APICallT<{
|
||||
hashedToken: string,
|
||||
token_id: number,
|
||||
}, AutoLoginResponse, AutoLoginFailed>,
|
||||
ReqNonce: GET as APICallT<undefined, AutoLoginNonceResponse, AutoLoginFailed>
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const SammoRootAPI = APIPathGen(apiRealPath, (path: string[]) => {
|
||||
return (args?: Record<string, unknown>, returnError?: boolean) => {
|
||||
export const SammoRootAPI = APIPathGen(apiRealPath, (path: string[], tail: APITail, pathParam) => {
|
||||
const method = extractHttpMethod(tail);
|
||||
return (args?: RawArgType, returnError?: boolean) => {
|
||||
if (returnError) {
|
||||
return callSammoAPI(path.join('/'), args, true);
|
||||
return callSammoAPI(method, path.join('/'), args, pathParam, true);
|
||||
}
|
||||
return callSammoAPI(path.join('/'), args);
|
||||
return callSammoAPI(method, path.join('/'), args, pathParam);
|
||||
};
|
||||
}) as typeof apiRealPath;
|
||||
});
|
||||
@@ -129,21 +129,13 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { BettingInfo, ToastType } from "@/defs";
|
||||
import { SammoAPI, type ValidResponse } from "@/SammoAPI";
|
||||
import type { BettingDetailResponse, BettingInfo, ToastType } from "@/defs";
|
||||
import { SammoAPI } from "@/SammoAPI";
|
||||
import { joinYearMonth } from "@/util/joinYearMonth";
|
||||
import { parseYearMonth } from "@/util/parseYearMonth";
|
||||
import { isString, range, sum } from "lodash";
|
||||
import { ref, type PropType, watch } from "vue";
|
||||
|
||||
type BettingDetailResponse = ValidResponse & {
|
||||
bettingInfo: BettingInfo;
|
||||
bettingDetail: [string, number][];
|
||||
myBetting: [string, number][];
|
||||
remainPoint: number;
|
||||
year: number;
|
||||
month: number;
|
||||
};
|
||||
|
||||
const props = defineProps({
|
||||
bettingID: {
|
||||
@@ -287,9 +279,7 @@ function calcReward() {
|
||||
|
||||
async function loadBetting(bettingID: number) {
|
||||
try {
|
||||
const result = await SammoAPI.Betting.GetBettingDetail<BettingDetailResponse>({
|
||||
betting_id: bettingID,
|
||||
});
|
||||
const result = await SammoAPI.Betting.GetBettingDetail[bettingID]();
|
||||
year.value = result.year;
|
||||
month.value = result.month;
|
||||
yearMonth.value = joinYearMonth(result.year, result.month);
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
|
||||
|
||||
export type LoginResponse = {
|
||||
result: true,
|
||||
nextToken: [number, string] | undefined,
|
||||
}
|
||||
|
||||
export type LoginFailed = {
|
||||
result: false,
|
||||
reqOTP: boolean,
|
||||
reason: string,
|
||||
}
|
||||
|
||||
export type LoginResponseWithKakao = LoginResponse | LoginFailed;
|
||||
|
||||
export type OTPResponse = {
|
||||
result: true,
|
||||
validUntil: string,
|
||||
} | {
|
||||
result: false,
|
||||
reset: boolean,
|
||||
reason: string,
|
||||
}
|
||||
|
||||
|
||||
export type AutoLoginNonceResponse = {
|
||||
result: true,
|
||||
loginNonce: string,
|
||||
};
|
||||
|
||||
export type AutoLoginResponse = {
|
||||
result: true,
|
||||
nextToken: [number, string] | undefined,
|
||||
}
|
||||
|
||||
export type AutoLoginFailed = {
|
||||
result: false,
|
||||
silent: boolean,
|
||||
reason: string,
|
||||
}
|
||||
@@ -1,10 +1,7 @@
|
||||
import type { Args } from "./processing/args";
|
||||
|
||||
export type InvalidResponse = {
|
||||
result: false;
|
||||
reason: string;
|
||||
}
|
||||
import type { Args } from "@/processing/args";
|
||||
import type { ValidResponse, InvalidResponse } from "@/util/callSammoAPI";
|
||||
|
||||
export type { ValidResponse, InvalidResponse };
|
||||
export type BasicGeneralListResponse = {
|
||||
result: true,
|
||||
nationID: number,
|
||||
@@ -201,7 +198,7 @@ export type CommandItem = {
|
||||
possible: boolean;
|
||||
reqArg: boolean;
|
||||
searchText?: string;
|
||||
};
|
||||
};
|
||||
|
||||
export type ChiefResponse = {
|
||||
result: true;
|
||||
@@ -266,3 +263,13 @@ export type BettingInfo = {
|
||||
candidates: SelectItem[];
|
||||
winner?: number[];
|
||||
}
|
||||
|
||||
|
||||
export type BettingDetailResponse = ValidResponse & {
|
||||
bettingInfo: BettingInfo;
|
||||
bettingDetail: [string, number][];
|
||||
myBetting: [string, number][];
|
||||
remainPoint: number;
|
||||
year: number;
|
||||
month: number;
|
||||
};
|
||||
+4
-43
@@ -8,51 +8,12 @@ import { setAxiosXMLHttpRequest } from '@util/setAxiosXMLHttpRequest';
|
||||
import { unwrap_any } from '@util/unwrap_any';
|
||||
import { sha512 } from 'js-sha512';
|
||||
import { unwrap } from '@util/unwrap';
|
||||
import type { InvalidResponse } from '@/defs';
|
||||
import { delay } from '@util/delay';
|
||||
import { Modal } from 'bootstrap';
|
||||
import '@/gateway/common';
|
||||
import { isString } from 'lodash';
|
||||
import { SammoRootAPI } from '@/SammoRootAPI';
|
||||
|
||||
type LoginResponse = {
|
||||
result: true,
|
||||
nextToken: [number, string] | undefined,
|
||||
}
|
||||
|
||||
type LoginFailed = {
|
||||
result: false,
|
||||
reqOTP: boolean,
|
||||
reason: string,
|
||||
}
|
||||
|
||||
type LoginResponseWithKakao = LoginResponse | LoginFailed;
|
||||
|
||||
type OTPResponse = {
|
||||
result: true,
|
||||
validUntil: string,
|
||||
} | {
|
||||
result: false,
|
||||
reset: boolean,
|
||||
reason: string,
|
||||
}
|
||||
|
||||
|
||||
type AutoLoginNonceResponse = {
|
||||
result: true,
|
||||
loginNonce: string,
|
||||
};
|
||||
|
||||
type AutoLoginResponse = {
|
||||
result: true,
|
||||
nextToken: [number, string] | undefined,
|
||||
}
|
||||
|
||||
type AutoLoginFailed = {
|
||||
result: false,
|
||||
silent: boolean,
|
||||
reason: string,
|
||||
}
|
||||
import { SammoRootAPI, type InvalidResponse } from '@/SammoRootAPI';
|
||||
import type { LoginFailed, LoginResponse, LoginResponseWithKakao, OTPResponse } from '@/defs/API/Login';
|
||||
declare global {
|
||||
interface Window {
|
||||
getOAuthToken: (mode: string, scope_list: string[]) => void;
|
||||
@@ -101,7 +62,7 @@ async function tryAutoLogin() {
|
||||
|
||||
const [tokenID, token] = tokenInfo;
|
||||
|
||||
const result = await SammoRootAPI.Login.ReqNonce<AutoLoginNonceResponse, AutoLoginFailed>({}, true);
|
||||
const result = await SammoRootAPI.Login.ReqNonce(undefined, true);
|
||||
|
||||
if (!result) {
|
||||
//api 에러.
|
||||
@@ -116,7 +77,7 @@ async function tryAutoLogin() {
|
||||
const nonce = result.loginNonce;
|
||||
|
||||
const hashedToken = sha512(token + nonce);
|
||||
const loginResult = await SammoRootAPI.Login.LoginByToken<AutoLoginResponse, AutoLoginFailed>({
|
||||
const loginResult = await SammoRootAPI.Login.LoginByToken({
|
||||
'hashedToken': hashedToken,
|
||||
'token_id': tokenID,
|
||||
}, true);
|
||||
|
||||
Vendored
+9
-5
@@ -1,21 +1,25 @@
|
||||
export function APIPathGen<T>(obj: T, callback: (path: string[])=>unknown): T;
|
||||
export function APIPathGen<T, V>(
|
||||
obj: T,
|
||||
callback: (path: string[], tail: V, pathParam?: Record<string, string | number>) => unknown,
|
||||
pathParam?: Record<string, string | number>
|
||||
): T;
|
||||
|
||||
export function StrVar<PathType extends string>(): <NextCall>(next: NextCall)=>{
|
||||
export function StrVar<PathType extends string>(paramKey: string): <NextCall>(next: NextCall) => {
|
||||
[v in PathType]: NextCall
|
||||
};
|
||||
|
||||
export function NumVar<NextCall>(next: NextCall):{
|
||||
export function NumVar<NextCall>(paramKey: string, next: NextCall): {
|
||||
[v: number]: NextCall
|
||||
};
|
||||
|
||||
/*
|
||||
const apiPath = {
|
||||
SomePath: someFunc,
|
||||
User: StrVar<'a'|'b'>()({
|
||||
User: StrVar<'a'|'b'>('name')({
|
||||
Update: someFunc,
|
||||
Delete: someFunc,
|
||||
}),
|
||||
NationInfo: NumVar({
|
||||
NationInfo: NumVar('id', {
|
||||
show: someFunc
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export function APIPathGen(obj, callback, path) {
|
||||
export function APIPathGen(obj, callback, path, pathParams) {
|
||||
return new Proxy(obj, {
|
||||
get(target, key) {
|
||||
let nextPath;
|
||||
@@ -9,12 +9,21 @@ export function APIPathGen(obj, callback, path) {
|
||||
nextPath = [...path, key.toString()];
|
||||
}
|
||||
|
||||
if (pathParams !== undefined) {
|
||||
pathParams = { ...pathParams };
|
||||
}
|
||||
|
||||
const varType = target.__nextVarType;
|
||||
const varKey = target.__nextVarKey;
|
||||
let next;
|
||||
if (varType !== undefined) {
|
||||
if (varType !== undefined && varKey !== undefined) {
|
||||
if (typeof key !== varType) {
|
||||
throw `${key} is not ${varType}`;
|
||||
}
|
||||
if(pathParams === undefined){
|
||||
pathParams = {}
|
||||
}
|
||||
pathParams[varKey] = key;
|
||||
next = target.next;
|
||||
}
|
||||
else if (key in target) {
|
||||
@@ -25,26 +34,28 @@ export function APIPathGen(obj, callback, path) {
|
||||
}
|
||||
|
||||
if (typeof (next) === 'function') {
|
||||
return callback(nextPath);
|
||||
return callback(nextPath, next, pathParams);
|
||||
}
|
||||
return APIPathGen(next, callback, nextPath);
|
||||
return APIPathGen(next, callback, nextPath, pathParams);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//generic 인자로 '자동'을 주려면 생략해야하므로 2단 호출
|
||||
export function StrVar() {
|
||||
export function StrVar(key) {
|
||||
return (next) => {
|
||||
return {
|
||||
__nextVarType: 'string',
|
||||
__nextVarKey: key,
|
||||
next
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function NumVar(next) {
|
||||
export function NumVar(key, next) {
|
||||
return {
|
||||
__nextVarType: 'number',
|
||||
__nextVarKey: key,
|
||||
next
|
||||
}
|
||||
}
|
||||
+90
-22
@@ -1,35 +1,64 @@
|
||||
import axios from "axios";
|
||||
import { isArray } from "lodash";
|
||||
import type { InvalidResponse } from '@/defs';
|
||||
import ky from 'ky';
|
||||
import { isArray, isEmpty } from "lodash";
|
||||
|
||||
export type ValidResponse = {
|
||||
result: true
|
||||
}
|
||||
|
||||
export type RawArgType = Record<string, unknown>|Record<string, unknown>[];
|
||||
export type InvalidResponse = {
|
||||
result: false;
|
||||
reason: string;
|
||||
}
|
||||
|
||||
export interface CallbackT<ArgType extends RawArgType, ResultType extends ValidResponse = ValidResponse, ErrorType extends InvalidResponse = InvalidResponse>{
|
||||
|
||||
export type RawArgType = Record<string, unknown> | Record<string, unknown>[] | undefined;
|
||||
|
||||
export interface APICallT<ArgType extends RawArgType, ResultType extends ValidResponse = ValidResponse, ErrorType extends InvalidResponse = InvalidResponse> {
|
||||
(args?: ArgType): Promise<ResultType>;
|
||||
(args: ArgType | undefined, returnError: false): Promise<ResultType>;
|
||||
(args: ArgType | undefined, returnError: true): Promise<ResultType | ErrorType>;
|
||||
}
|
||||
|
||||
export async function callSammoAPI<ResultType extends ValidResponse>(path: string | string[], args?: Record<string, unknown> | Record<string, unknown>[]): Promise<ResultType>;
|
||||
export async function callSammoAPI<ResultType extends ValidResponse>(path: string | string[], args: Record<string, unknown> | Record<string, unknown>[] | undefined, returnError: false): Promise<ResultType>;
|
||||
export async function callSammoAPI<ResultType extends ValidResponse, ErrorType extends InvalidResponse>(path: string | string[], args: Record<string, unknown> | Record<string, unknown>[] | undefined, returnError: true): Promise<ResultType | ErrorType>;
|
||||
type HttpMethod = 'get' | 'post' | 'put' | 'patch' | 'head' | 'delete';
|
||||
export type APITail = typeof GET | typeof POST | typeof PUT | typeof PATCH | typeof HEAD | typeof DELETE;
|
||||
|
||||
export async function callSammoAPI<ResultType extends ValidResponse, ErrorType extends InvalidResponse>(path: string | string[], args?: Record<string, unknown> | Record<string, unknown>[], returnError = false): Promise<ResultType | ErrorType> {
|
||||
const httpMethodMap = new Map<APITail, HttpMethod>([
|
||||
[GET, 'get'],
|
||||
[POST, 'post'],
|
||||
[PUT, 'put'],
|
||||
[PATCH, 'patch'],
|
||||
[HEAD, 'head'],
|
||||
[DELETE, 'delete'],
|
||||
]);
|
||||
|
||||
export function extractHttpMethod(tail: APITail): HttpMethod {
|
||||
return httpMethodMap.get(tail) ?? 'post';
|
||||
}
|
||||
|
||||
export async function callSammoAPI<ResultType extends ValidResponse>(method: HttpMethod, path: string | string[], args: RawArgType, paramArgs: Record<string, string | number> | undefined): Promise<ResultType>;
|
||||
export async function callSammoAPI<ResultType extends ValidResponse>(method: HttpMethod, path: string | string[], args: RawArgType, paramArgs: Record<string, string | number> | undefined, returnError: false): Promise<ResultType>;
|
||||
export async function callSammoAPI<ResultType extends ValidResponse, ErrorType extends InvalidResponse>(method: HttpMethod, path: string | string[], args: RawArgType, paramArgs: Record<string, string | number> | undefined, returnError: true): Promise<ResultType | ErrorType>;
|
||||
export async function callSammoAPI<ResultType extends ValidResponse, ErrorType extends InvalidResponse>(method: HttpMethod, path: string | string[], args: RawArgType, paramArgs: Record<string, string | number> | undefined, returnError = false): Promise<ResultType | ErrorType> {
|
||||
if (isArray(path)) {
|
||||
path = path.join('/');
|
||||
}
|
||||
|
||||
const response = await axios({
|
||||
url: `api.php?path=${path}`,
|
||||
method: "post",
|
||||
responseType: "json",
|
||||
data: args
|
||||
});
|
||||
const result: ErrorType | ResultType = response.data;
|
||||
if (args && isEmpty(args)) {
|
||||
args = undefined;
|
||||
}
|
||||
|
||||
const result = await ky('api.php', {
|
||||
searchParams: {
|
||||
...paramArgs,
|
||||
path,
|
||||
},
|
||||
method,
|
||||
json: args,
|
||||
headers: {
|
||||
'content-type': 'application/json'
|
||||
}
|
||||
}).json() as ErrorType | ResultType;
|
||||
|
||||
if (!result.result) {
|
||||
if (returnError) {
|
||||
return result;
|
||||
@@ -39,11 +68,50 @@ export async function callSammoAPI<ResultType extends ValidResponse, ErrorType e
|
||||
return result;
|
||||
}
|
||||
|
||||
export async function done<ResultType extends ValidResponse>(args?: RawArgType): Promise<ResultType>;
|
||||
export async function done<ResultType extends ValidResponse>(args: RawArgType | undefined, returnError: false): Promise<ResultType>;
|
||||
export async function done<ResultType extends ValidResponse, ErrorType extends InvalidResponse>(args: RawArgType | undefined, returnError: true): Promise<ResultType | ErrorType>;
|
||||
export async function GET<ResultType extends ValidResponse, ArgType extends undefined = undefined>(args?: ArgType): Promise<ResultType>;
|
||||
export async function GET<ResultType extends ValidResponse, ArgType extends undefined = undefined>(args: ArgType | undefined, returnError: false): Promise<ResultType>;
|
||||
export async function GET<ResultType extends ValidResponse, ErrorType extends InvalidResponse, ArgType extends undefined = undefined>(args: ArgType | undefined, returnError: true): Promise<ResultType | ErrorType>;
|
||||
export async function GET<ResultType extends ValidResponse, ErrorType extends InvalidResponse, ArgType extends undefined = undefined>(args?: ArgType, returnError = false): Promise<ResultType | ErrorType> {
|
||||
console.error(`Can't directly call GET. ${args}, ${returnError}. Use auto-generated path API.`);
|
||||
return callSammoAPI<ResultType, ErrorType>('get', [], args, undefined, true);
|
||||
}
|
||||
|
||||
export async function done<ResultType extends ValidResponse, ErrorType extends InvalidResponse>(args?: RawArgType, returnError = false): Promise<ResultType | ErrorType> {
|
||||
console.error(`Can't directly call. ${args}, ${returnError}. Use auto-generated path API.`);
|
||||
return callSammoAPI<ResultType, ErrorType>([], args, true);
|
||||
export async function POST<ResultType extends ValidResponse, ArgType extends RawArgType = RawArgType>(args?: ArgType): Promise<ResultType>;
|
||||
export async function POST<ResultType extends ValidResponse, ArgType extends RawArgType = RawArgType>(args: ArgType | undefined, returnError: false): Promise<ResultType>;
|
||||
export async function POST<ResultType extends ValidResponse, ErrorType extends InvalidResponse, ArgType extends RawArgType = RawArgType>(args: ArgType | undefined, returnError: true): Promise<ResultType | ErrorType>;
|
||||
export async function POST<ResultType extends ValidResponse, ErrorType extends InvalidResponse, ArgType extends RawArgType = RawArgType>(args?: ArgType, returnError = false): Promise<ResultType | ErrorType> {
|
||||
console.error(`Can't directly call POST. ${args}, ${returnError}. Use auto-generated path API.`);
|
||||
return callSammoAPI<ResultType, ErrorType>('post', [], args, undefined, true);
|
||||
}
|
||||
|
||||
export async function PUT<ResultType extends ValidResponse, ArgType extends RawArgType = RawArgType>(args?: ArgType): Promise<ResultType>;
|
||||
export async function PUT<ResultType extends ValidResponse, ArgType extends RawArgType = RawArgType>(args: ArgType | undefined, returnError: false): Promise<ResultType>;
|
||||
export async function PUT<ResultType extends ValidResponse, ErrorType extends InvalidResponse, ArgType extends RawArgType = RawArgType>(args: ArgType | undefined, returnError: true): Promise<ResultType | ErrorType>;
|
||||
export async function PUT<ResultType extends ValidResponse, ErrorType extends InvalidResponse, ArgType extends RawArgType = RawArgType>(args?: ArgType, returnError = false): Promise<ResultType | ErrorType> {
|
||||
console.error(`Can't directly call PUT. ${args}, ${returnError}. Use auto-generated path API.`);
|
||||
return callSammoAPI<ResultType, ErrorType>('put', [], args, undefined, true);
|
||||
}
|
||||
|
||||
export async function PATCH<ResultType extends ValidResponse, ArgType extends RawArgType = RawArgType>(args?: ArgType): Promise<ResultType>;
|
||||
export async function PATCH<ResultType extends ValidResponse, ArgType extends RawArgType = RawArgType>(args: ArgType | undefined, returnError: false): Promise<ResultType>;
|
||||
export async function PATCH<ResultType extends ValidResponse, ErrorType extends InvalidResponse, ArgType extends RawArgType = RawArgType>(args: ArgType | undefined, returnError: true): Promise<ResultType | ErrorType>;
|
||||
export async function PATCH<ResultType extends ValidResponse, ErrorType extends InvalidResponse, ArgType extends RawArgType = RawArgType>(args?: ArgType, returnError = false): Promise<ResultType | ErrorType> {
|
||||
console.error(`Can't directly call PATCH. ${args}, ${returnError}. Use auto-generated path API.`);
|
||||
return callSammoAPI<ResultType, ErrorType>('patch', [], args, undefined, true);
|
||||
}
|
||||
|
||||
export async function HEAD<ResultType extends ValidResponse, ArgType extends undefined = undefined>(args?: ArgType): Promise<ResultType>;
|
||||
export async function HEAD<ResultType extends ValidResponse, ArgType extends undefined = undefined>(args: ArgType | undefined, returnError: false): Promise<ResultType>;
|
||||
export async function HEAD<ResultType extends ValidResponse, ErrorType extends InvalidResponse, ArgType extends undefined = undefined>(args: ArgType | undefined, returnError: true): Promise<ResultType | ErrorType>;
|
||||
export async function HEAD<ResultType extends ValidResponse, ErrorType extends InvalidResponse, ArgType extends undefined = undefined>(args?: ArgType, returnError = false): Promise<ResultType | ErrorType> {
|
||||
console.error(`Can't directly call HEAD. ${args}, ${returnError}. Use auto-generated path API.`);
|
||||
return callSammoAPI<ResultType, ErrorType>('head', [], args, undefined, true);
|
||||
}
|
||||
|
||||
export async function DELETE<ResultType extends ValidResponse, ArgType extends RawArgType = RawArgType>(args?: ArgType): Promise<ResultType>;
|
||||
export async function DELETE<ResultType extends ValidResponse, ArgType extends RawArgType = RawArgType>(args: ArgType | undefined, returnError: false): Promise<ResultType>;
|
||||
export async function DELETE<ResultType extends ValidResponse, ErrorType extends InvalidResponse, ArgType extends RawArgType = RawArgType>(args: ArgType | undefined, returnError: true): Promise<ResultType | ErrorType>;
|
||||
export async function DELETE<ResultType extends ValidResponse, ErrorType extends InvalidResponse, ArgType extends RawArgType = RawArgType>(args?: ArgType, returnError = false): Promise<ResultType | ErrorType> {
|
||||
console.error(`Can't directly call DELETE. ${args}, ${returnError}. Use auto-generated path API.`);
|
||||
return callSammoAPI<ResultType, ErrorType>('patch', [], args, undefined, true);
|
||||
}
|
||||
Generated
+17
@@ -63,6 +63,7 @@
|
||||
"file-loader": "^6.2.0",
|
||||
"jquery": "^3.6.0",
|
||||
"js-sha512": "^0.8.0",
|
||||
"ky": "^0.30.0",
|
||||
"linkifyjs": "^3.0",
|
||||
"lodash": "^4.17.21",
|
||||
"mini-css-extract-plugin": "^2.6.0",
|
||||
@@ -6417,6 +6418,17 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/ky": {
|
||||
"version": "0.30.0",
|
||||
"resolved": "https://registry.npmjs.org/ky/-/ky-0.30.0.tgz",
|
||||
"integrity": "sha512-X/u76z4JtDVq10u1JA5UQfatPxgPaVDMYTrgHyiTpGN2z4TMEJkIHsoSBBSg9SWZEIXTKsi9kHgiQ9o3Y/4yog==",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sindresorhus/ky?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/levn": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
|
||||
@@ -15122,6 +15134,11 @@
|
||||
"resolved": "https://registry.npmjs.org/klona/-/klona-2.0.5.tgz",
|
||||
"integrity": "sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ=="
|
||||
},
|
||||
"ky": {
|
||||
"version": "0.30.0",
|
||||
"resolved": "https://registry.npmjs.org/ky/-/ky-0.30.0.tgz",
|
||||
"integrity": "sha512-X/u76z4JtDVq10u1JA5UQfatPxgPaVDMYTrgHyiTpGN2z4TMEJkIHsoSBBSg9SWZEIXTKsi9kHgiQ9o3Y/4yog=="
|
||||
},
|
||||
"levn": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
|
||||
|
||||
@@ -76,6 +76,7 @@
|
||||
"file-loader": "^6.2.0",
|
||||
"jquery": "^3.6.0",
|
||||
"js-sha512": "^0.8.0",
|
||||
"ky": "^0.30.0",
|
||||
"linkifyjs": "^3.0",
|
||||
"lodash": "^4.17.21",
|
||||
"mini-css-extract-plugin": "^2.6.0",
|
||||
|
||||
+22
-30
@@ -21,41 +21,33 @@ class APIHelper
|
||||
die();
|
||||
}
|
||||
|
||||
public static function launch(string $rootPath, ?string $actionPath = null)
|
||||
public static function launch(string $rootPath, string $actionPath, array $eParams = [], bool $loadRawInput = true)
|
||||
{
|
||||
//TODO: path를 php://input에서 받는게 아니라 api.php?~~~~~ 로 받아오는것이 etag 캐시 측면에서 훨씬 나을 듯!
|
||||
try {
|
||||
$rawInput = file_get_contents('php://input');
|
||||
$input = Json::decode($rawInput);
|
||||
} catch (\Exception $e) {
|
||||
Json::dieWithReason($e->getMessage());
|
||||
if($loadRawInput){
|
||||
try {
|
||||
$rawInput = file_get_contents('php://input');
|
||||
$input = Json::decode($rawInput);
|
||||
} catch (\Exception $e) {
|
||||
Json::dieWithReason($e->getMessage());
|
||||
$input = null;
|
||||
}
|
||||
}
|
||||
else{
|
||||
$input = null;
|
||||
}
|
||||
|
||||
if ($actionPath !== null) {
|
||||
if ($input && !is_array($input)) {
|
||||
Json::dieWithReason('args가 array가 아닙니다.' . gettype($input));
|
||||
}
|
||||
if (!$input) {
|
||||
$input = [];
|
||||
}
|
||||
$actionArgs = $input;
|
||||
} else {
|
||||
if (!$input) {
|
||||
Json::dieWithReason("input이 비어있습니다. {$rawInput}");
|
||||
}
|
||||
|
||||
if (!key_exists('path', $input)) {
|
||||
Json::dieWithReason('path가 지정되지 않았습니다.');
|
||||
}
|
||||
$actionPath = $input['path'];
|
||||
|
||||
if (key_exists('args', $input) && !is_array($input['args'])) {
|
||||
Json::dieWithReason('args가 array가 아닙니다.' . gettype($input['args']));
|
||||
}
|
||||
$actionArgs = $input['args'] ?? null;
|
||||
if(!$actionPath){
|
||||
Json::dieWithReason('path가 지정되지 않았습니다.');
|
||||
}
|
||||
if ($input && !is_array($input)) {
|
||||
Json::dieWithReason('args가 array가 아닙니다.' . gettype($input));
|
||||
}
|
||||
if (!$input) {
|
||||
$input = [];
|
||||
}
|
||||
|
||||
|
||||
//NOTE: array_merge([], {})의 상황이 가능함.
|
||||
$actionArgs = array_merge($input, $eParams);
|
||||
|
||||
try {
|
||||
$obj = buildAPIExecutorClass($actionPath, $rootPath, $actionArgs);
|
||||
|
||||
Reference in New Issue
Block a user