add factory for request

This commit is contained in:
liangping 2023-04-03 17:08:36 +08:00
parent 671050f5f2
commit 7f477bcd9f
2 changed files with 75 additions and 50 deletions

View File

@ -1,20 +1,30 @@
import fetch from 'cross-fetch' import fetch from 'cross-fetch'
export interface ApiResponse<T> { export async function fetchData<T>(url: string, adapter: (source: any) => T): Promise<T> {
data: T; const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error: ${response.status}`);
}
const data = await response.json();
return adapter(data);
} }
// Usage: // Usage:
// const usersResponse = await fetchData<User[]>("https://somewhere/") /*
export async function fetchData<T>(url: string): Promise<ApiResponse<T>> { const userAdapter = (source: any): User => {
const response = await fetch(url); return {
const data = await response.json(); id: source.id,
name: source.name,
const result : ApiResponse<T> = { email: source.email,
data };
} };
return result try {
const userData = await fetchData<User>("https://jsonplaceholder.typicode.com/users/1", userAdapter);
console.log(userData); // Output: { id: 1, name: "Leanne Graham", email: "Sincere@april.biz" }
} catch (error) {
console.error(error.message);
} }
// */
export async function get(url: string) { export async function get(url: string) {
return (await fetch(url)).json() return (await fetch(url)).json()

View File

@ -1,46 +1,61 @@
import semver from "semver"; import semver from "semver";
interface Registry {
[key: string]: string; export interface Request<T> {
} url: string,
adapter: (source: any) => T
const registry: Registry = { }
v1: "https://example.com/api/v1/endpoint",
v2: "https://example.com/api/v2/endpoint", interface User {
v3: "https://example.com/api/v3/endpoint",
alpha: "https://example.com/api/alpha/endpoint", }
beta: "https://example.com/api/beta/endpoint",
production: "https://example.com/api/production/endpoint", interface Post {
};
}
export function findConfigByName(name: string): string {
const base = "https://example.com/api/"; export interface RequestRegistry {
users: Request<User>;
const url = registry[name]; posts: Request<Post>;
if (!url) { }
throw new Error(`Unsupported version or name: ${name}`);
} export function convert<T>(source: any): T {
return source
return url; }
export interface Registry {
[key: string]: RequestRegistry;
}
export function withCustomAdapter<T extends RequestRegistry>(target: T, source: Partial<T>): T {
return Object.assign({}, target, source);
}
export function findConfigByName(name: string, registry: Registry): RequestRegistry {
const url = registry[name];
if (!url) {
throw new Error(`Unsupported version or name: ${name}`);
} }
export function findConfigByVersion(version: string, registry: Registry): string { return url;
let closestVersion: string | null = null; }
for (const key in registry) { export function findConfigByVersion(version: string, registry: Registry): RequestRegistry {
if (semver.satisfies(key, version)) { let closestVersion: string | null = null;
if (!closestVersion || semver.gt(key, closestVersion)) {
closestVersion = key; for (const key in registry) {
} if (semver.satisfies(key, version)) {
if (!closestVersion || semver.gt(key, closestVersion)) {
closestVersion = key;
} }
} }
if (!closestVersion) {
throw new Error(`Unsupported version: ${version}`);
}
console.log(`Closest version to ${version}: ${closestVersion}`);
return registry[closestVersion];
} }
if (!closestVersion) {
throw new Error(`Unsupported version: ${version}`);
}
console.log(`Closest version to ${version}: ${closestVersion}`);
return registry[closestVersion];
}