Spaces:
Sleeping
Sleeping
File size: 3,508 Bytes
fcd4478 f80b091 fcd4478 c3e8f3d f80b091 66e93d1 f80b091 c3e8f3d f80b091 fcd4478 f80b091 fcd4478 f80b091 fcd4478 f80b091 fcd4478 f80b091 66e93d1 f80b091 66e93d1 f80b091 66e93d1 f80b091 fcd4478 f80b091 fcd4478 f80b091 fcd4478 c3e8f3d f80b091 fcd4478 f80b091 fcd4478 66e93d1 fcd4478 c3e8f3d f80b091 fcd4478 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
import { auth } from '@/auth';
import { v5 as uuidV5 } from 'uuid';
interface ApiResponse<T> {
code: number; // code from server 0
message: string;
data: T;
}
const clefApiBuilder = <Params extends object | void, Resp>(
path: string,
options?: {
// default to GET
method: 'GET' | 'POST';
// default to 'app'
prefix: 'api' | 'app' | 'api.dev' | 'app.dev';
},
) => {
return async (params: Params): Promise<Resp> => {
const session = await auth();
const email = session?.user?.email;
if (!email || !email.endsWith('@landing.ai')) {
throw new Response('Unauthorized', {
status: 401,
});
}
const sessionUser = {
id: uuidV5(email, uuidV5.URL),
orgId: '-1024',
email: email,
username: email.split('@')[0],
userRole: 'adminPortal',
bucket: 'fake_bucket',
};
const prefix = options?.prefix ?? 'app';
const baseURL = `https://${prefix}.landing.ai/${path}`;
const method = options?.method ?? 'GET';
// Create a URL object with query params
const url = new URL(baseURL);
if (method === 'GET') {
Object.entries(params ?? {}).forEach(([key, value]) =>
url.searchParams.append(key, value),
);
}
const fetchParams: RequestInit = {
method: options?.method ?? 'GET',
headers: {
sessionuser: JSON.stringify(sessionUser), // faked production user
apikey: 'land_sk_DKeoYtaZZrYqJ9TMMiXe4BIQgJcZ0s3XAoB0JT3jv73FFqnr6k', // dev key
'X-ROUTE': 'mingruizhang-landing',
},
};
if (method === 'POST' && params instanceof Object) {
const formData = new FormData();
for (const [key, value] of Object.entries(params)) {
formData.append(key, value);
}
fetchParams.body = formData;
}
const res = await fetch(url.toString(), fetchParams);
if (!res.ok) {
console.error('ERROR: fetch data failure', res.status, res.statusText);
// This will activate the closest `error.js` Error Boundary
throw new Error('Failed to fetch data');
}
const { data }: ApiResponse<Resp> = await res.json();
return data;
};
};
export type ProjectBaseInfo = {
id: number;
name: string;
created_at: Date;
label_type: string;
organization: {
id: number;
name: string;
};
};
/**
* Fetch recent projects from all organizations from past 30 days, excluding
* 1. test organization such as bdd, cypress
* 2. internal organization such as landing, landing-ai, orgId=1
* 3. projects not containing media or only contain sample media
* @author https://github.com/landing-ai/landing-platform/blob/mingrui-04-08-meaningful-project/packages/server-clef/src/main_app/controllers/admin/get_admin_meaningful_project_controller.ts
*/
export const fetchRecentProjectList = clefApiBuilder<void, ProjectBaseInfo[]>(
'api/admin/projects/recent',
);
export type MediaDetails = {
id: number;
name: string;
path: string;
url: string;
projectId: number;
thumbnails: string[];
properties: {
width: number;
height: number;
format: string;
orientation: number;
};
};
/**
* Randomly fetch 10 media from a given project
* @author https://github.com/landing-ai/landing-platform/blob/mingrui-04-08-meaningful-project/packages/server-clef/src/main_app/controllers/admin/get_admin_meaningful_project_controller.ts
*/
export const fetchProjectMedia = clefApiBuilder<
{ projectId: number },
MediaDetails[]
>('api/admin/project/media');
|