This commit is contained in:
Rizky 2023-11-19 10:06:39 +07:00
parent b370df7af6
commit 34da559ee6
4 changed files with 194 additions and 98 deletions

View File

@ -1,11 +1,84 @@
import { dirAsync } from "fs-jetpack";
import trim from "lodash/trim";
import { dirname } from "path";
import { apiContext } from "service-srv"; import { apiContext } from "service-srv";
import { g } from "utils/global";
import { baseTypings } from "../../web/src/utils/script/types/base";
export const _ = { export const _ = {
url: "/code/:site_id/:action", url: "/code/:site_id/:action",
async api(site_id: string, action: "list") { async api(site_id: string, action: "list" | "reload-api") {
const { req, res } = apiContext(this); const { req, res } = apiContext(this);
if (action === "list") { if (action === "reload-api") {
const site = await db.site.findFirst({
select: { config: true },
where: { id: site_id },
});
if (site && site.config) {
const base = trim((site.config as any).api_url || "", "/");
const apires = await fetch(`${base}/_prasi/load.json`);
const json = (await apires.json()) as {
apiEntry: {};
apiTypes: string;
prismaTypes: Record<string, string>;
};
let apiPath = "";
if (typeof json.apiTypes === "string") {
apiPath = "gen/srv/api/srv";
await Bun.write(
`${g.datadir}/site/code/${site_id}/api-types.d.ts`,
json.apiTypes
);
}
for (const [k, v] of Object.entries(json.prismaTypes)) {
await dirAsync(dirname(`${g.datadir}/site/code/${site_id}/${k}`));
await Bun.write(
`${g.datadir}/site/code/${site_id}/${k}`,
JSON.parse(v)
);
}
await Bun.write(
`${g.datadir}/site/code/${site_id}/global.d.ts`,
`\
import React from "react";
import {
FC as ReactFC,
ReactNode as RNode,
ReactElement as RElement,
} from "react";
import * as prisma from "./prisma";
${iftext(
apiPath,
`\
import "./api-types";
import type * as SRVAPI from "${apiPath}";
`
)}
declare global {
const db: prisma.PrismaClient;
${baseTypings}
${iftext(
apiPath,
`\
type Api = typeof SRVAPI;
type ApiName = keyof Api;
const api: { [k in ApiName]: Awaited<Api[k]["handler"]>["_"]["api"] };
`
)}
}
`
);
return new Response("OK");
}
return new Response("NOT FOUND", { status: 404 });
} else if (action === "list") {
let list = await db.code.findMany({ where: { id_site: site_id } }); let list = await db.code.findMany({ where: { id_site: site_id } });
if (!list.find((e) => e.name === "site")) { if (!list.find((e) => e.name === "site")) {
@ -36,3 +109,10 @@ export const _ = {
return "This is code.ts"; return "This is code.ts";
}, },
}; };
export const iftext = (condition: any, text: string) => {
if (condition) {
return text;
}
return "";
};

View File

@ -91,7 +91,12 @@ declare module "ts:prisma" {
register( register(
monaco, monaco,
`\ `\
import React from 'react'; import React from "react";
import {
FC as ReactFC,
ReactNode as RNode,
ReactElement as RElement,
} from "react";
import prisma from 'ts:prisma'; import prisma from 'ts:prisma';
${iftext( ${iftext(

View File

@ -1,13 +1,13 @@
export const baseTypings = ` export const baseTypings = `
type FC<T> = React.FC<T>; type FC<T> = ReactFC<T>;
const Fragment = React.Fragment; const Fragment: typeof React.Fragment;
const ReactNode = React.ReactNode; const ReactNode: RNode;
const useCallback = React.useCallback; const useCallback: typeof React.useCallback;
const useMemo = React.useMemo; const useMemo: typeof React.useMemo;
const ReactElement = React.ReactElement; const ReactElement: RElement;
const isValidElement = React.isValidElement; const isValidElement: typeof React.isValidElement;
const useEffect = React.useEffect; const useEffect: typeof React.useEffect;
const useState = React.useState; const useState: typeof React.useState;
const pathname: string; const pathname: string;
const isEditor: boolean; const isEditor: boolean;
@ -18,9 +18,9 @@ const preload: (pathname: string) => void;
const apiHeaders: Record<string, any>; const apiHeaders: Record<string, any>;
const navigate: (url: string) => void; const navigate: (url: string) => void;
const params: any; const params: any;
const cx = (...classNames: any[]) => string; const cx: (...classNames: any[]) => string;
const css = ( const css: (
tag: CSSAttribute | TemplateStringsArray | string, tag: TemplateStringsArray | string,
...props: Array<string | number | boolean | undefined | null> ...props: Array<string | number | boolean | undefined | null>
) => string; ) => string;
@ -30,61 +30,69 @@ const props: {
onPointerMove?: () => void; onPointerMove?: () => void;
onPointerLeave?: () => void; onPointerLeave?: () => void;
}; };
const children: ReactNode; const children: RNode;
const PassProp: FC<Record<string,any> & {children: React.ReactNode; }>; const PassProp: FC<Record<string, any> & { children: React.ReactNode }>;
const PassChild: FC<{ name: string }>; const PassChild: FC<{ name: string }>;
const Preload: FC<{ url: string[] }>; const Preload: FC<{ url: string[] }>;
const apiurl: string; const apiurl: string;
const pageid: string; const pageid: string;
type ITEM = { type ITEM = {
id: string id: string;
name: string; name: string;
type: 'item' | 'text'; type: "item" | "text";
adv?: { adv?: {
js?: string; js?: string;
jsBuilt?: string; jsBuilt?: string;
css?: string; css?: string;
html?: string; html?: string;
}, };
text: string, text: string;
html: string, html: string;
component?: { id:string, props: Record<string, { component?: {
value: string, id: string;
valueBuilt: string, props: Record<
meta: { type: string } string,
}>}, {
childs: ITEM[] value: string;
valueBuilt: string;
meta: { type: string };
} }
>;
};
childs: ITEM[];
};
const newElement: (gen?: (item: ITEM) => ITEM | ITEM[]) => React.ReactNode; const newElement: (gen?: (item: ITEM) => ITEM | ITEM[]) => React.ReactNode;
const mobile: { const mobile: {
notif: { notif: {
register: (user_id: string) => void; register: (user_id: string) => void;
send: (data: { send: (data: {
user_id: string, user_id: string;
title: string, title: string;
body: string, body: string;
data: any data: any;
}) => void; }) => void;
onTap: (data: null |{ onTap: (
user_id: string, data: null | {
title: string, user_id: string;
body: string, title: string;
data: any body: string;
}) => void | Promise<void>; data: any;
onReceive: (data: {
user_id: string,
title: string,
body: string,
data: any
}) => void | Promise<void>
} }
) => void | Promise<void>;
onReceive: (data: {
user_id: string;
title: string;
body: string;
data: any;
}) => void | Promise<void>;
};
}; };
const Local: <T extends Record<string, any>>(arg: { const Local: <T extends Record<string, any>>(arg: {
name: string; name: string;
idx?: any; idx?: any;
value: T; value: T;
children: ((local: T & { render: () => void }) => any); children: (local: T & { render: () => void }) => any;
deps?: any[]; deps?: any[];
effect?: ( effect?: (
local: T & { render: () => void } local: T & { render: () => void }
@ -93,6 +101,5 @@ const Local: <T extends Record<string, any>>(arg: {
local: T & { render: () => void } local: T & { render: () => void }
) => void | (() => void) | Promise<void | (() => void)>; ) => void | (() => void) | Promise<void | (() => void)>;
cache?: boolean; cache?: boolean;
}) => ReactNode; }) => RNode
`; `;

View File

@ -94,7 +94,12 @@ declare module "ts:prisma" {
register( register(
monaco, monaco,
`\ `\
import React from 'react'; import React from "react";
import {
FC as ReactFC,
ReactNode as RNode,
ReactElement as RElement,
} from "react";
import prisma from 'ts:prisma'; import prisma from 'ts:prisma';
${iftext( ${iftext(
@ -109,7 +114,6 @@ declare global {;
${baseTypings} ${baseTypings}
const moko: {nama: string};
${propText.join("\n")} ${propText.join("\n")}
${iftext( ${iftext(