fix server content-type
This commit is contained in:
parent
f894e70c69
commit
cbab0edec2
|
|
@ -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 "-";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
@ -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 "-";
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
@ -4,14 +4,13 @@ import { readAsync } from "fs-jetpack";
|
||||||
import mime from "mime-types";
|
import mime from "mime-types";
|
||||||
import { apiContext } from "service-srv";
|
import { apiContext } from "service-srv";
|
||||||
import { glb } from "../global";
|
import { glb } from "../global";
|
||||||
|
import { g } from "utils/global";
|
||||||
|
|
||||||
export const _ = {
|
export const _ = {
|
||||||
url: "/npm/:mode/:id/*",
|
url: "/npm/:mode/:id/*",
|
||||||
async api(mode: "site" | "page", id: string) {
|
async api(mode: "site" | "page", id: string) {
|
||||||
const { req, res, mode: _mode } = apiContext(this);
|
const { req, res, mode: _mode } = apiContext(this);
|
||||||
let path = dir.path(`../npm/${mode}/${id}/${req.params._}`);
|
let path = dir.path(`${g.datadir}/npm/${mode}/${id}/${req.params._}`);
|
||||||
|
|
||||||
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
||||||
|
|
||||||
if (!glb.npm) {
|
if (!glb.npm) {
|
||||||
glb.npm = { page: {}, site: {} };
|
glb.npm = { page: {}, site: {} };
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,11 @@
|
||||||
/// <reference types="node" />
|
/// <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 _: {
|
export const _: {
|
||||||
url: string;
|
url: string;
|
||||||
api(username: string, password: string): Promise<{
|
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 _: {
|
export const _: {
|
||||||
url: string;
|
url: string;
|
||||||
api(): Promise<any>;
|
api(): Promise<any>;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
declare module "global" {
|
declare module "app/srv/global" {
|
||||||
import { site, user } from "dbgen";
|
import { site, user } from "dbgen";
|
||||||
import { ExecaChildProcess } from "execa";
|
import { ExecaChildProcess } from "execa";
|
||||||
export const glb: {
|
export const glb: {
|
||||||
|
|
@ -45,46 +51,602 @@ declare module "global" {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
declare module "api/npm" {
|
declare module "app/srv/api/npm" {
|
||||||
export const _: {
|
export const _: {
|
||||||
url: string;
|
url: string;
|
||||||
api(mode: "site" | "page", id: string): Promise<void>;
|
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 _: {
|
export const _: {
|
||||||
url: string;
|
url: string;
|
||||||
api(site_id: string): Promise<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: {
|
export const login: {
|
||||||
name: string;
|
name: string;
|
||||||
url: string;
|
url: string;
|
||||||
path: string;
|
path: string;
|
||||||
args: string[];
|
args: string[];
|
||||||
handler: Promise<typeof import("api/auth/login")>;
|
handler: Promise<typeof import("app/srv/api/auth/login")>;
|
||||||
};
|
};
|
||||||
export const session: {
|
export const session: {
|
||||||
name: string;
|
name: string;
|
||||||
url: string;
|
url: string;
|
||||||
path: string;
|
path: string;
|
||||||
args: any[];
|
args: any[];
|
||||||
handler: Promise<typeof import("api/session")>;
|
handler: Promise<typeof import("app/srv/api/session")>;
|
||||||
};
|
};
|
||||||
export const npm: {
|
export const npm: {
|
||||||
name: string;
|
name: string;
|
||||||
url: string;
|
url: string;
|
||||||
path: string;
|
path: string;
|
||||||
args: 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: {
|
export const site_dts: {
|
||||||
name: string;
|
name: string;
|
||||||
url: string;
|
url: string;
|
||||||
path: string;
|
path: string;
|
||||||
args: string[];
|
args: string[];
|
||||||
handler: Promise<typeof import("api/site-dts")>;
|
handler: Promise<typeof import("app/srv/api/site-dts")>;
|
||||||
};
|
};
|
||||||
export const _upload: {
|
export const _upload: {
|
||||||
name: string;
|
name: string;
|
||||||
|
|
|
||||||
|
|
@ -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 = {
|
export const login = {
|
||||||
name: "login",
|
name: "login",
|
||||||
url: "/_login",
|
url: "/_login",
|
||||||
|
|
@ -19,6 +26,13 @@ export const npm = {
|
||||||
args: ["mode","id"],
|
args: ["mode","id"],
|
||||||
handler: import("./api/npm")
|
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 = {
|
export const site_dts = {
|
||||||
name: "site_dts",
|
name: "site_dts",
|
||||||
url: "/site-dts/:site_id",
|
url: "/site-dts/:site_id",
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "srv",
|
"name": "srv",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@fal-works/esbuild-plugin-global-externals": "^2.1.2",
|
||||||
|
"@hyrious/esbuild-plugin-style": "^0.3.5",
|
||||||
"@node-rs/argon2": "^1.5.2",
|
"@node-rs/argon2": "^1.5.2",
|
||||||
"@paralleldrive/cuid2": "^2.2.2",
|
"@paralleldrive/cuid2": "^2.2.2",
|
||||||
"@types/mime-types": "^2.1.2",
|
"@types/mime-types": "^2.1.2",
|
||||||
|
"esbuild": "^0.19.4",
|
||||||
"lz-string": "^1.5.0",
|
"lz-string": "^1.5.0",
|
||||||
"mime-types": "^2.1.35",
|
"mime-types": "^2.1.35",
|
||||||
"radix3": "^1.1.0"
|
"radix3": "^1.1.0"
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,7 @@ export default page({
|
||||||
let e = await api.session();
|
let e = await api.session();
|
||||||
if (!e) {
|
if (!e) {
|
||||||
(window as any).redirectTo = location.pathname;
|
(window as any).redirectTo = location.pathname;
|
||||||
console.log("session not found");
|
navigate("/login");
|
||||||
// navigate("/login");
|
|
||||||
localStorage.removeItem("prasi-session");
|
localStorage.removeItem("prasi-session");
|
||||||
} else {
|
} else {
|
||||||
localStorage.setItem("prasi-session", JSON.stringify(e));
|
localStorage.setItem("prasi-session", JSON.stringify(e));
|
||||||
|
|
|
||||||
|
|
@ -38,8 +38,7 @@ export default page({
|
||||||
let e = await api.session();
|
let e = await api.session();
|
||||||
if (!e) {
|
if (!e) {
|
||||||
(window as any).redirectTo = location.pathname;
|
(window as any).redirectTo = location.pathname;
|
||||||
console.log("session not found");
|
navigate("/login");
|
||||||
// navigate("/login");
|
|
||||||
localStorage.removeItem("prasi-session");
|
localStorage.removeItem("prasi-session");
|
||||||
} else {
|
} else {
|
||||||
localStorage.setItem("prasi-session", JSON.stringify(e));
|
localStorage.setItem("prasi-session", JSON.stringify(e));
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ export const SiteManager = () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const reloadSites = async () => {
|
const reloadSites = async () => {
|
||||||
|
|
||||||
const orgs = await db.org_user.findMany({
|
const orgs = await db.org_user.findMany({
|
||||||
where: {
|
where: {
|
||||||
id_user: p.session.data.user.id,
|
id_user: p.session.data.user.id,
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ export const LItem: FC<{
|
||||||
id: string;
|
id: string;
|
||||||
fromProp?: boolean;
|
fromProp?: boolean;
|
||||||
}> = ({ id, fromProp }) => {
|
}> = ({ id, fromProp }) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LRender id={id} fromProp={fromProp}>
|
<LRender id={id} fromProp={fromProp}>
|
||||||
{(childs) => {
|
{(childs) => {
|
||||||
|
|
|
||||||
|
|
@ -65,5 +65,9 @@ export const mobileCSS = css`
|
||||||
linear-gradient(-45deg, transparent 75%, #fafafa 75%);
|
linear-gradient(-45deg, transparent 75%, #fafafa 75%);
|
||||||
|
|
||||||
background-size: 20px 20px;
|
background-size: 20px 20px;
|
||||||
background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
|
background-position:
|
||||||
|
0 0,
|
||||||
|
0 10px,
|
||||||
|
10px -10px,
|
||||||
|
-10px 0px;
|
||||||
`;
|
`;
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,7 @@ export const treeScopeEval = (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const output = { jsx: null as any };
|
const output = { jsx: null as any };
|
||||||
args = {
|
args = {
|
||||||
...w.exports,
|
...w.exports,
|
||||||
|
|
@ -86,7 +87,9 @@ export const treeScopeEval = (
|
||||||
console.warn(`Available var:`, args, `\n\n`);
|
console.warn(`Available var:`, args, `\n\n`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (e) {}
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
|
||||||
return output.jsx;
|
return output.jsx;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ import { manifest, version } from "@parcel/service-worker";
|
||||||
|
|
||||||
const g = {
|
const g = {
|
||||||
cache: null as null | Cache,
|
cache: null as null | Cache,
|
||||||
|
dev: false,
|
||||||
|
baseUrl: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
async function install() {
|
async function install() {
|
||||||
|
|
@ -22,27 +24,34 @@ addEventListener("activate", (e) =>
|
||||||
addEventListener("fetch", async (evt) => {
|
addEventListener("fetch", async (evt) => {
|
||||||
const e = evt as FetchEvent;
|
const e = evt as FetchEvent;
|
||||||
|
|
||||||
|
if (g.baseUrl) {
|
||||||
|
const url = e.request.url;
|
||||||
|
if (url.startsWith(g.baseUrl)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
e.respondWith(
|
e.respondWith(
|
||||||
(async () => {
|
(async () => {
|
||||||
if (!g.cache) {
|
if (!g.cache) {
|
||||||
g.cache = await caches.open(version);
|
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 cache = g.cache;
|
||||||
|
|
||||||
const r = await cache.match(e.request);
|
const r = await cache.match(e.request);
|
||||||
if (r) {
|
if (r) {
|
||||||
|
cache.add(e.request);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
const url = new URL(e.request.url);
|
return await fetch(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;
|
|
||||||
})()
|
})()
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -51,8 +51,15 @@ export const createResponse = (existingRes: any, body: any) => {
|
||||||
const status =
|
const status =
|
||||||
typeof existingRes._status === "number" ? existingRes._status : undefined;
|
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(
|
let res = new Response(
|
||||||
typeof body === "string" ? body : JSON.stringify(body, replacer),
|
finalBody,
|
||||||
status
|
status
|
||||||
? {
|
? {
|
||||||
status,
|
status,
|
||||||
|
|
@ -61,12 +68,14 @@ export const createResponse = (existingRes: any, body: any) => {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (typeof body === "object") {
|
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;
|
const cur = existingRes as Response;
|
||||||
for (const [key, value] of cur.headers.entries()) {
|
for (const [key, value] of cur.headers.entries()) {
|
||||||
res.headers.append(key, value);
|
res.headers.set(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,20 @@ export const serveAPI = async (url: URL, req: Request) => {
|
||||||
if (finalResponse) {
|
if (finalResponse) {
|
||||||
return createResponse(current.res, 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;
|
return current.res;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ declare global {
|
||||||
const navigate: (path: string) => void;
|
const navigate: (path: string) => void;
|
||||||
const params: any;
|
const params: any;
|
||||||
const css: typeof goober.css;
|
const css: typeof goober.css;
|
||||||
const cx: (...arg: string[]) => string;
|
const cx: (...arg: any[]) => string;
|
||||||
const api: any;
|
const api: any;
|
||||||
const db: PrismaClient;
|
const db: PrismaClient;
|
||||||
const prasiContext: any;
|
const prasiContext: any;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue