From da2c1648c6fef046af410ef6619261264d090370 Mon Sep 17 00:00:00 2001 From: ihsangan Date: Tue, 14 Oct 2025 15:12:39 +0800 Subject: [PATCH 01/31] parse request with post method --- src/helpers.ts | 2 +- src/routing.ts | 6 ++---- src/utils.ts | 31 +++++++++++++++++++++++++++++++ wrangler.toml | 2 +- 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/helpers.ts b/src/helpers.ts index 94308d7..b2cf1ea 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -23,7 +23,7 @@ export default async function serveResult(request: Request): Promise { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': allowedMethod.join(', '), 'Access-Control-Expose-Headers': '*', - 'Cache-Control': 'public, max-age=30, s-maxage=43200, proxy-revalidate, immutable', + 'Cache-Control': 'public, max-age=30, s-maxage=30, proxy-revalidate, immutable', 'Content-Type': 'application/json; charset=utf-8', 'X-Powered-By': '@ihsangan/valid' } diff --git a/src/routing.ts b/src/routing.ts index 551857b..e581c71 100644 --- a/src/routing.ts +++ b/src/routing.ts @@ -1,12 +1,10 @@ -import { getUrl, Result } from './utils' +import { getUrl, parseRequest, Result } from './utils' import * as router from './router' export default async function callAPI(request: Request): Promise { const url = getUrl(request) const path = url.pathname - const params = url.searchParams - const id = params.get('id') - const server = params.get('zone') || params.get('server') + const { id, server } = await parseRequest(request) if (!id) { return { success: false, diff --git a/src/utils.ts b/src/utils.ts index 0e4823d..759e4f4 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -8,6 +8,37 @@ export function timeNow(): number { return Date.now() } +export async function parseRequest(request: Request): Promise<{ id: string | null; server: string | null }> { + if (request.method === 'POST') { + const contentType = request.headers.get('content-type') + let data: { [key: string]: string | null } = {} + try { + if (contentType && contentType.includes('application/json')) { + data = await request.json() + } else if (contentType && contentType.includes('application/x-www-form-urlencoded')) { + const formData = await request.formData() + for (const [key, value] of formData.entries()) { + data[key] = value + } + } else { + return { id: null, server: null } + } + return { + id: data.id || null, + server: data.zone || data.server || null, + } + } catch (error) { + return { id: null, server: null } + } + } + const url = getUrl(request) + const params = url.searchParams + return { + id: params.get('id') || null, + server: params.get('zone') || params.get('server') || null, + } +} + export async function hitCoda(body: string): Promise { const response = await fetch('https://order-sg.codashop.com/initPayment.action', { method: 'POST', diff --git a/wrangler.toml b/wrangler.toml index 36040e2..eb04b7c 100644 --- a/wrangler.toml +++ b/wrangler.toml @@ -1,4 +1,4 @@ -name = "validator" +name = "validev" main = "./src/index.ts" workers_dev = true compatibility_date = "2025-01-01" From 1942f84351e16155a3f0ce485994bff9d70d761b Mon Sep 17 00:00:00 2001 From: ihsangan Date: Tue, 14 Oct 2025 15:22:11 +0800 Subject: [PATCH 02/31] lol i forget to allow post method --- src/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.ts b/src/utils.ts index 759e4f4..e185cb6 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,4 +1,4 @@ -export const allowedMethod = ['GET', 'HEAD'] +export const allowedMethod = ['GET', 'HEAD', 'POST'] export function getUrl(request: Request): URL { return new URL(request.url) From 34c7585ae4ca641dddd5c49f7d936fe1e8c2e4bc Mon Sep 17 00:00:00 2001 From: ihsangan Date: Tue, 14 Oct 2025 16:05:11 +0800 Subject: [PATCH 03/31] try ignoreMethod --- src/handler.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/handler.ts b/src/handler.ts index 9dc1bb3..65c8f61 100644 --- a/src/handler.ts +++ b/src/handler.ts @@ -19,7 +19,8 @@ export default async function checkCache(request: Request): Promise { }) } let cache = caches.default - let response = await cache.match(request.url) + let response = await cache.match(request.url, { + ignoreMethod: false }) if (!response) { response = await serveResult(request) await cache.put(request.url, response.clone()) From 8504281fa40c10cf35dd18f223a100cdb3ba0472 Mon Sep 17 00:00:00 2001 From: ihsangan Date: Tue, 14 Oct 2025 16:31:52 +0800 Subject: [PATCH 04/31] request Object as cache key --- src/handler.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/handler.ts b/src/handler.ts index 65c8f61..adf60d9 100644 --- a/src/handler.ts +++ b/src/handler.ts @@ -19,11 +19,10 @@ export default async function checkCache(request: Request): Promise { }) } let cache = caches.default - let response = await cache.match(request.url, { - ignoreMethod: false }) + let response = await cache.match(request) if (!response) { response = await serveResult(request) - await cache.put(request.url, response.clone()) + await cache.put(request, response.clone()) } response = new Response(response.body, response) response.headers.set('X-Response-Time', timeNow() - now) From 9419d8a5fd191a63130449f3eda69823255abad6 Mon Sep 17 00:00:00 2001 From: ihsangan Date: Wed, 15 Oct 2025 11:01:47 +0800 Subject: [PATCH 05/31] try set Response.json --- src/handler.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/handler.ts b/src/handler.ts index adf60d9..6a61d1c 100644 --- a/src/handler.ts +++ b/src/handler.ts @@ -4,16 +4,15 @@ import serveResult from './helpers' export default async function checkCache(request: Request): Promise { const now = timeNow() if (allowedMethod.indexOf(request.method) === -1) { - return new Response(JSON.stringify({ + return new Response.json({ success: false, message: 'Method not allowed' - }), { + }, { status: 405, headers: { 'Allow': allowedMethod.join(', '), 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': allowedMethod.join(', '), - 'Content-Type': 'application/json; charset=utf-8', 'X-Powered-By': '@ihsangan/valid' } }) From 483cc7a8b908118a57f83aa034b69dbef3419188 Mon Sep 17 00:00:00 2001 From: ihsangan Date: Wed, 15 Oct 2025 11:18:01 +0800 Subject: [PATCH 06/31] Response.json is not a constructor --- src/handler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/handler.ts b/src/handler.ts index 6a61d1c..c51a3a7 100644 --- a/src/handler.ts +++ b/src/handler.ts @@ -4,7 +4,7 @@ import serveResult from './helpers' export default async function checkCache(request: Request): Promise { const now = timeNow() if (allowedMethod.indexOf(request.method) === -1) { - return new Response.json({ + return Response.json({ success: false, message: 'Method not allowed' }, { From 70a1dbfbb0f5e6f5403efcca28deb0536844e2eb Mon Sep 17 00:00:00 2001 From: ihsangan Date: Wed, 15 Oct 2025 11:28:13 +0800 Subject: [PATCH 07/31] response time --- src/handler.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/handler.ts b/src/handler.ts index c51a3a7..663602d 100644 --- a/src/handler.ts +++ b/src/handler.ts @@ -13,7 +13,8 @@ export default async function checkCache(request: Request): Promise { 'Allow': allowedMethod.join(', '), 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': allowedMethod.join(', '), - 'X-Powered-By': '@ihsangan/valid' + 'X-Powered-By': '@ihsangan/valid', + 'X-Response-Time': timeNow() - now } }) } From 4a02194899f7b2dc31a98b52670be4c802f81290 Mon Sep 17 00:00:00 2001 From: ihsangan Date: Wed, 15 Oct 2025 17:29:49 +0800 Subject: [PATCH 08/31] many changes, can't describe --- src/handler.ts | 9 +++++---- src/helpers.ts | 6 +++--- src/routing.ts | 12 +++++++----- src/utils.ts | 20 ++++++++------------ 4 files changed, 23 insertions(+), 24 deletions(-) diff --git a/src/handler.ts b/src/handler.ts index 663602d..3009432 100644 --- a/src/handler.ts +++ b/src/handler.ts @@ -1,4 +1,4 @@ -import { allowedMethod, timeNow } from './utils' +import { allowedMethod, parseRequest, timeNow } from './utils' import serveResult from './helpers' export default async function checkCache(request: Request): Promise { @@ -18,11 +18,12 @@ export default async function checkCache(request: Request): Promise { } }) } + let url = await parseRequest(request) let cache = caches.default - let response = await cache.match(request) + let response = await cache.match(url) if (!response) { - response = await serveResult(request) - await cache.put(request, response.clone()) + response = await serveResult(url) + await cache.put(url, response.clone()) } response = new Response(response.body, response) response.headers.set('X-Response-Time', timeNow() - now) diff --git a/src/helpers.ts b/src/helpers.ts index b2cf1ea..1901632 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -1,10 +1,10 @@ import { getUrl, Result, allowedMethod } from './utils' import callAPI from './routing' -export default async function serveResult(request: Request): Promise { - const dc = getUrl(request).searchParams.get('decode') +export default async function serveResult(url: string): Promise { + const dc = getUrl(url).searchParams.get('decode') let code = 200 - let result: Result = await callAPI(request); + let result: Result = await callAPI(url) if (result.name) { result.name = result.name.replace(/\u002B/g, '%20') if (dc === null || dc === 'true' || dc !== 'false') { diff --git a/src/routing.ts b/src/routing.ts index e581c71..3f3d514 100644 --- a/src/routing.ts +++ b/src/routing.ts @@ -1,10 +1,12 @@ -import { getUrl, parseRequest, Result } from './utils' +import { getUrl, Result } from './utils' import * as router from './router' -export default async function callAPI(request: Request): Promise { - const url = getUrl(request) - const path = url.pathname - const { id, server } = await parseRequest(request) +export default async function callAPI(url: string): Promise { + const requestUrl = getUrl(url) + const path = requestUrl.pathname + const params = requestUrl.searchParams + const id = params.get('id') + const server = params.get('server') || params.get('zone') if (!id) { return { success: false, diff --git a/src/utils.ts b/src/utils.ts index e185cb6..8b5e712 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -8,7 +8,8 @@ export function timeNow(): number { return Date.now() } -export async function parseRequest(request: Request): Promise<{ id: string | null; server: string | null }> { +export async function parseRequest(request: Request): Promise { + let url = getUrl(request) if (request.method === 'POST') { const contentType = request.headers.get('content-type') let data: { [key: string]: string | null } = {} @@ -21,22 +22,17 @@ export async function parseRequest(request: Request): Promise<{ id: string | nul data[key] = value } } else { - return { id: null, server: null } + return url.toString() } - return { - id: data.id || null, - server: data.zone || data.server || null, + for (const key in data) { + url.searchParams.set(key, data[key]) } + return url.toString() } catch (error) { - return { id: null, server: null } + return url.toString() } } - const url = getUrl(request) - const params = url.searchParams - return { - id: params.get('id') || null, - server: params.get('zone') || params.get('server') || null, - } + return url.toString() } export async function hitCoda(body: string): Promise { From 3bfb3e605bd5e44364aef751f35e0606f6949ac6 Mon Sep 17 00:00:00 2001 From: ihsangan Date: Wed, 15 Oct 2025 17:42:55 +0800 Subject: [PATCH 09/31] hehe --- src/utils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index 8b5e712..b1d7894 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,7 +1,7 @@ export const allowedMethod = ['GET', 'HEAD', 'POST'] -export function getUrl(request: Request): URL { - return new URL(request.url) +export function getUrl(request: Request | string): URL { + return new URL(request.url || request) } export function timeNow(): number { From 4a43f61b67b75c44e22d9c01ed50ca01da7dd121 Mon Sep 17 00:00:00 2001 From: ihsangan Date: Wed, 15 Oct 2025 18:15:11 +0800 Subject: [PATCH 10/31] rename status code --- src/helpers.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/helpers.ts b/src/helpers.ts index 1901632..89745cf 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -3,7 +3,7 @@ import callAPI from './routing' export default async function serveResult(url: string): Promise { const dc = getUrl(url).searchParams.get('decode') - let code = 200 + let status = 200 let result: Result = await callAPI(url) if (result.name) { result.name = result.name.replace(/\u002B/g, '%20') @@ -12,13 +12,13 @@ export default async function serveResult(url: string): Promise { } } if (result.message === 'Bad request') { - code = 400 + status = 400 } if (result.message === 'Not found') { - code = 404 + status = 404 } const response = new Response(JSON.stringify(result), { - status: code, + status, headers: { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': allowedMethod.join(', '), From 0ebb17f119a625c0d538958391ed1649cccd8779 Mon Sep 17 00:00:00 2001 From: ihsangan Date: Wed, 15 Oct 2025 18:15:11 +0800 Subject: [PATCH 11/31] rename status code From 4a63ae2d5fd4fc7dfeab31526862da3cc792e001 Mon Sep 17 00:00:00 2001 From: ihsangan Date: Wed, 15 Oct 2025 18:48:43 +0800 Subject: [PATCH 12/31] give return Response.json() --- src/handler.ts | 1 - src/helpers.ts | 4 +--- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/handler.ts b/src/handler.ts index 3009432..85f73bb 100644 --- a/src/handler.ts +++ b/src/handler.ts @@ -25,7 +25,6 @@ export default async function checkCache(request: Request): Promise { response = await serveResult(url) await cache.put(url, response.clone()) } - response = new Response(response.body, response) response.headers.set('X-Response-Time', timeNow() - now) return response } \ No newline at end of file diff --git a/src/helpers.ts b/src/helpers.ts index 89745cf..1bf7721 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -17,16 +17,14 @@ export default async function serveResult(url: string): Promise { if (result.message === 'Not found') { status = 404 } - const response = new Response(JSON.stringify(result), { + return Response.json(result, { status, headers: { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': allowedMethod.join(', '), 'Access-Control-Expose-Headers': '*', 'Cache-Control': 'public, max-age=30, s-maxage=30, proxy-revalidate, immutable', - 'Content-Type': 'application/json; charset=utf-8', 'X-Powered-By': '@ihsangan/valid' } }) - return response } \ No newline at end of file From 4ff6dd7ad8c95f88efa8ec37a285549d420aa464 Mon Sep 17 00:00:00 2001 From: ihsangan Date: Wed, 15 Oct 2025 19:23:23 +0800 Subject: [PATCH 13/31] edit cache headers --- src/helpers.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/helpers.ts b/src/helpers.ts index 1bf7721..a36ecc1 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -23,7 +23,7 @@ export default async function serveResult(url: string): Promise { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': allowedMethod.join(', '), 'Access-Control-Expose-Headers': '*', - 'Cache-Control': 'public, max-age=30, s-maxage=30, proxy-revalidate, immutable', + 'Cache-Control': 'public, max-age=30, s-maxage=30', 'X-Powered-By': '@ihsangan/valid' } }) From 5cdd7e32e9ee9a9105301894320f4d81d6d81bf4 Mon Sep 17 00:00:00 2001 From: ihsangan Date: Wed, 15 Oct 2025 19:55:51 +0800 Subject: [PATCH 14/31] ... --- src/handler.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/handler.ts b/src/handler.ts index 85f73bb..7c1bdcb 100644 --- a/src/handler.ts +++ b/src/handler.ts @@ -25,6 +25,7 @@ export default async function checkCache(request: Request): Promise { response = await serveResult(url) await cache.put(url, response.clone()) } + response = Response.json(response.body, response) response.headers.set('X-Response-Time', timeNow() - now) return response } \ No newline at end of file From 6d59c9536ebfd654ed2a9a6343bba323c03cec2d Mon Sep 17 00:00:00 2001 From: ihsangan Date: Wed, 15 Oct 2025 20:00:49 +0800 Subject: [PATCH 15/31] ..? --- src/handler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/handler.ts b/src/handler.ts index 7c1bdcb..3009432 100644 --- a/src/handler.ts +++ b/src/handler.ts @@ -25,7 +25,7 @@ export default async function checkCache(request: Request): Promise { response = await serveResult(url) await cache.put(url, response.clone()) } - response = Response.json(response.body, response) + response = new Response(response.body, response) response.headers.set('X-Response-Time', timeNow() - now) return response } \ No newline at end of file From 05bbd13da64ef5c255b91860691168becf1c51c9 Mon Sep 17 00:00:00 2001 From: ihsangan Date: Thu, 16 Oct 2025 18:02:28 +0800 Subject: [PATCH 16/31] function getParams --- src/routing.ts | 8 ++------ src/utils.ts | 21 ++++++++++++++++++++- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/routing.ts b/src/routing.ts index 3f3d514..fa5fa6a 100644 --- a/src/routing.ts +++ b/src/routing.ts @@ -1,12 +1,8 @@ -import { getUrl, Result } from './utils' +import { getParams, Result } from './utils' import * as router from './router' export default async function callAPI(url: string): Promise { - const requestUrl = getUrl(url) - const path = requestUrl.pathname - const params = requestUrl.searchParams - const id = params.get('id') - const server = params.get('server') || params.get('zone') + const { path, id, server } = getParams(url) if (!id) { return { success: false, diff --git a/src/utils.ts b/src/utils.ts index b1d7894..e5ec8f2 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -35,6 +35,18 @@ export async function parseRequest(request: Request): Promise { return url.toString() } +export async function getParams(inputUrl: string): Params { + const url = getUrl(inputUrl) + const urlParams = url.searchParams + const params: Params = { + path = url.pathname + } + for (const [key, value] of urlParams.entries()) { + params[key] = value + } + return params +} + export async function hitCoda(body: string): Promise { const response = await fetch('https://order-sg.codashop.com/initPayment.action', { method: 'POST', @@ -46,11 +58,18 @@ export async function hitCoda(body: string): Promise { return await response.json() } +interface Params{ + path: string + id?: string + server?: string + decode?: string +} + export interface Result { success: boolean game?: string id?: number | string - server?: string | number, + server?: string | number name?: string message?: string } \ No newline at end of file From d626e0f393e11bb2754d6c8ea1038d8ec17da5c9 Mon Sep 17 00:00:00 2001 From: ihsangan Date: Thu, 16 Oct 2025 18:05:50 +0800 Subject: [PATCH 17/31] . --- src/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.ts b/src/utils.ts index e5ec8f2..e894536 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -39,7 +39,7 @@ export async function getParams(inputUrl: string): Params { const url = getUrl(inputUrl) const urlParams = url.searchParams const params: Params = { - path = url.pathname + path: url.pathname } for (const [key, value] of urlParams.entries()) { params[key] = value From 6c27f2c75f3a6be796ce56c6eff131883fdc7aea Mon Sep 17 00:00:00 2001 From: ihsangan Date: Thu, 16 Oct 2025 18:36:15 +0800 Subject: [PATCH 18/31] 0 --- src/routing.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/routing.ts b/src/routing.ts index fa5fa6a..93aed7d 100644 --- a/src/routing.ts +++ b/src/routing.ts @@ -1,8 +1,13 @@ -import { getParams, Result } from './utils' +import { getParams, getUrl, Result } from './utils' import * as router from './router' export default async function callAPI(url: string): Promise { - const { path, id, server } = getParams(url) + const requestUrl = getUrl(url) + const path = requestUrl.pathname + const params = requestUrl.searchParams + const id = params.get('id') + const server = params.get('server') || params.get('zone') + //const { path, id, server } = getParams(url) if (!id) { return { success: false, From 6313de636afeb01dfaa4fd4ae69b0a798c393cc1 Mon Sep 17 00:00:00 2001 From: ihsangan Date: Thu, 16 Oct 2025 18:39:43 +0800 Subject: [PATCH 19/31] 1 --- src/routing.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/routing.ts b/src/routing.ts index 93aed7d..9db6020 100644 --- a/src/routing.ts +++ b/src/routing.ts @@ -5,9 +5,9 @@ export default async function callAPI(url: string): Promise { const requestUrl = getUrl(url) const path = requestUrl.pathname const params = requestUrl.searchParams - const id = params.get('id') - const server = params.get('server') || params.get('zone') - //const { path, id, server } = getParams(url) + //const id = params.get('id') + //const server = params.get('server') || params.get('zone') + const { id, server } = getParams(url) if (!id) { return { success: false, From 5ec053c77d716cb02d236eae22651a941835ad95 Mon Sep 17 00:00:00 2001 From: ihsangan Date: Thu, 16 Oct 2025 18:44:53 +0800 Subject: [PATCH 20/31] update utils.ts --- src/utils.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index e894536..b484049 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -35,10 +35,10 @@ export async function parseRequest(request: Request): Promise { return url.toString() } -export async function getParams(inputUrl: string): Params { - const url = getUrl(inputUrl) +export async function getParams(inputUrl: string): Record { + const url = new URL(inputUrl) const urlParams = url.searchParams - const params: Params = { + const params: Record = { path: url.pathname } for (const [key, value] of urlParams.entries()) { From 4ee5e9c6a65c73688407c61be1d16647619f653b Mon Sep 17 00:00:00 2001 From: ihsangan Date: Thu, 16 Oct 2025 18:50:19 +0800 Subject: [PATCH 21/31] update routing.ts --- src/routing.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/routing.ts b/src/routing.ts index 9db6020..e5152a1 100644 --- a/src/routing.ts +++ b/src/routing.ts @@ -4,11 +4,11 @@ import * as router from './router' export default async function callAPI(url: string): Promise { const requestUrl = getUrl(url) const path = requestUrl.pathname - const params = requestUrl.searchParams + //const params = requestUrl.searchParams //const id = params.get('id') //const server = params.get('server') || params.get('zone') - const { id, server } = getParams(url) - if (!id) { + const params = getParams(url) + if (!params.id) { return { success: false, message: 'Bad request' @@ -21,7 +21,7 @@ export default async function callAPI(url: string): Promise { case path.includes('/codm'): return await router.codm(Number(id)) case path.includes('/ff'): - return await router.ff(Number(id)) + return await router.ff(Number(params.id)) case path.includes('/gi'): return await router.gi(Number(id)) case path.includes('/hi'): From 8c8748bca7d1681258444da3c2783d3ffa32ff54 Mon Sep 17 00:00:00 2001 From: ihsangan Date: Thu, 16 Oct 2025 18:53:27 +0800 Subject: [PATCH 22/31] update routing.ts --- src/routing.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routing.ts b/src/routing.ts index e5152a1..a6aff75 100644 --- a/src/routing.ts +++ b/src/routing.ts @@ -11,7 +11,7 @@ export default async function callAPI(url: string): Promise { if (!params.id) { return { success: false, - message: 'Bad request' + message: params } } try { From b4295eb63a0020766b70da8a3afa9b6a6d55b97c Mon Sep 17 00:00:00 2001 From: ihsangan Date: Thu, 16 Oct 2025 18:54:54 +0800 Subject: [PATCH 23/31] update routing.ts --- src/routing.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routing.ts b/src/routing.ts index a6aff75..a597e62 100644 --- a/src/routing.ts +++ b/src/routing.ts @@ -11,7 +11,7 @@ export default async function callAPI(url: string): Promise { if (!params.id) { return { success: false, - message: params + message: url } } try { From a79b2000f1924feb6b36953cec38df6c7c24f3f0 Mon Sep 17 00:00:00 2001 From: ihsangan Date: Thu, 16 Oct 2025 19:01:12 +0800 Subject: [PATCH 24/31] update routing.ts --- src/routing.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routing.ts b/src/routing.ts index a597e62..8ad4a02 100644 --- a/src/routing.ts +++ b/src/routing.ts @@ -11,7 +11,7 @@ export default async function callAPI(url: string): Promise { if (!params.id) { return { success: false, - message: url + message: JSON.stringify(params) } } try { From 9c20983ff1d2ef64a604090865f364b939f7a737 Mon Sep 17 00:00:00 2001 From: ihsangan Date: Thu, 16 Oct 2025 19:06:22 +0800 Subject: [PATCH 25/31] update utils.ts --- src/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.ts b/src/utils.ts index b484049..3b99021 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -35,7 +35,7 @@ export async function parseRequest(request: Request): Promise { return url.toString() } -export async function getParams(inputUrl: string): Record { +export function getParams(inputUrl: string): Record { const url = new URL(inputUrl) const urlParams = url.searchParams const params: Record = { From 4b9c19f0ffbf46abeeca241539523d6c7af7e833 Mon Sep 17 00:00:00 2001 From: ihsangan Date: Thu, 16 Oct 2025 19:23:51 +0800 Subject: [PATCH 26/31] update --- src/routing.ts | 16 ++++++---------- src/utils.ts | 5 +++-- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/routing.ts b/src/routing.ts index 8ad4a02..f35f393 100644 --- a/src/routing.ts +++ b/src/routing.ts @@ -1,17 +1,13 @@ -import { getParams, getUrl, Result } from './utils' +import { getParams, Result } from './utils' import * as router from './router' export default async function callAPI(url: string): Promise { - const requestUrl = getUrl(url) - const path = requestUrl.pathname - //const params = requestUrl.searchParams - //const id = params.get('id') - //const server = params.get('server') || params.get('zone') - const params = getParams(url) - if (!params.id) { + let { path, id, server, zone} = getParams(url) + server = server || zone + if (id) { return { success: false, - message: JSON.stringify(params) + message: 'Bad request' } } try { @@ -21,7 +17,7 @@ export default async function callAPI(url: string): Promise { case path.includes('/codm'): return await router.codm(Number(id)) case path.includes('/ff'): - return await router.ff(Number(params.id)) + return await router.ff(Number(id)) case path.includes('/gi'): return await router.gi(Number(id)) case path.includes('/hi'): diff --git a/src/utils.ts b/src/utils.ts index 3b99021..3a16a98 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -35,10 +35,10 @@ export async function parseRequest(request: Request): Promise { return url.toString() } -export function getParams(inputUrl: string): Record { +export function getParams(inputUrl: string): Params { const url = new URL(inputUrl) const urlParams = url.searchParams - const params: Record = { + const params: Params = { path: url.pathname } for (const [key, value] of urlParams.entries()) { @@ -62,6 +62,7 @@ interface Params{ path: string id?: string server?: string + zone?: string decode?: string } From 7a61ceea44de0ed6040a6fcf22ccd9f508ee4b80 Mon Sep 17 00:00:00 2001 From: ihsangan Date: Thu, 16 Oct 2025 19:28:49 +0800 Subject: [PATCH 27/31] kurang "!" jirr --- src/routing.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routing.ts b/src/routing.ts index f35f393..6692ddb 100644 --- a/src/routing.ts +++ b/src/routing.ts @@ -4,7 +4,7 @@ import * as router from './router' export default async function callAPI(url: string): Promise { let { path, id, server, zone} = getParams(url) server = server || zone - if (id) { + if (!id) { return { success: false, message: 'Bad request' From 78f1b08d1aab42059d7bdd98ecf0e739fdd9d6dc Mon Sep 17 00:00:00 2001 From: ihsangan Date: Fri, 17 Oct 2025 09:20:09 +0800 Subject: [PATCH 28/31] update --- src/handler.ts | 3 +-- src/helpers.ts | 6 +++--- src/utils.ts | 6 +----- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/handler.ts b/src/handler.ts index 3009432..701deb8 100644 --- a/src/handler.ts +++ b/src/handler.ts @@ -13,8 +13,7 @@ export default async function checkCache(request: Request): Promise { 'Allow': allowedMethod.join(', '), 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': allowedMethod.join(', '), - 'X-Powered-By': '@ihsangan/valid', - 'X-Response-Time': timeNow() - now + 'X-Powered-By': '@ihsangan/valid' } }) } diff --git a/src/helpers.ts b/src/helpers.ts index a36ecc1..d261424 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -1,13 +1,13 @@ -import { getUrl, Result, allowedMethod } from './utils' +import { getParams, Result, allowedMethod } from './utils' import callAPI from './routing' export default async function serveResult(url: string): Promise { - const dc = getUrl(url).searchParams.get('decode') + const { decode } = getParams(url) let status = 200 let result: Result = await callAPI(url) if (result.name) { result.name = result.name.replace(/\u002B/g, '%20') - if (dc === null || dc === 'true' || dc !== 'false') { + if (decode === null || decode === 'true' || decode !== 'false') { result.name = decodeURIComponent(result.name) } } diff --git a/src/utils.ts b/src/utils.ts index 3a16a98..e9aa6b9 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,15 +1,11 @@ export const allowedMethod = ['GET', 'HEAD', 'POST'] -export function getUrl(request: Request | string): URL { - return new URL(request.url || request) -} - export function timeNow(): number { return Date.now() } export async function parseRequest(request: Request): Promise { - let url = getUrl(request) + let url = new URL(request) if (request.method === 'POST') { const contentType = request.headers.get('content-type') let data: { [key: string]: string | null } = {} From 079731aefedbaf648d581979e4235dea2500fc37 Mon Sep 17 00:00:00 2001 From: ihsangan Date: Fri, 17 Oct 2025 09:32:12 +0800 Subject: [PATCH 29/31] request.url --- src/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.ts b/src/utils.ts index e9aa6b9..8707f46 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -5,7 +5,7 @@ export function timeNow(): number { } export async function parseRequest(request: Request): Promise { - let url = new URL(request) + let url = new URL(request.url) if (request.method === 'POST') { const contentType = request.headers.get('content-type') let data: { [key: string]: string | null } = {} From cee013b35f21f9ab7ffdbe389aedd0bf37028e21 Mon Sep 17 00:00:00 2001 From: ihsangan Date: Fri, 17 Oct 2025 09:41:45 +0800 Subject: [PATCH 30/31] update handler.ts --- src/handler.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/handler.ts b/src/handler.ts index 701deb8..ad40e28 100644 --- a/src/handler.ts +++ b/src/handler.ts @@ -2,7 +2,7 @@ import { allowedMethod, parseRequest, timeNow } from './utils' import serveResult from './helpers' export default async function checkCache(request: Request): Promise { - const now = timeNow() + const now = Date.now() if (allowedMethod.indexOf(request.method) === -1) { return Response.json({ success: false, @@ -25,6 +25,6 @@ export default async function checkCache(request: Request): Promise { await cache.put(url, response.clone()) } response = new Response(response.body, response) - response.headers.set('X-Response-Time', timeNow() - now) + response.headers.set('X-Response-Time', Date.now() - now) return response } \ No newline at end of file From a3ab4a3974a1779a48b16e81b57b75809d1af739 Mon Sep 17 00:00:00 2001 From: ihsangan Date: Fri, 17 Oct 2025 21:39:30 +0800 Subject: [PATCH 31/31] finish --- LICENSE | 54 ++++++++++++++++++++++++++++++-------------------- README.md | 31 +++++++++++++++++++++++++++-- src/helpers.ts | 2 +- wrangler.toml | 2 +- 4 files changed, 63 insertions(+), 26 deletions(-) mode change 100755 => 100644 LICENSE diff --git a/LICENSE b/LICENSE old mode 100755 new mode 100644 index 2c66ec6..bfef380 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Attribution-ShareAlike 4.0 International +Attribution-NonCommercial-ShareAlike 4.0 International ======================================================================= @@ -54,18 +54,18 @@ exhaustive, and do not form part of our licenses. ======================================================================= -Creative Commons Attribution-ShareAlike 4.0 International Public -License +Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International +Public License By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons -Attribution-ShareAlike 4.0 International Public License ("Public -License"). To the extent this Public License may be interpreted as a -contract, You are granted the Licensed Rights in consideration of Your -acceptance of these terms and conditions, and the Licensor grants You -such rights in consideration of benefits the Licensor receives from -making the Licensed Material available under these terms and -conditions. +Attribution-NonCommercial-ShareAlike 4.0 International Public License +("Public License"). To the extent this Public License may be +interpreted as a contract, You are granted the Licensed Rights in +consideration of Your acceptance of these terms and conditions, and the +Licensor grants You such rights in consideration of benefits the +Licensor receives from making the Licensed Material available under +these terms and conditions. Section 1 -- Definitions. @@ -84,7 +84,7 @@ Section 1 -- Definitions. and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License. - c. BY-SA Compatible License means a license listed at + c. BY-NC-SA Compatible License means a license listed at creativecommons.org/compatiblelicenses, approved by Creative Commons as essentially the equivalent of this Public License. @@ -108,7 +108,7 @@ Section 1 -- Definitions. g. License Elements means the license attributes listed in the name of a Creative Commons Public License. The License Elements of this - Public License are Attribution and ShareAlike. + Public License are Attribution, NonCommercial, and ShareAlike. h. Licensed Material means the artistic or literary work, database, or other material to which the Licensor applied this Public @@ -122,7 +122,15 @@ Section 1 -- Definitions. j. Licensor means the individual(s) or entity(ies) granting rights under this Public License. - k. Share means to provide material to the public by any means or + k. NonCommercial means not primarily intended for or directed towards + commercial advantage or monetary compensation. For purposes of + this Public License, the exchange of the Licensed Material for + other material subject to Copyright and Similar Rights by digital + file-sharing or similar means is NonCommercial provided there is + no payment of monetary compensation in connection with the + exchange. + + l. Share means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material @@ -130,13 +138,13 @@ Section 1 -- Definitions. public may access the material from a place and at a time individually chosen by them. - l. Sui Generis Database Rights means rights other than copyright + m. Sui Generis Database Rights means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world. - m. You means the individual or entity exercising the Licensed Rights + n. You means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning. @@ -150,9 +158,10 @@ Section 2 -- Scope. exercise the Licensed Rights in the Licensed Material to: a. reproduce and Share the Licensed Material, in whole or - in part; and + in part, for NonCommercial purposes only; and - b. produce, reproduce, and Share Adapted Material. + b. produce, reproduce, and Share Adapted Material for + NonCommercial purposes only. 2. Exceptions and Limitations. For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public @@ -220,7 +229,9 @@ Section 2 -- Scope. Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly - reserves any right to collect such royalties. + reserves any right to collect such royalties, including when + the Licensed Material is used other than for NonCommercial + purposes. Section 3 -- License Conditions. @@ -265,7 +276,6 @@ following conditions. reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information. - 3. If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable. @@ -277,7 +287,7 @@ following conditions. 1. The Adapter's License You apply must be a Creative Commons license with the same License Elements, this version or - later, or a BY-SA Compatible License. + later, or a BY-NC-SA Compatible License. 2. You must include the text of, or the URI or hyperlink to, the Adapter's License You apply. You may satisfy this condition @@ -297,7 +307,8 @@ apply to Your use of the Licensed Material: a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial - portion of the contents of the database; + portion of the contents of the database for NonCommercial purposes + only; b. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database @@ -404,7 +415,6 @@ Section 8 -- Interpretation. that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority. - ======================================================================= Creative Commons is not a party to its public diff --git a/README.md b/README.md index ad13b5d..874da1f 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,35 @@ Kamu bisa langsung fork aja repo ini, atau bisa tekan tombol dibawah ini (jangan ``` https://api.isan.eu.org/nickname ``` +## Metode Request +API ini mendukung metode GET dan POST. +1. Metode GET + +Anda dapat mengirimkan parameter langsung melalui URL. +``` +/ml?id=1114917746&server=13486 +``` +2. Metode POST + +Anda juga dapat mengirimkan data melalui body request dengan `Content-Type` berupa `application/json` atau `application/x-www-form-urlencoded`. Ini berguna untuk menyembunyikan parameter dari URL. + +Contoh (`application/json`): +```sh +curl -X POST 'https://api.isan.eu.org/nickname/ml' \ +-H 'Content-Type: application/json' \ +-d '{ + "id": "1114917746", + "server": "13486" +}' +``` +Contoh (`application/x-www-form-urlencoded`): +```sh +curl -X POST 'https://api.isan.eu.org/nickname/ml' \ +-H 'Content-Type: application/x-www-form-urlencoded' \ +-d 'id=1114917746&server=13486' +``` ## Output -application/json; charset=utf-8 ([RFC4627](https://datatracker.ietf.org/doc/html/rfc4627)) +application/json ([RFC4627](https://datatracker.ietf.org/doc/html/rfc4627)) ```ts interface Result { success: boolean; @@ -117,4 +144,4 @@ Contoh penggunaan `?decode=true` ## Monitoring API monitoring [UptimeRobot](https://stats.uptimerobot.com/s9axzR77Fm) # Copyright -© Projek ini dibawah lisensi: [CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/), tidak terafiliasi dengan Codashop. +© Projek ini dibawah lisensi: [CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/), tidak terafiliasi dengan Codashop. diff --git a/src/helpers.ts b/src/helpers.ts index d261424..9c3085d 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -23,7 +23,7 @@ export default async function serveResult(url: string): Promise { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': allowedMethod.join(', '), 'Access-Control-Expose-Headers': '*', - 'Cache-Control': 'public, max-age=30, s-maxage=30', + 'Cache-Control': 'public, max-age=30, s-maxage=43200, proxy-revalidate, immutable', 'X-Powered-By': '@ihsangan/valid' } }) diff --git a/wrangler.toml b/wrangler.toml index eb04b7c..36040e2 100644 --- a/wrangler.toml +++ b/wrangler.toml @@ -1,4 +1,4 @@ -name = "validev" +name = "validator" main = "./src/index.ts" workers_dev = true compatibility_date = "2025-01-01"