diff --git a/app/srv/api/npm.ts b/app/srv/api/npm.ts new file mode 100644 index 00000000..32384d81 --- /dev/null +++ b/app/srv/api/npm.ts @@ -0,0 +1,83 @@ +import crypto from "crypto"; +import { dir } from "dir"; +import { readAsync } from "fs-jetpack"; +import mime from "mime-types"; +import { apiContext } from "service-srv"; +import { glb } from "../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", "*"); + + if (!glb.npm) { + glb.npm = { page: {}, site: {} }; + } + + const contentType = mime.lookup(path); + if (contentType) res.setHeader("content-type", contentType); + + if (path.endsWith(`${mode}.js`)) { + path = path.substring(0, path.length - `${mode}.js`.length) + `index.js`; + + if (glb.npm[mode][id]) { + const npm = glb.npm[mode][id]; + if (npm) { + res.setHeader("etag", npm.etag); + res.setHeader("content-length", npm.file.byteLength.toString()); + + if (npm.etag === req.headers.get("if-none-match")) { + res.sendStatus(304); + return; + } + + res.send(npm.file); + + readAsync(path, "buffer").then((file) => { + if (file && path.endsWith("index.js")) { + glb.npm[mode][id] = { + file, + etag: crypto.createHash("md5").update(file).digest("hex"), + }; + } + }); + return; + } + } + } + + if (path.length > dir.path(`../npm/${mode}/${id}`).length) { + const file = await readAsync(path, "buffer"); + + if (file) { + if (path.endsWith("index.js")) { + glb.npm[mode][id] = { + file, + etag: crypto.createHash("md5").update(file).digest("hex"), + }; + const npm = glb.npm[mode][id]; + if (npm) { + res.setHeader("etag", npm.etag); + + if (npm.etag === req.headers.get("if-none-match")) { + res.sendStatus(304); + return; + } + } + } + + res.setHeader("content-length", file.byteLength.toString()); + res.send(file); + return; + } else { + glb.npm[mode][id] = null; + } + } + res.setHeader("etag", "empty"); + + res.send(""); + }, +}; diff --git a/app/srv/exports.d.ts b/app/srv/exports.d.ts index b8cd9aaa..c6129284 100644 --- a/app/srv/exports.d.ts +++ b/app/srv/exports.d.ts @@ -1,3 +1,4 @@ +/// declare module "api/auth/login" { export const _: { url: string; @@ -18,6 +19,38 @@ declare module "api/session" { api(): Promise; }; } +declare module "global" { + import { site, user } from "dbgen"; + import { ExecaChildProcess } from "execa"; + export const glb: { + lastUpdate: Record; + prasiSrv: { + status: Record; + running: Record; + }; + npm: { + page: Record; + site: Record; + }; + }; + export type Session = { + user: user & { + site: site[]; + }; + }; +} +declare module "api/npm" { + export const _: { + url: string; + api(mode: "site" | "page", id: string): Promise; + }; +} declare module "exports" { export const login: { name: string; @@ -33,12 +66,12 @@ declare module "exports" { args: any[]; handler: Promise; }; - export const _web: { + export const npm: { name: string; url: string; path: string; args: string[]; - handler: Promise; + handler: Promise; }; export const _upload: { name: string; diff --git a/app/srv/exports.ts b/app/srv/exports.ts index 1522ea0e..aeef854d 100644 --- a/app/srv/exports.ts +++ b/app/srv/exports.ts @@ -12,12 +12,12 @@ export const session = { args: [], handler: import("./api/session") } -export const _web = { - name: "_web", - url: "/_web/:id/**", - path: "app/srv/api/_web.ts", - args: ["id","_"], - handler: import("./api/_web") +export const npm = { + name: "npm", + url: "/npm/:mode/:id/*", + path: "app/srv/api/npm.ts", + args: ["mode","id"], + handler: import("./api/npm") } export const _upload = { name: "_upload", @@ -28,14 +28,14 @@ export const _upload = { } export const _prasi = { name: "_prasi", - url: "/_prasi/**", + url: "/_prasi/*", path: "app/srv/api/_prasi.ts", args: [], handler: import("./api/_prasi") } export const _file = { name: "_file", - url: "/_file/**", + url: "/_file/*", path: "app/srv/api/_file.ts", args: [], handler: import("./api/_file") diff --git a/app/srv/global.ts b/app/srv/global.ts new file mode 100644 index 00000000..229d4065 --- /dev/null +++ b/app/srv/global.ts @@ -0,0 +1,26 @@ +import { site, user } from "dbgen"; +import { ExecaChildProcess } from "execa"; + +export const glb = global as unknown as { + lastUpdate: Record; + prasiSrv: { + status: Record< + string, + | "unavailable" + | "installing" + | "starting" + | "started" + | "stopped" + | "destroying" + >; + running: Record; + }; + npm: { + page: Record; + site: Record; + }; +}; + +export type Session = { + user: user & { site: site[] }; +}; diff --git a/app/web/src/base/page/all.tsx b/app/web/src/base/page/all.tsx index d25b2346..c8a38d09 100644 --- a/app/web/src/base/page/all.tsx +++ b/app/web/src/base/page/all.tsx @@ -1,12 +1,17 @@ import { useEffect } from "react"; import { page } from "web-utils"; +import { Loading } from "../../utils/ui/loading"; export default page({ url: "**", component: ({}) => { useEffect(() => { - navigate("/login"); + if (localStorage.getItem("prasi-session")) { + navigate("/editor/_/_"); + } else { + navigate("/login"); + } }, []); - return
Loading...
; + return ; }, }); diff --git a/app/web/src/base/page/auth/login.tsx b/app/web/src/base/page/auth/login.tsx index 47637ead..500e50ee 100644 --- a/app/web/src/base/page/auth/login.tsx +++ b/app/web/src/base/page/auth/login.tsx @@ -21,7 +21,9 @@ export default page({ if (rto) { navigate(rto); } else { - navigate("/editor"); + console.log("navigate to"); + localStorage.setItem("prasi-session", JSON.stringify(s)); + navigate("/editor/_/_"); } } else { form.init = true; @@ -50,7 +52,7 @@ export default page({ if (rto) { navigate(rto); } else { - navigate("/editor"); + navigate("/editor/_/_"); } } }} diff --git a/app/web/src/base/page/editor.tsx b/app/web/src/base/page/editor.tsx index 00323375..90d56ed8 100644 --- a/app/web/src/base/page/editor.tsx +++ b/app/web/src/base/page/editor.tsx @@ -1,7 +1,6 @@ -import { page } from "web-utils"; -import { useLocal } from "web-utils"; -import { Loading } from "../../utils/ui/loading"; import { Suspense, lazy, useEffect } from "react"; +import { page, useLocal } from "web-utils"; +import { Loading } from "../../utils/ui/loading"; const Editor = lazy(async () => ({ default: (await import("../../render/editor/editor")).Editor, @@ -35,7 +34,8 @@ export default page({ let e = await api.session(); if (!e) { (window as any).redirectTo = location.pathname; - navigate("/login"); + console.log("session not found"); + // navigate("/login"); localStorage.removeItem("prasi-session"); } else { localStorage.setItem("prasi-session", JSON.stringify(e)); diff --git a/app/web/src/base/pages.ts b/app/web/src/base/pages.ts index 81a84dca..d6e25181 100644 --- a/app/web/src/base/pages.ts +++ b/app/web/src/base/pages.ts @@ -6,3 +6,8 @@ export const login = { url: "/login", page: () => import("./page/auth/login"), }; + +export const editor = { + url: "/editor/:site_id/:page_id", + page: () => import("./page/editor"), +}; diff --git a/app/web/src/base/root.tsx b/app/web/src/base/root.tsx index afbac143..2c156cbd 100644 --- a/app/web/src/base/root.tsx +++ b/app/web/src/base/root.tsx @@ -2,22 +2,25 @@ import { createRouter } from "radix3"; import { FC, Suspense, lazy } from "react"; import { GlobalContext, useLocal } from "web-utils"; import { Loading } from "../utils/ui/loading"; +import { w } from "../utils/types/general"; export const Root: FC<{}> = ({}) => { const local = useLocal( { - router: createRouter({ strictTrailingSlash: true }), + router: createRouter<{ url: string; Page: FC }>({ + strictTrailingSlash: true, + }), Page: null as any, }, async () => { const pages = await import("./pages"); for (const [_, v] of Object.entries(pages)) { - local.router.insert( - v.url, - lazy(async () => { + local.router.insert(v.url, { + url: v.url, + Page: lazy(async () => { return { default: (await v.page()).default.component as any }; - }) - ); + }), + }); } local.render(); } @@ -28,7 +31,8 @@ export const Root: FC<{}> = ({}) => { const found = local.router.lookup(location.pathname); if (found) { - local.Page = found; + w.params = found.params; + local.Page = found.Page; } if (!local.Page) { diff --git a/app/web/src/index.tsx b/app/web/src/index.tsx index 1263c66b..85507c13 100644 --- a/app/web/src/index.tsx +++ b/app/web/src/index.tsx @@ -3,14 +3,14 @@ import { defineReact, defineWindow } from "web-utils"; import { Root } from "./base/root"; import "./index.css"; import { createAPI, createDB, reloadDBAPI } from "./utils/script/init-api"; +import { w } from "./utils/types/general"; const start = async () => { registerServiceWorker(); defineReact(); await defineWindow(false); - const w = window as any; const base = `${location.protocol}//${location.host}`; - + w.serverurl = base; await reloadDBAPI(base); w.api = createAPI(base); w.db = createDB(base); diff --git a/app/web/src/render/editor/logic/global.ts b/app/web/src/render/editor/logic/global.ts index 34d80dec..7245c962 100644 --- a/app/web/src/render/editor/logic/global.ts +++ b/app/web/src/render/editor/logic/global.ts @@ -1,5 +1,5 @@ import { FC, ReactElement, ReactNode } from "react"; -import { createRouter } from "web-utils"; +import { createRouter } from "radix3"; import { CompDoc } from "../../../base/global/content-editor"; import { IContent, MContent, MPage } from "../../../utils/types/general"; import { IItem, MItem } from "../../../utils/types/item"; diff --git a/app/web/src/render/editor/panel/script/monaco/monaco-el.tsx b/app/web/src/render/editor/panel/script/monaco/monaco-el.tsx index bc7fed90..e4d7d55a 100644 --- a/app/web/src/render/editor/panel/script/monaco/monaco-el.tsx +++ b/app/web/src/render/editor/panel/script/monaco/monaco-el.tsx @@ -91,7 +91,7 @@ export const ScriptMonacoElement: FC<{ } if (!w.importCache.prettier_parser) w.importCache.prettier_parser = await import( - "prettier/parser-typescript" + "prettier/plugins/typescript" ); if (!w.importCache.prettier) diff --git a/app/web/src/render/editor/panel/script/monaco/mount.tsx b/app/web/src/render/editor/panel/script/monaco/mount.tsx index d3a9f32c..14ee8509 100644 --- a/app/web/src/render/editor/panel/script/monaco/mount.tsx +++ b/app/web/src/render/editor/panel/script/monaco/mount.tsx @@ -56,7 +56,7 @@ export const jsMount = async (p: PG, editor: MonacoEditor, monaco: Monaco) => { } if (!w.importCache.prettier_parser) w.importCache.prettier_parser = await import( - "prettier/parser-typescript" + "prettier/plugins/typescript" ); if (!w.importCache.prettier) diff --git a/app/web/src/utils/types/general.ts b/app/web/src/utils/types/general.ts index a5ea9130..efdd1eb8 100644 --- a/app/web/src/utils/types/general.ts +++ b/app/web/src/utils/types/general.ts @@ -1,6 +1,5 @@ import { page as dbpage } from "dbgen"; import { TypedDoc, TypedMap } from "yjs-types"; -import { loadSite } from "../../../../srv/edit/tools/load-site"; import { IItem, MItem } from "./item"; import { IRoot, MRoot } from "./root"; import { ISection, MSection } from "./section"; @@ -31,6 +30,9 @@ export const w = window as unknown as { params: any; editorGlbDefault: string; ts: number; + serverurl: string; + api: any; + db: any; }; export type Page = { @@ -47,7 +49,6 @@ export type MPage = TypedDoc<{ } >; }>; -export type Site = Exclude>, null>; export type IContent = ISection | IItem | IText; export type MContent = MSection | MItem | MText; diff --git a/app/web/tsconfig.json b/app/web/tsconfig.json index f5832eec..283fd92c 100644 --- a/app/web/tsconfig.json +++ b/app/web/tsconfig.json @@ -20,5 +20,10 @@ "isolatedModules": true, // "noEmit": true, "jsx": "react-jsx", + "paths": { + "dbgen": [ + "../../node_modules/.prisma/client/index.d.ts" + ], + } }, } \ No newline at end of file diff --git a/bun.lockb b/bun.lockb index 93dd0eed..46f913d2 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index 138ac395..4348a791 100644 --- a/package.json +++ b/package.json @@ -19,5 +19,5 @@ "peerDependencies": { "typescript": "^5.0.0" }, - "dependencies": { "@node-rs/argon2": "^1.5.2" } + "dependencies": { "@node-rs/argon2": "^1.5.2", "@types/mime-types": "^2.1.2", "mime-types": "^2.1.35" } } diff --git a/pkgs/core/api/_file.ts b/pkgs/core/api/_file.ts index 0b44c7d2..05f3dd28 100644 --- a/pkgs/core/api/_file.ts +++ b/pkgs/core/api/_file.ts @@ -2,14 +2,14 @@ import { apiContext } from "../server/api-ctx"; import { dir } from "../utils/dir"; export const _ = { - url: "/_file/**", + url: "/_file/*", async api() { const { req } = apiContext(this); const rpath = decodeURIComponent(req.params._); - const path = dir(`../data/upload/${rpath}`); + const path = dir.path(`../data/upload/${rpath}`); try { - return new Response(Bun.file(path)); + return new Response(Bun.file(path) as any); } catch (e) { return new Response("NOT FOUND", { status: 404 }); } diff --git a/pkgs/core/api/_prasi.ts b/pkgs/core/api/_prasi.ts index 9a85d23e..6d628a39 100644 --- a/pkgs/core/api/_prasi.ts +++ b/pkgs/core/api/_prasi.ts @@ -9,7 +9,7 @@ const cache = { }; export const _ = { - url: "/_prasi/**", + url: "/_prasi/*", async api() { const { req, res } = apiContext(this); res.setHeader("Access-Control-Allow-Origin", "*"); @@ -95,7 +95,7 @@ declare module "gen/srv/api/entry" { export * as srv from "gen/srv/api/srv"; } ` + - ((await readAsync(dir("app/srv/exports.d.ts"))) || "") + ((await readAsync(dir.path("app/srv/exports.d.ts"))) || "") .replace(/\"app\/srv\/api/gi, '"srv/api') .replace( 'declare module "app/srv/exports"', @@ -108,20 +108,20 @@ const getPrisma = async (path: string) => { if (path === "prisma") return JSON.stringify( ( - (await readAsync(dir("node_modules/.prisma/client/index.d.ts"))) || "" + (await readAsync(dir.path("node_modules/.prisma/client/index.d.ts"))) || "" ).replace(`@prisma/client/runtime/library`, `./runtime/library`) ); if (path === "runtime") return JSON.stringify( await readAsync( - dir("node_modules/@prisma/client/runtime/index-browser.d.ts") + dir.path("node_modules/@prisma/client/runtime/index-browser.d.ts") ) ); if (path === "library") return JSON.stringify( - await readAsync(dir("node_modules/@prisma/client/runtime/library.d.ts")) + await readAsync(dir.path("node_modules/@prisma/client/runtime/library.d.ts")) ); return JSON.stringify({}); diff --git a/pkgs/core/api/_upload.ts b/pkgs/core/api/_upload.ts index 24d9912a..d583963d 100644 --- a/pkgs/core/api/_upload.ts +++ b/pkgs/core/api/_upload.ts @@ -21,7 +21,7 @@ export const _ = { .toLowerCase()}`; url = `/_file/${path}`; - await writeAsync(dir(`../data/upload/${path}`), part.buffer); + await writeAsync(dir.path(`../data/upload/${path}`), part.buffer); } return url; diff --git a/pkgs/core/api/_web.ts b/pkgs/core/api/_web.ts deleted file mode 100644 index c3bd8dc2..00000000 --- a/pkgs/core/api/_web.ts +++ /dev/null @@ -1,79 +0,0 @@ -import mime from "mime"; -import { apiContext } from "../server/api-ctx"; -import { g } from "../utils/global"; -import { getApiEntry } from "./_prasi"; - -export const _ = { - url: "/_web/:id/**", - async api(id: string, _: string) { - const { req, res } = apiContext(this); - - const web = g.web[id]; - if (web) { - const cache = web.cache; - if (cache) { - const parts = _.split("/"); - - switch (parts[0]) { - case "site": { - res.setHeader("content-type", "application/json"); - if (req.query_parameters["prod"]) { - return { - site: cache.site, - pages: cache.pages.map((e) => { - return { - id: e.id, - url: e.url, - }; - }), - api: getApiEntry(), - }; - } else { - return cache.site; - } - } - case "pages": { - res.setHeader("content-type", "application/json"); - return cache.pages.map((e) => { - return { - id: e.id, - url: e.url, - }; - }); - } - case "page": { - res.setHeader("content-type", "application/json"); - return cache.pages.find((e) => e.id === parts[1]); - } - case "npm-site": { - let path = parts.slice(1).join("/"); - res.setHeader("content-type", mime.getType(path) || "text/plain"); - - if (path === "site.js") { - path = "index.js"; - } - return cache.npm.site[path]; - } - case "npm-page": { - const page_id = parts[1]; - if (cache.npm.pages[page_id]) { - let path = parts.slice(2).join("/"); - res.setHeader("content-type", mime.getType(path) || "text/plain"); - - if (path === "page.js") { - path = "index.js"; - } - return cache.npm.pages[page_id][path]; - } - res.setHeader("content-type", "text/javascript"); - } - case "comp": { - res.setHeader("content-type", "application/json"); - return cache.comps.find((e) => e.id === parts[1]); - } - } - } - } - return req.params; - }, -}; diff --git a/pkgs/core/server/api-ctx.ts b/pkgs/core/server/api-ctx.ts index c3e1c189..9cb0c35c 100644 --- a/pkgs/core/server/api-ctx.ts +++ b/pkgs/core/server/api-ctx.ts @@ -1,3 +1,4 @@ +import { g } from "utils/global"; const parseQueryParams = (ctx: any) => { const pageHref = ctx.req.url; @@ -15,6 +16,7 @@ export const apiContext = (ctx: any) => { ctx.req.params = ctx.params; ctx.req.query_parameters = parseQueryParams(ctx); return { + mode: g.mode, req: ctx.req as Request & { params: any; query_parameters: any }, res: { ...ctx.res, diff --git a/pkgs/core/server/api-scan.ts b/pkgs/core/server/api-scan.ts index 7a9833af..a8b78ade 100644 --- a/pkgs/core/server/api-scan.ts +++ b/pkgs/core/server/api-scan.ts @@ -22,7 +22,7 @@ export const prepareApiRoutes = async () => { path: importPath.substring((root || path).length + 1), }; g.api[filename] = route; - g.router.insert(route.url, g.api[filename]); + g.router.insert(route.url.replace(/\*/gi, "**"), g.api[filename]); } catch (e) { g.log.warn( `Failed to import app/srv/api${importPath.substring( @@ -46,6 +46,6 @@ export const prepareApiRoutes = async () => { } } }; - await scan(dir(`app/srv/api`)); - await scan(dir(`pkgs/core/api`)); + await scan(dir.path(`app/srv/api`)); + await scan(dir.path(`pkgs/core/api`)); }; diff --git a/pkgs/core/server/create.ts b/pkgs/core/server/create.ts index 243b0755..70d1ac82 100644 --- a/pkgs/core/server/create.ts +++ b/pkgs/core/server/create.ts @@ -3,6 +3,7 @@ import { dir } from "../utils/dir"; import { g } from "../utils/global"; import { serveAPI } from "./serve-api"; +const cache = { static: {} as Record }; export const createServer = async () => { g.api = {}; g.router = createRouter({ strictTrailingSlash: true }); @@ -22,15 +23,21 @@ export const createServer = async () => { } try { - const file = Bun.file(dir(`app/static${url.pathname}`)); - if (file.type !== "application/octet-stream") { + if (cache.static[url.pathname]) { + return new Response(cache.static[url.pathname]); + } + + const file = Bun.file(dir.path(`app/static${url.pathname}`)); + if ((await file.exists()) && file.type !== "application/octet-stream") { + cache.static[url.pathname] = file; return new Response(file as any); } } catch (e) { g.log.error(e); } + try { - return new Response(Bun.file(dir(`app/static/index.html`)) as any); + return new Response(Bun.file(dir.path(`app/static/index.html`)) as any); } catch (e) { g.log.error(e); return new Response("Loading..."); diff --git a/pkgs/core/server/prep-api-ts.ts b/pkgs/core/server/prep-api-ts.ts index 63f68e89..8c881060 100644 --- a/pkgs/core/server/prep-api-ts.ts +++ b/pkgs/core/server/prep-api-ts.ts @@ -16,20 +16,20 @@ export const ${name} = { handler: import("./api/${v.path.substring(0, v.path.length - 3)}") }`); } - await Bun.write(dir(`app/srv/exports.ts`), out.join(`\n`)); + await Bun.write(dir.path(`app/srv/exports.ts`), out.join(`\n`)); - const targetFile = dir("app/srv/exports.d.ts"); + const targetFile = dir.path("app/srv/exports.d.ts"); const tsc = spawn( [ - dir("node_modules/.bin/tsc"), - dir("app/srv/exports.ts"), + dir.path("node_modules/.bin/tsc"), + dir.path("app/srv/exports.ts"), "--declaration", "--emitDeclarationOnly", "--outFile", targetFile, ], { - cwd: dir(`node_modules/.bin`), + cwd: dir.path(`node_modules/.bin`), } ); diff --git a/pkgs/core/upgrade.ts b/pkgs/core/upgrade.ts index 885c4d2d..9b4a661c 100644 --- a/pkgs/core/upgrade.ts +++ b/pkgs/core/upgrade.ts @@ -11,15 +11,15 @@ const res = await fetch( const data = await unzipper.Open.buffer(Buffer.from(await res.arrayBuffer())); const promises: Promise[] = []; -await removeAsync(dir("pkgs")); +await removeAsync(dir.path("pkgs")); for (const file of data.files) { if (file.type === "File") { const path = file.path.split("/").slice(1).join("/"); if (path === "tsconfig.json" || path.startsWith("pkgs")) { promises.push( new Promise(async (done) => { - await dirAsync(dirname(dir(path))); - await Bun.write(dir(path), await file.buffer()); + await dirAsync(dirname(dir.path(path))); + await Bun.write(dir.path(path), await file.buffer()); done(); }) ); diff --git a/pkgs/core/utils/config.ts b/pkgs/core/utils/config.ts index 36bea182..578744a6 100644 --- a/pkgs/core/utils/config.ts +++ b/pkgs/core/utils/config.ts @@ -5,11 +5,11 @@ const _internal = { config: {} as any, writeTimeout: null as any }; export const config = { init: async () => { - await dirAsync(dir("../data/config")); - await dirAsync(dir("../data/files")); + await dirAsync(dir.path("../data/config")); + await dirAsync(dir.path("../data/files")); _internal.config = - (await readAsync(dir("../data/config/conf.json"), "json")) || {}; + (await readAsync(dir.path("../data/config/conf.json"), "json")) || {}; }, get all() { return _internal.config; @@ -27,7 +27,7 @@ export const config = { _internal.config[key] = value; clearTimeout(_internal.writeTimeout); _internal.writeTimeout = setTimeout(() => { - Bun.write(dir("../data/config/conf.json"), _internal.config); + Bun.write(dir.path("../data/config/conf.json"), _internal.config); }, 100); }, }; diff --git a/pkgs/core/utils/dev-watcher.ts b/pkgs/core/utils/dev-watcher.ts index 1b3da892..f7bc1851 100644 --- a/pkgs/core/utils/dev-watcher.ts +++ b/pkgs/core/utils/dev-watcher.ts @@ -4,9 +4,9 @@ import { dir } from "./dir"; import { dirAsync } from "fs-jetpack"; export const startDevWatcher = async () => { - await dirAsync(dir(`app/srv/api`)); - watch(dir(`app/srv/api`), async (event, filename) => { - const s = file(dir(`app/srv/api/${filename}`)); + await dirAsync(dir.path(`app/srv/api`)); + watch(dir.path(`app/srv/api`), async (event, filename) => { + const s = file(dir.path(`app/srv/api/${filename}`)); if (s.size === 0) { await Bun.write( `app/srv/api/${filename}`, diff --git a/pkgs/core/utils/dir.ts b/pkgs/core/utils/dir.ts index e49f156f..c9eb33a8 100644 --- a/pkgs/core/utils/dir.ts +++ b/pkgs/core/utils/dir.ts @@ -1,5 +1,7 @@ import { join } from "path"; -export const dir = (path: string) => { - return join(process.cwd(), path); +export const dir = { + path: (path: string) => { + return join(process.cwd(), path); + }, }; diff --git a/pkgs/core/utils/parcel.ts b/pkgs/core/utils/parcel.ts index 6a6c5f06..0f352fb6 100644 --- a/pkgs/core/utils/parcel.ts +++ b/pkgs/core/utils/parcel.ts @@ -7,28 +7,28 @@ export const parcelBuild = async () => { await dirAsync("app/static"); const args = [ "node", - dir("node_modules/.bin/parcel"), + dir.path("node_modules/.bin/parcel"), g.mode === "dev" ? "watch" : "build", "./src/index.tsx", g.mode === "dev" ? "--no-hmr" : "--no-optimize", "--dist-dir", - dir(`app/static`), + dir.path(`app/static`), ]; g.log.info(`Building web with parcel`); if (g.mode !== "dev") { - await removeAsync(dir("app/static")); - await removeAsync(dir("app/web/.parcel-cache")); + await removeAsync(dir.path("app/static")); + await removeAsync(dir.path("app/web/.parcel-cache")); const parcel = spawn({ cmd: args, - cwd: dir("app/web"), + cwd: dir.path("app/web"), stdio: ["ignore", "inherit", "inherit"], }); await parcel.exited; } else { const parcel = spawn({ cmd: args, - cwd: dir("app/web"), + cwd: dir.path("app/web"), stdio: ["ignore", "pipe", "pipe"], }); diff --git a/pkgs/core/utils/prisma.ts b/pkgs/core/utils/prisma.ts index e82c55ea..0ea8a307 100644 --- a/pkgs/core/utils/prisma.ts +++ b/pkgs/core/utils/prisma.ts @@ -4,9 +4,9 @@ import { $ } from "execa"; import { g } from "./global"; export const preparePrisma = async () => { - if (await existsAsync(dir("app/db/.env"))) { - if (!(await existsAsync(dir("node_modules/.prisma")))) { - await $({ cwd: dir(`app/db`) })`bun prisma generate`; + if (await existsAsync(dir.path("app/db/.env"))) { + if (!(await existsAsync(dir.path("node_modules/.prisma")))) { + await $({ cwd: dir.path(`app/db`) })`bun prisma generate`; } const { PrismaClient } = await import("../../../app/db/db"); g.db = new PrismaClient(); diff --git a/pkgs/core/utils/session.ts b/pkgs/core/utils/session.ts index 57addce2..7c0d1452 100644 --- a/pkgs/core/utils/session.ts +++ b/pkgs/core/utils/session.ts @@ -14,7 +14,7 @@ export const createCache = () => ({ lmdb: null as unknown as RootDatabase>, cookieKey: "", async init(arg: { cookieKey: string; dbname?: string }) { - const dbpath = dir(join(g.datadir, (arg.dbname || "session") + ".lmdb")); + const dbpath = dir.path(join(g.datadir, (arg.dbname || "session") + ".lmdb")); await dirAsync(dirname(dbpath)); self(this).lmdb = open({ path: dbpath, diff --git a/tsconfig.json b/tsconfig.json index 2042d68e..b7a3b708 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -23,6 +23,9 @@ "forceConsistentCasingInFileNames": true, "allowJs": true, "paths": { + "dir": [ + "./pkgs/core/utils/dir.ts" + ], "dbgen": [ "./node_modules/.prisma/client/index.d.ts" ],