fix server content-type

This commit is contained in:
Rizky 2023-10-15 23:08:00 +07:00
parent f894e70c69
commit cbab0edec2
17 changed files with 856 additions and 34 deletions

189
app/srv/api/npm-bundle.ts Normal file
View File

@ -0,0 +1,189 @@
import globalExternals from "@fal-works/esbuild-plugin-global-externals";
import { style } from "@hyrious/esbuild-plugin-style";
import { npm_page, npm_site } from "dbgen";
import { dir } from "dir";
import { build } from "esbuild";
import { $ } from "execa";
import { dirAsync, writeAsync } from "fs-jetpack";
import { stat } from "fs/promises";
import { apiContext } from "service-srv";
import { g } from "utils/global";
import { validate } from "uuid";
import { glb } from "../global";
import { eg } from "../ws/edit/edit-global";
export type NPMImportAs = {
main: { mode: "default" | "*"; name: string };
names: string[];
custom?: string;
};
export const _ = {
url: "/npm-bundle/:mode/:id",
async api(mode: "site" | "page", id: string) {
const {} = apiContext(this);
if (!validate(id)) return "-";
let items = [] as npm_page[] | npm_site[];
if (mode === "site") {
items = await db.npm_site.findMany({ where: { id_site: id } });
} else {
items = await db.npm_page.findMany({ where: { id_page: id } });
}
const packages: Record<string, string> = {};
const imports = items
.map((e) => {
const import_as = e.import_as as NPMImportAs;
packages[e.module] = e.version;
if (import_as.main.name || import_as.names.length > 0) {
let main = "";
let names = import_as.names.map((e) => `${e} as __${e}`);
if (import_as.main.name) {
main =
import_as.main.mode === "default"
? `__${import_as.main.name}`
: `* as __${import_as.main.name}`;
}
const imports = [
main.trim(),
(names.length > 0 ? `{ ${names.join(",")} }` : "").trim(),
].filter((e) => e);
let final = "";
if (imports.length > 0) {
final = `import ${imports.join(",")} from "${e.module}";`;
}
if (import_as.custom) {
final = final + "\n" + import_as.custom;
}
return final;
}
return "";
})
.filter((e) => !!e)
.join("\n");
const exports = items
.map((e) => {
const import_as = e.import_as as NPMImportAs;
const res: string[] = [];
if (import_as.main.name || import_as.names.length > 0) {
let main = "";
let names = import_as.names;
if (import_as.main.name) {
main = import_as.main.name;
}
if (main) {
res.push(`window.exports.${main} = __${main};`);
}
if (names.length > 0) {
names.forEach((e) => {
res.push(`window.exports.${e} = __${e};`);
});
}
}
return res.join("\n").trim();
})
.filter((e) => !!e)
.join("\n");
const src = `\
${imports}
${exports}
`.trim();
await dirAsync(dir.path(`${g.datadir}/npm/${mode}/${id}`));
await writeAsync(dir.path(`${g.datadir}/npm/${mode}/${id}/input.js`), src);
packages["react"] = "18.2.0";
packages["react-dom"] = "18.2.0";
await writeAsync(dir.path(`${g.datadir}/npm/${mode}/${id}/package.json`), {
dependencies: packages,
});
await writeAsync(
dir.path(`${g.datadir}/npm/${mode}/${id}/pnpm-workspace.yaml`),
`\
packages:
- ./*`
);
try {
await $({
cwd: dir.path(`${g.datadir}/npm/${mode}/${id}`),
})`pnpm i`;
await build({
absWorkingDir: dir.path(`${g.datadir}/npm/${mode}/${id}`),
entryPoints: ["input.js"],
bundle: true,
outfile: "index.js",
minify: true,
treeShaking: true,
sourcemap: true,
plugins: [
style(),
globalExternals({
react: {
varName: "window.React",
type: "cjs",
},
"react-dom": {
varName: "window.ReactDOM",
type: "cjs",
},
}),
],
logLevel: "silent",
});
} catch (e) {
return e;
}
try {
const s = await stat(dir.path(`${g.datadir}/npm/${mode}/${id}/index.js`));
if (mode === "page") {
delete glb.npm.page[id];
await db.npm_page.updateMany({
where: {
id_page: id,
},
data: { bundled: true },
});
const p = eg.edit.page[id];
if (p) {
await db.page.update({
where: {
id,
},
data: {
updated_at: new Date(),
},
});
p.doc.getMap("map").set("updated_at", new Date().toISOString());
}
} else if (mode === "site") {
delete glb.npm.site[id];
await db.npm_site.updateMany({
where: {
id_site: id,
},
data: { bundled: true },
});
}
return s.size.toString();
} catch (e) {
return "-";
}
},
};

16
app/srv/api/npm-size.ts Normal file
View File

@ -0,0 +1,16 @@
import { dir } from "dir";
import { stat } from "fs/promises";
import { apiContext } from "service-srv";
import { g } from "utils/global";
export const _ = {
url: "/npm-size/:mode/:id",
async api(mode: "site" | "page", id: string) {
const { req, res } = apiContext(this);
try {
const s = await stat(dir.path(`${g.datadir}/npm/${mode}/${id}/index.js`));
return s.size.toString();
} catch (e) {}
return "-";
},
};

View File

@ -4,14 +4,13 @@ import { readAsync } from "fs-jetpack";
import mime from "mime-types";
import { apiContext } from "service-srv";
import { glb } from "../global";
import { g } from "utils/global";
export const _ = {
url: "/npm/:mode/:id/*",
async api(mode: "site" | "page", id: string) {
const { req, res, mode: _mode } = apiContext(this);
let path = dir.path(`../npm/${mode}/${id}/${req.params._}`);
res.setHeader("Access-Control-Allow-Origin", "*");
let path = dir.path(`${g.datadir}/npm/${mode}/${id}/${req.params._}`);
if (!glb.npm) {
glb.npm = { page: {}, site: {} };

582
app/srv/exports.d.ts vendored
View File

@ -1,5 +1,11 @@
/// <reference types="node" />
declare module "api/auth/login" {
declare module "app/srv/api/npm-size" {
export const _: {
url: string;
api(mode: "site" | "page", id: string): Promise<string>;
};
}
declare module "app/srv/api/auth/login" {
export const _: {
url: string;
api(username: string, password: string): Promise<{
@ -13,13 +19,13 @@ declare module "api/auth/login" {
}>;
};
}
declare module "api/session" {
declare module "app/srv/api/session" {
export const _: {
url: string;
api(): Promise<any>;
};
}
declare module "global" {
declare module "app/srv/global" {
import { site, user } from "dbgen";
import { ExecaChildProcess } from "execa";
export const glb: {
@ -45,46 +51,602 @@ declare module "global" {
};
};
}
declare module "api/npm" {
declare module "app/srv/api/npm" {
export const _: {
url: string;
api(mode: "site" | "page", id: string): Promise<void>;
};
}
declare module "api/site-dts" {
declare module "app/web/src/utils/types/ws" {
export type WS_MSG = WS_MSG_GET_COMP | WS_MSG_SET_COMP | WS_MSG_GET_PAGE | WS_MSG_SET_PAGE | WS_MSG_SV_LOCAL | WS_MSG_SVDIFF_REMOTE | WS_MSG_DIFF_LOCAL | WS_MSG_UNDO | WS_MSG_REDO | WS_MSG_NEW_COMP | WS_SITE_JS | {
type: "ping";
} | {
type: "pong";
};
export type WS_SITE_JS = {
type: "site-js";
id_site: string;
src: string;
};
export type WS_MSG_GET_COMP = {
type: "get_comp";
comp_id: string;
};
export type WS_MSG_SET_COMP = {
type: "set_comp";
comp_id: string;
changes: string;
};
export type WS_MSG_GET_PAGE = {
type: "get_page";
page_id: string;
};
export type WS_MSG_SET_PAGE = {
type: "set_page";
changes: string;
};
export type WS_MSG_NEW_COMP = {
type: "new_comp";
id: string;
doc: string;
};
export type WS_MSG_UNDO = {
type: "undo";
mode: "page" | "site" | "comp";
id: string;
};
export type WS_MSG_REDO = {
type: "redo";
mode: "page" | "site" | "comp";
id: string;
};
export type WS_MSG_SV_LOCAL = {
type: "sv_local";
mode: "page" | "site" | "comp";
id: string;
sv_local: string;
};
export type WS_MSG_SVDIFF_REMOTE = {
type: "svd_remote";
mode: "page" | "site" | "comp";
id: string;
sv_remote: string;
diff_remote: string;
};
export type WS_MSG_DIFF_LOCAL = {
type: "diff_local";
mode: "page" | "site" | "comp";
id: string;
diff_local: string;
};
}
declare module "app/web/src/utils/types/meta-fn" {
import { TypedMap } from "yjs-types";
import { IItem, MItem } from "app/web/src/utils/types/item";
import * as Y from "yjs";
export type FNLayout = {
dir: "row" | "col" | "row-reverse" | "col-reverse";
align: FNAlign;
gap: number | "auto";
wrap: undefined | "flex-wrap" | "flex-nowrap";
};
export type FMLayout = TypedMap<FNLayout>;
export type FNAdv = {
js?: Y.Text | string;
jsBuilt?: string;
css?: Y.Text | string;
html?: Y.Text | string;
};
export type FMAdv = TypedMap<FNAdv>;
export type FNComponent = {
id: string;
name: string;
updated_at?: number;
props: Record<string, FNCompDef>;
};
export type FNCompDef = {
idx: number;
type: string;
value: any;
valueBuilt: any;
gen?: string;
genBuilt?: string;
content?: IItem;
visible?: string;
meta?: FNCompMeta;
};
type FNCompMeta = {
type: "text" | "option" | "content-element";
options?: string;
optionsBuilt?: string;
option_mode?: "dropdown" | "button";
};
export type FMCompDef = TypedMap<Omit<FNCompDef, "meta" | "content"> & {
content: MItem;
meta: TypedMap<FNCompMeta>;
}>;
export type FMComponent = TypedMap<Omit<FNComponent, "group" | "props"> & {
props: TypedMap<Record<string, FMCompDef>>;
}>;
export type FNAlign = "top-left" | "top-center" | "top-right" | "top" | "left" | "center" | "right" | "bottom" | "bottom-left" | "bottom-center" | "bottom-right" | "stretch";
export type FNPadding = {
t?: number;
b?: number;
l?: number;
r?: number;
};
export type FMPadding = TypedMap<FNPadding>;
export type FNDimension = {
w?: number | "fit" | "full";
h?: number | "fit" | "full";
wUnit?: "px" | "%";
hUnit?: "px" | "%";
proportion?: boolean;
};
export type FMDimension = TypedMap<FNDimension>;
export type FNBackground = {
color?: string;
url?: string;
size?: "cover" | "contain" | "full" | "auto" | "%" | "px";
repeat?: "repeat" | "repeat-x" | "repeat-y" | "space" | "round" | "no-repeat";
pos?: "top" | "left" | "center" | "bottom" | "right";
};
export type FMBackground = TypedMap<FNBackground>;
export type FNBorder = {
style?: "solid" | "dash";
stroke?: FNBorderCorner;
rounded?: FNRounded;
color?: string;
};
export type FNBorderCorner = {
t?: number;
b?: number;
l?: number;
r?: number;
};
export type FNRounded = {
tr?: number;
tl?: number;
bl?: number;
br?: number;
};
export type FMBorder = TypedMap<FNBorder>;
export type FNFont = {
color?: string;
size?: number;
family?: string;
height?: number | "auto";
align?: "center" | "left" | "right";
whitespace?: "whitespace-normal" | "whitespace-nowrap" | "whitespace-pre" | "whitespace-pre-line" | "whitespace-pre-wrap" | "whitespace-break-spaces";
wordBreak?: "break-normal" | "break-words" | "break-all" | "break-keep";
};
export type FMFont = TypedMap<FNFont>;
export type FNLinkTag = {
tag?: string;
link?: string;
class?: string;
};
export type FMLinkTag = TypedMap<FNLinkTag>;
}
declare module "app/web/src/utils/types/meta" {
import { FMAdv, FMBackground, FMBorder, FMComponent, FMDimension, FMFont, FMLayout, FMLinkTag, FMPadding, FNBackground, FNBorder, FNDimension, FNFont, FNPadding } from "app/web/src/utils/types/meta-fn";
export type MetaItem = {
id: string;
originalId?: string;
type: "text" | "section" | "item";
name: string;
field?: string;
html?: string;
text?: string;
hidden?: "only-editor" | "all" | false;
};
export type BasicItem = {
padding?: FNPadding;
bg?: FNBackground;
font?: FNFont;
dim?: FNDimension;
border?: FNBorder;
};
export type MBasicItem = {
padding?: FMPadding;
bg?: FMBackground;
font?: FMFont;
component?: FMComponent;
dim?: FMDimension;
layout?: FMLayout;
linktag?: FMLinkTag;
adv?: FMAdv;
border?: FMBorder;
};
}
declare module "app/web/src/utils/types/root" {
import { TypedArray, TypedMap } from "yjs-types";
import { ISection } from "app/web/src/utils/types/section";
export type IRoot = {
id: "root";
type: "root";
id_page: string;
childs: ISection[];
};
export type MRoot = TypedMap<{
id: "root";
type: "root";
childs: TypedArray<ISection>;
}>;
}
declare module "app/web/src/utils/types/section" {
import { TypedArray, TypedMap } from "yjs-types";
import { IItem, MItem } from "app/web/src/utils/types/item";
import { BasicItem, MBasicItem, MetaItem } from "app/web/src/utils/types/meta";
import { FNAdv, FNLayout, FNLinkTag } from "app/web/src/utils/types/meta-fn";
import { MRoot } from "app/web/src/utils/types/root";
export type ISection = {
layout?: FNLayout;
mobile?: ISection;
linktag?: FNLinkTag;
adv?: FNAdv;
type: "section";
childs: IItem[];
} & MetaItem & BasicItem;
export type MSection = TypedMap<{
mobile?: MSection;
type: "section";
childs?: TypedArray<MItem>;
} & MBasicItem & MetaItem> & {
parent: TypedArray<MSection> & {
parent: MRoot;
};
};
}
declare module "app/web/src/utils/types/text" {
import { TypedArray, TypedMap } from "yjs-types";
import { BasicItem, MBasicItem, MetaItem } from "app/web/src/utils/types/meta";
import { FNAdv, FNLayout, FNLinkTag } from "app/web/src/utils/types/meta-fn";
import { MItem } from "app/web/src/utils/types/item";
export type IText = {
mobile?: IText;
type: "text";
layout?: FNLayout;
linktag?: FNLinkTag;
text: string;
html: string;
adv?: FNAdv;
} & BasicItem & MetaItem;
export type MText = TypedMap<{
type: "text";
mobile?: MText;
childs?: TypedArray<void>;
} & MBasicItem & MetaItem> & {
parent: TypedArray<MItem> & {
parent: MItem;
};
};
}
declare module "app/web/src/utils/types/item" {
import { TypedArray, TypedMap } from "yjs-types";
import { BasicItem, MBasicItem, MetaItem } from "app/web/src/utils/types/meta";
import { FNAdv, FNComponent, FNLayout, FNLinkTag } from "app/web/src/utils/types/meta-fn";
import { MSection } from "app/web/src/utils/types/section";
import { IText, MText } from "app/web/src/utils/types/text";
export type IItem = {
layout?: FNLayout;
linktag?: FNLinkTag;
mobile?: IItem;
adv?: FNAdv;
type: "item";
component?: FNComponent;
childs: (IItem | IText)[];
} & MetaItem & BasicItem;
export type MItem = TypedMap<{
type: "item";
mobile?: MItem;
childs?: TypedArray<MItem | MText>;
} & MBasicItem & MetaItem> & {
parent: TypedArray<MSection | MItem> & {
parent: MSection | MItem;
};
};
}
declare module "app/web/src/utils/types/general" {
import { page as dbpage } from "dbgen";
import { TypedDoc, TypedMap } from "yjs-types";
import { IItem, MItem } from "app/web/src/utils/types/item";
import { IRoot, MRoot } from "app/web/src/utils/types/root";
import { ISection, MSection } from "app/web/src/utils/types/section";
import { IText, MText } from "app/web/src/utils/types/text";
export type PageProps = {
pathname: string;
domain: string;
params: any;
};
export type PrasiAPI = {
apiEntry: any;
prismaTypes: {
"prisma.d.ts": string;
"runtime/library.d.ts": string;
"runtime/index.d.ts": string;
};
apiTypes: string;
};
export const w: {
isEditor: boolean;
isMobile: boolean;
isDesktop: boolean;
prasiApi: Record<string, PrasiAPI>;
loadedFonts: string[];
prasiApiDbPull: boolean;
params: any;
editorGlbDefault: string;
ts: number;
serverurl: string;
api: any;
db: any;
};
export type Page = {
id: string;
content_tree: IRoot;
js: string | null;
js_compiled: string | null;
};
export type MPage = TypedDoc<{
map: TypedMap<Omit<dbpage, "content_tree" | "updated_at"> & {
content_tree: MRoot;
updated_at: string;
}>;
}>;
export type IContent = ISection | IItem | IText;
export type MContent = MSection | MItem | MText;
export type RenderContentProp = Partial<{
active: IContent | null;
hover: IContent | null;
update: (updateID: string, name: string, newState: IRoot) => void;
onHover: (e: React.MouseEvent, item: IContent) => Promise<void>;
onOut: (e: React.MouseEvent, item: IContent) => Promise<void>;
onClick: (e: React.MouseEvent, item: IContent) => Promise<void>;
isEditor: boolean;
setContent: (item: IContent) => Promise<void>;
_onlyChildren?: true;
}>;
export type ERenderProp<ITEM> = {
item: ITEM;
};
}
declare module "app/srv/ws/edit/tools/load-page" {
import { Page } from "app/web/src/utils/types/general";
export const loadPage: (page_id: string) => Promise<Page>;
}
declare module "app/srv/ws/edit/action/get-page" {
import { WSData } from "pkgs/core/server/create";
import { WS_MSG_GET_PAGE } from "app/web/src/utils/types/ws";
export const getPage: (ws: ServerWebSocket<WSData>, msg: WS_MSG_GET_PAGE) => Promise<void>;
}
declare module "app/srv/ws/edit/action/get-comp" {
import { WSData } from "pkgs/core/server/create";
import { WS_MSG_GET_COMP } from "app/web/src/utils/types/ws";
export const getComp: (ws: ServerWebSocket<WSData>, msg: WS_MSG_GET_COMP) => Promise<void>;
}
declare module "app/srv/ws/edit/action/sv-local" {
export const svLocal: (ws: Websocket, msg: WS_MSG_SV_LOCAL) => Promise<void>;
}
declare module "app/srv/ws/edit/action/diff-local" {
export const diffLocal: (ws: Websocket, msg: any) => Promise<void>;
}
declare module "app/srv/ws/edit/action/svdiff-remote" {
export const svdiffRemote: (ws: Websocket, msg: WS_MSG_SVDIFF_REMOTE) => Promise<void>;
}
declare module "app/srv/ws/edit/action/undo-redo" {
export const undo: (ws: Websocket, msg: WS_MSG_UNDO) => void;
export const redo: (ws: Websocket, msg: WS_MSG_REDO) => void;
}
declare module "app/srv/ws/handler" {
import { WebSocketHandler } from "bun";
import { WSData } from "pkgs/core/server/create";
export const wsHandler: Record<string, WebSocketHandler<WSData>>;
}
declare module "pkgs/core/utils/dir" {
export const dir: {
path: (path: string) => string;
};
}
declare module "app/db/db" {
}
declare module "pkgs/core/utils/global" {
import { Logger } from "pino";
import { RadixRouter } from "radix3";
type SingleRoute = {
url: string;
args: string[];
fn: (...arg: any[]) => Promise<any>;
path: string;
};
export const g: {
status: "init" | "ready";
datadir: string;
dburl: string;
mode: "dev" | "prod";
log: Logger;
api: Record<string, SingleRoute>;
domains: null | Record<string, string>;
router: RadixRouter<SingleRoute>;
port: number;
frm: {
js: string;
etag: string;
};
parcel: Subprocess;
};
}
declare module "pkgs/core/server/api-ctx" {
export const apiContext: (ctx: any) => {
mode: any;
req: Request & {
params: any;
query_parameters: any;
};
res: Response & {
send: (body?: string | object) => void;
setHeader: (key: string, value: string) => void;
sendStatus: (code: number) => void;
};
};
export const createResponse: (existingRes: any, body: any) => Response;
}
declare module "pkgs/core/server/serve-api" {
export const serveAPI: (url: URL, req: Request) => Promise<Response>;
}
declare module "pkgs/core/server/create" {
export type WSData = {
url: URL;
};
export const createServer: () => Promise<void>;
}
declare module "app/srv/ws/edit/tools/load-site" {
export type SiteConfig = {
api_url?: string;
prasi?: {
port: number;
dburl: string;
};
};
export type Site = Exclude<Awaited<ReturnType<typeof loadSite>>, null>;
export const loadSite: (idOrDomain: string) => Promise<Omit<site, "config"> & {
config?: SiteConfig;
page: {
id: string;
url: string;
updated_at: Date | null;
name: string;
}[];
}>;
}
declare module "app/srv/ws/edit/edit-global" {
import { ServerWebSocket } from "bun";
import { component } from "dbgen";
import { UndoManager } from "yjs";
import { TypedArray, TypedDoc, TypedMap } from "yjs-types";
import type { WSData } from "pkgs/core/server/create";
import { IItem } from "app/web/src/utils/types/item";
import { IRoot } from "app/web/src/utils/types/root";
import { Site } from "app/srv/ws/edit/tools/load-site";
import { MPage } from "app/web/src/utils/types/general";
import type { RadixRouter } from "radix3";
type ArrayElement<ArrayType extends readonly unknown[]> = ArrayType extends readonly (infer ElementType)[] ? ElementType : never;
export type SingleComp = {
id: string;
doc: TypedDoc<{
map: TypedMap<component & {
content_tree: TypedMap<IItem>;
}>;
}>;
undoManager: UndoManager;
saveTimeout?: ReturnType<typeof setTimeout>;
ws: Set<ServerWebSocket<WSData>>;
};
export const eg: {
cache: Record<string, Record<string, {
id: string;
js: string | null;
url: string;
js_compiled: string | null;
content_tree: IRoot;
lastRefresh: number;
}>>;
router: Record<string, RadixRouter<{
id: string;
url: string;
}>>;
edit: {
site: Record<string, {
id: string;
doc: TypedDoc<{
site: TypedMap<Site & {
page: TypedArray<ArrayElement<Site["page"]>>;
}>;
}>;
undoManager: UndoManager;
saveTimeout?: ReturnType<typeof setTimeout>;
ws: Set<ServerWebSocket<WSData>>;
}>;
comp: Record<string, SingleComp>;
page: Record<string, {
id: string;
doc: MPage;
undoManager: UndoManager;
saveTimeout?: ReturnType<typeof setTimeout>;
ws: Set<ServerWebSocket<WSData>>;
}>;
ws: WeakMap<ServerWebSocket<WSData>, {
clientID: string;
}>;
};
};
}
declare module "app/srv/api/npm-bundle" {
export type NPMImportAs = {
main: {
mode: "default" | "*";
name: string;
};
names: string[];
custom?: string;
};
export const _: {
url: string;
api(mode: "site" | "page", id: string): Promise<any>;
};
}
declare module "app/srv/api/site-dts" {
export const _: {
url: string;
api(site_id: string): Promise<string>;
};
}
declare module "exports" {
declare module "app/srv/exports" {
export const npm_size: {
name: string;
url: string;
path: string;
args: string[];
handler: Promise<typeof import("app/srv/api/npm-size")>;
};
export const login: {
name: string;
url: string;
path: string;
args: string[];
handler: Promise<typeof import("api/auth/login")>;
handler: Promise<typeof import("app/srv/api/auth/login")>;
};
export const session: {
name: string;
url: string;
path: string;
args: any[];
handler: Promise<typeof import("api/session")>;
handler: Promise<typeof import("app/srv/api/session")>;
};
export const npm: {
name: string;
url: string;
path: string;
args: string[];
handler: Promise<typeof import("api/npm")>;
handler: Promise<typeof import("app/srv/api/npm")>;
};
export const npm_bundle: {
name: string;
url: string;
path: string;
args: string[];
handler: Promise<typeof import("app/srv/api/npm-bundle")>;
};
export const site_dts: {
name: string;
url: string;
path: string;
args: string[];
handler: Promise<typeof import("api/site-dts")>;
handler: Promise<typeof import("app/srv/api/site-dts")>;
};
export const _upload: {
name: string;

View File

@ -1,3 +1,10 @@
export const npm_size = {
name: "npm_size",
url: "/npm-size/:mode/:id",
path: "app/srv/api/npm-size.ts",
args: ["mode","id"],
handler: import("./api/npm-size")
}
export const login = {
name: "login",
url: "/_login",
@ -19,6 +26,13 @@ export const npm = {
args: ["mode","id"],
handler: import("./api/npm")
}
export const npm_bundle = {
name: "npm_bundle",
url: "/npm-bundle/:mode/:id",
path: "app/srv/api/npm-bundle.ts",
args: ["mode","id"],
handler: import("./api/npm-bundle")
}
export const site_dts = {
name: "site_dts",
url: "/site-dts/:site_id",

View File

@ -1,9 +1,12 @@
{
"name": "srv",
"dependencies": {
"@fal-works/esbuild-plugin-global-externals": "^2.1.2",
"@hyrious/esbuild-plugin-style": "^0.3.5",
"@node-rs/argon2": "^1.5.2",
"@paralleldrive/cuid2": "^2.2.2",
"@types/mime-types": "^2.1.2",
"esbuild": "^0.19.4",
"lz-string": "^1.5.0",
"mime-types": "^2.1.35",
"radix3": "^1.1.0"

View File

@ -33,8 +33,7 @@ export default page({
let e = await api.session();
if (!e) {
(window as any).redirectTo = location.pathname;
console.log("session not found");
// navigate("/login");
navigate("/login");
localStorage.removeItem("prasi-session");
} else {
localStorage.setItem("prasi-session", JSON.stringify(e));

View File

@ -38,8 +38,7 @@ export default page({
let e = await api.session();
if (!e) {
(window as any).redirectTo = location.pathname;
console.log("session not found");
// navigate("/login");
navigate("/login");
localStorage.removeItem("prasi-session");
} else {
localStorage.setItem("prasi-session", JSON.stringify(e));

View File

@ -22,6 +22,7 @@ export const SiteManager = () => {
});
const reloadSites = async () => {
const orgs = await db.org_user.findMany({
where: {
id_user: p.session.data.user.id,

View File

@ -6,6 +6,7 @@ export const LItem: FC<{
id: string;
fromProp?: boolean;
}> = ({ id, fromProp }) => {
return (
<LRender id={id} fromProp={fromProp}>
{(childs) => {

View File

@ -65,5 +65,9 @@ export const mobileCSS = css`
linear-gradient(-45deg, transparent 75%, #fafafa 75%);
background-size: 20px 20px;
background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
background-position:
0 0,
0 10px,
10px -10px,
-10px 0px;
`;

View File

@ -51,6 +51,7 @@ export const treeScopeEval = (
}
}
}
const output = { jsx: null as any };
args = {
...w.exports,
@ -86,7 +87,9 @@ export const treeScopeEval = (
console.warn(`Available var:`, args, `\n\n`);
});
}
} catch (e) {}
} catch (e) {
console.error(e);
}
return output.jsx;
} catch (e) {

View File

@ -2,6 +2,8 @@ import { manifest, version } from "@parcel/service-worker";
const g = {
cache: null as null | Cache,
dev: false,
baseUrl: "",
};
async function install() {
@ -22,27 +24,34 @@ addEventListener("activate", (e) =>
addEventListener("fetch", async (evt) => {
const e = evt as FetchEvent;
if (g.baseUrl) {
const url = e.request.url;
if (url.startsWith(g.baseUrl)) {
return;
}
}
e.respondWith(
(async () => {
if (!g.cache) {
g.cache = await caches.open(version);
}
if (!g.baseUrl) {
const keys = await g.cache.keys();
const url = new URL(keys[0].url);
url.pathname = "";
g.baseUrl = url.toString();
}
const cache = g.cache;
const r = await cache.match(e.request);
if (r) {
cache.add(e.request);
return r;
}
const url = new URL(e.request.url);
const res = await fetch(e.request);
if (
url.pathname.includes("_api_frm") ||
url.pathname.startsWith("/_prasi")
) {
await cache.put(e.request, res);
}
return res;
return await fetch(e.request.url);
})()
);
});

BIN
bun.lockb

Binary file not shown.

View File

@ -51,8 +51,15 @@ export const createResponse = (existingRes: any, body: any) => {
const status =
typeof existingRes._status === "number" ? existingRes._status : undefined;
let finalBody = body;
if (body instanceof Buffer) {
} else {
finalBody =
typeof body === "string" ? body : JSON.stringify(body, replacer);
}
let res = new Response(
typeof body === "string" ? body : JSON.stringify(body, replacer),
finalBody,
status
? {
status,
@ -61,12 +68,14 @@ export const createResponse = (existingRes: any, body: any) => {
);
if (typeof body === "object") {
res.headers.append("content-type", "application/json");
if (!res.headers.get("content-type")) {
res.headers.set("content-type", "application/json");
}
}
const cur = existingRes as Response;
for (const [key, value] of cur.headers.entries()) {
res.headers.append(key, value);
res.headers.set(key, value);
}
return res;

View File

@ -74,6 +74,20 @@ export const serveAPI = async (url: URL, req: Request) => {
if (finalResponse) {
return createResponse(current.res, finalResponse);
}
if (
(current.res as any)._status &&
(current.res as any)._status !== current.res.status
) {
const res = new Response(current.res.body, {
status: (current.res as any)._status,
});
current.res.headers.forEach((v, k) => {
res.headers.set(k, v);
});
return res;
}
return current.res;
}

View File

@ -4,7 +4,7 @@ declare global {
const navigate: (path: string) => void;
const params: any;
const css: typeof goober.css;
const cx: (...arg: string[]) => string;
const cx: (...arg: any[]) => string;
const api: any;
const db: PrismaClient;
const prasiContext: any;