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 { 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: {} };
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ export const LItem: FC<{
|
|||
id: string;
|
||||
fromProp?: boolean;
|
||||
}> = ({ id, fromProp }) => {
|
||||
|
||||
return (
|
||||
<LRender id={id} fromProp={fromProp}>
|
||||
{(childs) => {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
`;
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
})()
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue