wip checkpoint
This commit is contained in:
parent
3dc13caab8
commit
21fa871b92
|
|
@ -0,0 +1,62 @@
|
||||||
|
import { w } from "../../../utils/types/general";
|
||||||
|
import { fetchViaProxy } from "../proxy";
|
||||||
|
|
||||||
|
export const loadApiProxyDef = async (url: string, with_types: boolean) => {
|
||||||
|
const raw = await fetchViaProxy(urlPath(url, "/_prasi/_"));
|
||||||
|
let ver = "";
|
||||||
|
if (raw && (raw as any).prasi) {
|
||||||
|
ver = (raw as any).prasi;
|
||||||
|
}
|
||||||
|
const base = baseUrl(url);
|
||||||
|
|
||||||
|
if (ver === "v2") {
|
||||||
|
await new Promise<void>((done) => {
|
||||||
|
const d = document;
|
||||||
|
const script = d.createElement("script");
|
||||||
|
script.onload = async () => {
|
||||||
|
done();
|
||||||
|
};
|
||||||
|
if (with_types) {
|
||||||
|
script.src = `${base}/_prasi/load.js?url=${url}&dev=1`;
|
||||||
|
} else {
|
||||||
|
script.src = `${base}/_prasi/load.js?url=${url}`;
|
||||||
|
}
|
||||||
|
d.body.appendChild(script);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const apiEntry = await fetch(base + "/_prasi/api-entry");
|
||||||
|
w.prasiApi[url] = {
|
||||||
|
apiEntry: (await apiEntry.json()).srv,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (with_types) {
|
||||||
|
const apiTypes = await fetch(base + "/_prasi/api-types");
|
||||||
|
w.prasiApi[url].apiTypes = await apiTypes.text();
|
||||||
|
w.prasiApi[url].prismaTypes = {
|
||||||
|
"prisma.d.ts": await loadText(`${base}/_prasi/prisma/index.d.ts`),
|
||||||
|
"runtime/index.d.ts": await loadText(
|
||||||
|
`${base}/_prasi/prisma/runtime/index.d.ts`
|
||||||
|
),
|
||||||
|
"runtime/library.d.ts": await loadText(
|
||||||
|
`${base}/_prasi/prisma/runtime/library.d.ts`
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const baseUrl = (url: string) => {
|
||||||
|
const base = new URL(url);
|
||||||
|
return `${base.protocol}//${base.host}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const urlPath = (url: string, pathname: string) => {
|
||||||
|
const base = new URL(url);
|
||||||
|
base.pathname = pathname;
|
||||||
|
return base.toString();
|
||||||
|
};
|
||||||
|
|
||||||
|
const loadText = async (url: string, v2?: boolean) => {
|
||||||
|
const res = await fetch(url);
|
||||||
|
return await res.text();
|
||||||
|
};
|
||||||
|
|
@ -1,40 +1,49 @@
|
||||||
import { fetchSendApi } from "./client-frame";
|
import { w } from "../../../utils/types/general";
|
||||||
|
import { fetchViaProxy } from "../proxy";
|
||||||
|
import { loadApiProxyDef } from "./api-proxy-def";
|
||||||
|
|
||||||
export const apiClient = (
|
export type ApiProxy<T extends Record<string, any> = {}> = any;
|
||||||
api: Record<string, { url: string; args: any[] }>,
|
|
||||||
apiUrl: string
|
export const apiProxy = (api_url: string) => {
|
||||||
) => {
|
|
||||||
return new Proxy(
|
return new Proxy(
|
||||||
{},
|
{},
|
||||||
{
|
{
|
||||||
get: (_, actionName: string) => {
|
get: (_, actionName: string) => {
|
||||||
const createFn = (actionName: string) => {
|
const createFn = (actionName: string) => {
|
||||||
return function (this: { apiUrl: string } | undefined, ...rest: any) {
|
return function (
|
||||||
|
this: { api_url: string } | undefined,
|
||||||
|
...rest: any
|
||||||
|
) {
|
||||||
return new Promise<any>(async (resolve, reject) => {
|
return new Promise<any>(async (resolve, reject) => {
|
||||||
try {
|
try {
|
||||||
let _apiURL = apiUrl;
|
let base_url = api_url;
|
||||||
if (typeof this?.apiUrl === "string") {
|
if (typeof this?.api_url === "string") {
|
||||||
_apiURL = this.apiUrl;
|
base_url = this.api_url;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!api) {
|
if (!w.prasiApi) {
|
||||||
reject(
|
w.prasiApi = {};
|
||||||
new Error(`API Definition for ${_apiURL} is not loaded.`)
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (api && !api[actionName]) {
|
if (!w.prasiApi[base_url]) {
|
||||||
reject(
|
await loadApiProxyDef(base_url, false);
|
||||||
`API ${actionName.toString()} not found, existing API: \n - ${Object.keys(
|
|
||||||
api || {}
|
|
||||||
).join("\n - ")}`
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let actionUrl = api[actionName].url;
|
const api_def = w.prasiApi[base_url];
|
||||||
const actionParams = api[actionName].args;
|
if (api_def) {
|
||||||
|
if (!api_def.apiEntry) api_def.apiEntry = {};
|
||||||
|
if (api_def.apiEntry && !api_def.apiEntry[actionName]) {
|
||||||
|
reject(
|
||||||
|
`API ${actionName.toString()} not found, existing API: \n - ${Object.keys(
|
||||||
|
api_def || {}
|
||||||
|
).join("\n - ")}`
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let actionUrl = api_def.apiEntry[actionName].url;
|
||||||
|
const actionParams = api_def.apiEntry[actionName].args;
|
||||||
if (actionUrl && actionParams) {
|
if (actionUrl && actionParams) {
|
||||||
if (rest.length > 0 && actionParams.length > 0) {
|
if (rest.length > 0 && actionParams.length > 0) {
|
||||||
for (const [idx, p] of Object.entries(rest)) {
|
for (const [idx, p] of Object.entries(rest)) {
|
||||||
|
|
@ -53,7 +62,7 @@ export const apiClient = (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const url = `${_apiURL}${actionUrl}`;
|
const url = `${base_url}${actionUrl}`;
|
||||||
|
|
||||||
const result = await fetchSendApi(url, rest);
|
const result = await fetchSendApi(url, rest);
|
||||||
resolve(result);
|
resolve(result);
|
||||||
|
|
@ -82,3 +91,9 @@ export const apiClient = (
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const fetchSendApi = async (url: string, params: any) => {
|
||||||
|
return await fetchViaProxy(url, params, {
|
||||||
|
"content-type": "application/json",
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
import { waitUntil } from "web-utils";
|
|
||||||
import { createFrameCors } from "./client-frame";
|
|
||||||
import hash_sum from "hash-sum";
|
import hash_sum from "hash-sum";
|
||||||
|
import { fetchViaProxy } from "../proxy";
|
||||||
|
|
||||||
export const dbClient = (name: string, dburl?: string) => {
|
export const dbProxy = (dburl: string) => {
|
||||||
return new Proxy(
|
return new Proxy(
|
||||||
{},
|
{},
|
||||||
{
|
{
|
||||||
|
|
@ -10,7 +9,6 @@ export const dbClient = (name: string, dburl?: string) => {
|
||||||
if (table === "_tables") {
|
if (table === "_tables") {
|
||||||
return () => {
|
return () => {
|
||||||
return fetchSendDb(
|
return fetchSendDb(
|
||||||
name,
|
|
||||||
{
|
{
|
||||||
name,
|
name,
|
||||||
action: "definition",
|
action: "definition",
|
||||||
|
|
@ -24,7 +22,6 @@ export const dbClient = (name: string, dburl?: string) => {
|
||||||
if (table === "_definition") {
|
if (table === "_definition") {
|
||||||
return (table: string) => {
|
return (table: string) => {
|
||||||
return fetchSendDb(
|
return fetchSendDb(
|
||||||
name,
|
|
||||||
{
|
{
|
||||||
name,
|
name,
|
||||||
action: "definition",
|
action: "definition",
|
||||||
|
|
@ -38,7 +35,6 @@ export const dbClient = (name: string, dburl?: string) => {
|
||||||
if (table.startsWith("$")) {
|
if (table.startsWith("$")) {
|
||||||
return (...params: any[]) => {
|
return (...params: any[]) => {
|
||||||
return fetchSendDb(
|
return fetchSendDb(
|
||||||
name,
|
|
||||||
{
|
{
|
||||||
name,
|
name,
|
||||||
action: "query",
|
action: "query",
|
||||||
|
|
@ -60,7 +56,6 @@ export const dbClient = (name: string, dburl?: string) => {
|
||||||
action = "query";
|
action = "query";
|
||||||
}
|
}
|
||||||
return fetchSendDb(
|
return fetchSendDb(
|
||||||
name,
|
|
||||||
{
|
{
|
||||||
name,
|
name,
|
||||||
action,
|
action,
|
||||||
|
|
@ -83,37 +78,13 @@ const cachedQueryResult: Record<
|
||||||
{ timestamp: number; result: any; promise: Promise<any> }
|
{ timestamp: number; result: any; promise: Promise<any> }
|
||||||
> = {};
|
> = {};
|
||||||
|
|
||||||
export const fetchSendDb = async (
|
export const fetchSendDb = async (params: any, dburl: string) => {
|
||||||
name: string,
|
const base = new URL(dburl);
|
||||||
params: any,
|
base.pathname = `/_dbs/`;
|
||||||
dburl?: string
|
|
||||||
) => {
|
|
||||||
const w = typeof window === "object" ? window : (globalThis as any);
|
|
||||||
let url = `/_dbs/${name}`;
|
|
||||||
let frm: Awaited<ReturnType<typeof createFrameCors>>;
|
|
||||||
|
|
||||||
if (params.table) {
|
if (params.table) {
|
||||||
url += `/${params.table}`;
|
base.pathname += `/${params.table}`;
|
||||||
}
|
|
||||||
|
|
||||||
const _base = dburl || w.serverurl;
|
|
||||||
|
|
||||||
if (!w.frmapi) {
|
|
||||||
w.frmapi = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!w.frmapi[_base]) {
|
|
||||||
w.frmapi[_base] = await createFrameCors(_base);
|
|
||||||
}
|
|
||||||
|
|
||||||
frm = w.frmapi[_base];
|
|
||||||
|
|
||||||
if (!frm) {
|
|
||||||
await waitUntil(() => {
|
|
||||||
frm = w.frmapi[_base];
|
|
||||||
return frm;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
const url = base.toString();
|
||||||
|
|
||||||
const hsum = hash_sum(params);
|
const hsum = hash_sum(params);
|
||||||
const cached = cachedQueryResult[hsum];
|
const cached = cachedQueryResult[hsum];
|
||||||
|
|
@ -121,7 +92,9 @@ export const fetchSendDb = async (
|
||||||
if (!cached || (cached && Date.now() - cached.timestamp > 1000)) {
|
if (!cached || (cached && Date.now() - cached.timestamp > 1000)) {
|
||||||
cachedQueryResult[hsum] = {
|
cachedQueryResult[hsum] = {
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
promise: frm.send(url, params, w.apiHeaders),
|
promise: fetchViaProxy(url, params, {
|
||||||
|
"content-type": "application/json",
|
||||||
|
}),
|
||||||
result: null,
|
result: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -47,11 +47,16 @@ export const fetchViaProxy = async (
|
||||||
const cur = new URL(location.href);
|
const cur = new URL(location.href);
|
||||||
const base = new URL(url);
|
const base = new URL(url);
|
||||||
if (cur.host === base.host) {
|
if (cur.host === base.host) {
|
||||||
const res = await fetch(base.pathname, {
|
const res = await fetch(
|
||||||
method: "POST",
|
base.pathname,
|
||||||
body,
|
data
|
||||||
headers,
|
? {
|
||||||
});
|
method: "POST",
|
||||||
|
body,
|
||||||
|
headers,
|
||||||
|
}
|
||||||
|
: undefined
|
||||||
|
);
|
||||||
const raw = await res.text();
|
const raw = await res.text();
|
||||||
try {
|
try {
|
||||||
return JSON.parse(raw);
|
return JSON.parse(raw);
|
||||||
|
|
@ -59,17 +64,15 @@ export const fetchViaProxy = async (
|
||||||
return raw;
|
return raw;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log(url);
|
const res = await fetch(`/_proxy`, {
|
||||||
return null;
|
method: "POST",
|
||||||
// const res = await fetch(`/_proxy`, {
|
body: JSON.stringify({
|
||||||
// method: "POST",
|
url,
|
||||||
// body: JSON.stringify({
|
body,
|
||||||
// url,
|
headers,
|
||||||
// body,
|
}),
|
||||||
// headers,
|
headers: { "content-type": "application/json" },
|
||||||
// }),
|
});
|
||||||
// headers: { "content-type": "application/json" },
|
return res.json();
|
||||||
// });
|
|
||||||
// return res.json();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
import { Root as ReactRoot, createRoot } from "react-dom/client";
|
import { Root as ReactRoot, createRoot } from "react-dom/client";
|
||||||
import { defineReact, defineWindow } from "web-utils";
|
import { defineReact, defineWindow } from "web-utils";
|
||||||
|
import { apiProxy } from "./base/load/api/api-proxy";
|
||||||
|
import { dbProxy } from "./base/load/db/db-proxy";
|
||||||
import { Root } from "./base/root";
|
import { Root } from "./base/root";
|
||||||
import "./index.css";
|
import "./index.css";
|
||||||
import { registerMobile } from "./render/live/logic/mobile";
|
import { registerMobile } from "./render/live/logic/mobile";
|
||||||
import { reloadDBAPI } from "./utils/script/init-api";
|
|
||||||
import { w } from "./utils/types/general";
|
|
||||||
import { sworkerAddCache, sworkerRegister } from "./sworker-boot";
|
import { sworkerAddCache, sworkerRegister } from "./sworker-boot";
|
||||||
import { dbClient } from "./base/load/db/client-db";
|
import { w } from "./utils/types/general";
|
||||||
|
|
||||||
const start = async () => {
|
const start = async () => {
|
||||||
const base = `${location.protocol}//${location.host}`;
|
const base = `${location.protocol}//${location.host}`;
|
||||||
|
|
@ -14,7 +14,12 @@ const start = async () => {
|
||||||
root: null as null | ReactRoot,
|
root: null as null | ReactRoot,
|
||||||
};
|
};
|
||||||
w.mobile = registerMobile();
|
w.mobile = registerMobile();
|
||||||
w.db = dbClient("prasi", location.origin);
|
|
||||||
|
const cur = new URL(location.href);
|
||||||
|
const base_url = `${cur.protocol}//${cur.host}`;
|
||||||
|
w.db = dbProxy(base_url);
|
||||||
|
w.api = apiProxy(base_url);
|
||||||
|
|
||||||
w.serverurl = base;
|
w.serverurl = base;
|
||||||
|
|
||||||
sworkerRegister(react);
|
sworkerRegister(react);
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,18 @@
|
||||||
import init from "wasm-gzip";
|
import init from "wasm-gzip";
|
||||||
import { jscript } from "../../../utils/script/jscript";
|
import { jscript } from "../../../utils/script/jscript";
|
||||||
import { dbClient } from "../../../base/load/db/client-db";
|
import { dbProxy } from "../../../base/load/db/db-proxy";
|
||||||
import { PG } from "./ed-global";
|
import { PG } from "./ed-global";
|
||||||
import { fetchViaProxy } from "../../vi/load/proxy";
|
import { fetchViaProxy } from "../../../base/load/proxy";
|
||||||
|
import { ApiProxy, apiProxy } from "../../../base/load/api/api-proxy";
|
||||||
|
|
||||||
let w = window as unknown as { db: ReturnType<typeof dbClient> };
|
let w = window as unknown as {
|
||||||
|
db: ReturnType<typeof dbProxy>;
|
||||||
|
api: ApiProxy;
|
||||||
|
};
|
||||||
|
|
||||||
export const edInit = async (p: PG) => {
|
export const edInit = async (p: PG) => {
|
||||||
p.status = "ready";
|
p.status = "ready";
|
||||||
|
|
||||||
const cur = new URL(location.href);
|
|
||||||
w.db = dbClient("prasi", `${cur.protocol}//${cur.host}`);
|
|
||||||
|
|
||||||
await init();
|
await init();
|
||||||
jscript.init(p.render, { esbuild: false });
|
jscript.init(p.render, { esbuild: false });
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { IContent } from "../../../../utils/types/general";
|
import { IContent } from "../../../../utils/types/general";
|
||||||
import { VG } from "../../../vi/render/global";
|
import { VG } from "../../../vi/render/global";
|
||||||
import { IMeta, PG, active } from "../../logic/ed-global";
|
import { IMeta, PG, active } from "../../logic/ed-global";
|
||||||
|
import { treeRebuild } from "../../logic/tree/build";
|
||||||
|
|
||||||
type MPIVParam = Parameters<Exclude<VG["visit"], undefined>>;
|
type MPIVParam = Parameters<Exclude<VG["visit"], undefined>>;
|
||||||
export const mainPerItemVisit = (
|
export const mainPerItemVisit = (
|
||||||
|
|
@ -59,6 +60,12 @@ export const mainPerItemVisit = (
|
||||||
parts.props.onPointerDown = (e) => {
|
parts.props.onPointerDown = (e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|
||||||
|
if (active.comp_id && !p.comp.list[active.comp_id]) {
|
||||||
|
active.comp_id = "";
|
||||||
|
treeRebuild(p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const item = getOuterItem(
|
const item = getOuterItem(
|
||||||
{
|
{
|
||||||
meta: active.comp_id ? p.comp.list[active.comp_id].meta : p.page.meta,
|
meta: active.comp_id ? p.comp.list[active.comp_id].meta : p.page.meta,
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,7 @@ export const EdPopUser = ({
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
{user.all.length > 0 && onAdd && (
|
{Array.isArray(user.all) && user.all.length > 0 && onAdd && (
|
||||||
<Select
|
<Select
|
||||||
options={user.all
|
options={user.all
|
||||||
.filter((e) => {
|
.filter((e) => {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
import Downshift from "downshift";
|
import Downshift from "downshift";
|
||||||
import { FC, useEffect } from "react";
|
import { FC, useEffect } from "react";
|
||||||
import { useGlobal, useLocal } from "web-utils";
|
import { useGlobal, useLocal } from "web-utils";
|
||||||
import { createAPI, createDB } from "../../../../../utils/script/init-api";
|
import { apiProxy } from "../../../../../base/load/api/api-proxy";
|
||||||
|
import { dbProxy } from "../../../../../base/load/db/db-proxy";
|
||||||
import { FMCompDef, FNCompDef } from "../../../../../utils/types/meta-fn";
|
import { FMCompDef, FNCompDef } from "../../../../../utils/types/meta-fn";
|
||||||
import { EDGlobal } from "../../../logic/ed-global";
|
import { EDGlobal } from "../../../logic/ed-global";
|
||||||
import { EdPropLabel } from "./prop-label";
|
import { EdPropLabel } from "./prop-label";
|
||||||
|
|
@ -27,8 +28,8 @@ export const EdPropInstanceOptions: FC<{
|
||||||
if (!local.loaded) {
|
if (!local.loaded) {
|
||||||
try {
|
try {
|
||||||
if (p.site.config.api_url) {
|
if (p.site.config.api_url) {
|
||||||
if (!p.script.db) p.script.db = createDB(p.site.config.api_url);
|
if (!p.script.db) p.script.db = dbProxy(p.site.config.api_url);
|
||||||
if (!p.script.api) p.script.api = createAPI(p.site.config.api_url);
|
if (!p.script.api) p.script.api = apiProxy(p.site.config.api_url);
|
||||||
}
|
}
|
||||||
|
|
||||||
const args = {
|
const args = {
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,12 @@
|
||||||
import get from "lodash.get";
|
import get from "lodash.get";
|
||||||
import {
|
import { apiProxy } from "../../../base/load/api/api-proxy";
|
||||||
createAPI,
|
import { dbProxy } from "../../../base/load/db/db-proxy";
|
||||||
createDB,
|
import { jscript } from "../../../utils/script/jscript";
|
||||||
initApi,
|
import { devLoader } from "../../live/dev-loader";
|
||||||
reloadDBAPI,
|
|
||||||
} from "../../../utils/script/init-api";
|
|
||||||
import { LSite } from "../../live/logic/global";
|
import { LSite } from "../../live/logic/global";
|
||||||
import { validateLayout } from "../../live/logic/layout";
|
import { validateLayout } from "../../live/logic/layout";
|
||||||
import importModule from "../tools/dynamic-import";
|
import importModule from "../tools/dynamic-import";
|
||||||
import { EditorGlobal, PG } from "./global";
|
import { EditorGlobal, PG } from "./global";
|
||||||
import { devLoader } from "../../live/dev-loader";
|
|
||||||
import { jscript } from "../../../utils/script/jscript";
|
|
||||||
import { deepClone } from "web-utils";
|
|
||||||
|
|
||||||
export const w = window as unknown as {
|
export const w = window as unknown as {
|
||||||
basepath: string;
|
basepath: string;
|
||||||
|
|
@ -121,7 +116,7 @@ export const initEditor = async (p: PG, site_id: string) => {
|
||||||
prodUrl: localStorage.getItem(`prasi-ext-prod-url-${p.site.id}`) || "",
|
prodUrl: localStorage.getItem(`prasi-ext-prod-url-${p.site.id}`) || "",
|
||||||
};
|
};
|
||||||
|
|
||||||
p.site.api_url = await initApi(site.config);
|
p.site.api_url = site.config.api_url;
|
||||||
|
|
||||||
if (w.externalAPI.prodUrl !== p.site.api_url) {
|
if (w.externalAPI.prodUrl !== p.site.api_url) {
|
||||||
w.externalAPI.prodUrl = p.site.api_url;
|
w.externalAPI.prodUrl = p.site.api_url;
|
||||||
|
|
@ -129,7 +124,6 @@ export const initEditor = async (p: PG, site_id: string) => {
|
||||||
}
|
}
|
||||||
if (w.externalAPI.mode === "dev" && w.externalAPI.devUrl) {
|
if (w.externalAPI.mode === "dev" && w.externalAPI.devUrl) {
|
||||||
p.site.api_url = w.externalAPI.devUrl;
|
p.site.api_url = w.externalAPI.devUrl;
|
||||||
await reloadDBAPI(w.externalAPI.devUrl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
w.apiurl = p.site.api_url;
|
w.apiurl = p.site.api_url;
|
||||||
|
|
@ -173,8 +167,8 @@ export const execSiteJS = (p: PG) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const fn = p.site.js_compiled;
|
const fn = p.site.js_compiled;
|
||||||
scope["api"] = createAPI(p.site.api_url);
|
scope["api"] = apiProxy(p.site.api_url);
|
||||||
scope["db"] = createDB(p.site.api_url);
|
scope["db"] = dbProxy(p.site.api_url);
|
||||||
const f = new Function(...Object.keys(scope), fn);
|
const f = new Function(...Object.keys(scope), fn);
|
||||||
try {
|
try {
|
||||||
const res = f(...Object.values(scope));
|
const res = f(...Object.values(scope));
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { FC } from "react";
|
import { FC } from "react";
|
||||||
import { createAPI, createDB } from "../../../utils/script/init-api";
|
import { apiProxy } from "../../../base/load/api/api-proxy";
|
||||||
|
import { dbProxy } from "../../../base/load/db/db-proxy";
|
||||||
import { FNCompDef } from "../../../utils/types/meta-fn";
|
import { FNCompDef } from "../../../utils/types/meta-fn";
|
||||||
import { EItem } from "../elements/e-item";
|
import { EItem } from "../elements/e-item";
|
||||||
import { ItemMeta, PG } from "./global";
|
import { ItemMeta, PG } from "./global";
|
||||||
|
|
@ -15,8 +16,8 @@ export const treePropEval = (
|
||||||
) => {
|
) => {
|
||||||
if (meta.item.type === "item" && meta.item.component) {
|
if (meta.item.type === "item" && meta.item.component) {
|
||||||
if (p.site.api_url) {
|
if (p.site.api_url) {
|
||||||
if (!p.script.db) p.script.db = createDB(p.site.api_url);
|
if (!p.script.db) p.script.db = dbProxy(p.site.api_url);
|
||||||
if (!p.script.api) p.script.api = createAPI(p.site.api_url);
|
if (!p.script.api) p.script.api = apiProxy(p.site.api_url);
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = meta.item.component.props;
|
const props = meta.item.component.props;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { FC, ReactNode, Suspense, useEffect } from "react";
|
import { FC, ReactNode, Suspense, useEffect } from "react";
|
||||||
import { deepClone } from "web-utils";
|
import { deepClone } from "web-utils";
|
||||||
import { createAPI, createDB } from "../../../utils/script/init-api";
|
import { apiProxy } from "../../../base/load/api/api-proxy";
|
||||||
|
import { dbProxy } from "../../../base/load/db/db-proxy";
|
||||||
import { ErrorBox } from "../elements/e-error";
|
import { ErrorBox } from "../elements/e-error";
|
||||||
import { ItemMeta, PG } from "./global";
|
import { ItemMeta, PG } from "./global";
|
||||||
|
|
||||||
|
|
@ -30,8 +31,8 @@ export const treeScopeEval = (
|
||||||
|
|
||||||
// prepare args
|
// prepare args
|
||||||
if (p.site.api_url) {
|
if (p.site.api_url) {
|
||||||
if (!p.script.db) p.script.db = createDB(p.site.api_url);
|
if (!p.script.db) p.script.db = dbProxy(p.site.api_url);
|
||||||
if (!p.script.api) p.script.api = createAPI(p.site.api_url);
|
if (!p.script.api) p.script.api = apiProxy(p.site.api_url);
|
||||||
}
|
}
|
||||||
const w = window as any;
|
const w = window as any;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ import { useGlobal } from "web-utils";
|
||||||
import { EditorGlobal } from "../../../../logic/global";
|
import { EditorGlobal } from "../../../../logic/global";
|
||||||
import { ExternalDeploy } from "./ExternalDeploy";
|
import { ExternalDeploy } from "./ExternalDeploy";
|
||||||
import { w } from "../../../../logic/init";
|
import { w } from "../../../../logic/init";
|
||||||
import { reloadDBAPI } from "../../../../../../utils/script/init-api";
|
|
||||||
|
|
||||||
export const ExternalAPI = ({
|
export const ExternalAPI = ({
|
||||||
status,
|
status,
|
||||||
|
|
@ -88,11 +87,9 @@ export const ExternalAPI = ({
|
||||||
if (w.externalAPI.mode === "dev") {
|
if (w.externalAPI.mode === "dev") {
|
||||||
p.site.api_url = w.externalAPI.devUrl;
|
p.site.api_url = w.externalAPI.devUrl;
|
||||||
checkApi();
|
checkApi();
|
||||||
await reloadDBAPI(w.externalAPI.devUrl, "dev");
|
|
||||||
} else {
|
} else {
|
||||||
p.site.api_url = w.externalAPI.prodUrl;
|
p.site.api_url = w.externalAPI.prodUrl;
|
||||||
checkApi();
|
checkApi();
|
||||||
await reloadDBAPI(w.externalAPI.prodUrl, "dev");
|
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,9 @@ import { formatDistance } from "date-fns/esm";
|
||||||
import trim from "lodash.trim";
|
import trim from "lodash.trim";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { deepClone, useGlobal, useLocal } from "web-utils";
|
import { deepClone, useGlobal, useLocal } from "web-utils";
|
||||||
import { createAPI } from "../../../../../../utils/script/init-api";
|
|
||||||
import { AutoHeightTextarea } from "../../../../../../utils/ui/auto-textarea";
|
import { AutoHeightTextarea } from "../../../../../../utils/ui/auto-textarea";
|
||||||
import { EditorGlobal } from "../../../../logic/global";
|
import { EditorGlobal } from "../../../../logic/global";
|
||||||
|
import { apiProxy } from "../../../../../../base/load/api/api-proxy";
|
||||||
|
|
||||||
const server = {
|
const server = {
|
||||||
status: "ready" as
|
status: "ready" as
|
||||||
|
|
@ -40,7 +40,7 @@ export const ExternalDeploy = () => {
|
||||||
try {
|
try {
|
||||||
const url = p.site.api_url;
|
const url = p.site.api_url;
|
||||||
|
|
||||||
local.api = createAPI(url);
|
local.api = apiProxy(url);
|
||||||
let res = await local.api._deploy({
|
let res = await local.api._deploy({
|
||||||
type: "check",
|
type: "check",
|
||||||
id_site: p.site.id,
|
id_site: p.site.id,
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import trim from "lodash.trim";
|
||||||
import { EditorGlobal } from "../../../../logic/global";
|
import { EditorGlobal } from "../../../../logic/global";
|
||||||
import { Loading } from "../../../../../../utils/ui/loading";
|
import { Loading } from "../../../../../../utils/ui/loading";
|
||||||
import { w } from "../../../../../../utils/types/general";
|
import { w } from "../../../../../../utils/types/general";
|
||||||
import { reloadDBAPI } from "../../../../../../utils/script/init-api";
|
|
||||||
|
|
||||||
export const InternalAPI: FC<{
|
export const InternalAPI: FC<{
|
||||||
close: () => void;
|
close: () => void;
|
||||||
|
|
@ -178,10 +177,6 @@ export const InternalAPI: FC<{
|
||||||
config.api_url = `https://${p.site.api_prasi.port}.prasi.world`;
|
config.api_url = `https://${p.site.api_prasi.port}.prasi.world`;
|
||||||
|
|
||||||
const base = trim(config.api_url, "/");
|
const base = trim(config.api_url, "/");
|
||||||
|
|
||||||
try {
|
|
||||||
await reloadDBAPI(base);
|
|
||||||
} catch (e) {}
|
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
|
|
@ -198,16 +193,7 @@ export const InternalAPI: FC<{
|
||||||
|
|
||||||
<div
|
<div
|
||||||
className={cx("cursor-pointer hover:underline")}
|
className={cx("cursor-pointer hover:underline")}
|
||||||
onClick={async () => {
|
onClick={async () => {}}
|
||||||
local.clearingCache = true;
|
|
||||||
local.render();
|
|
||||||
try {
|
|
||||||
await reloadDBAPI(p.site.api_url, "dev");
|
|
||||||
} catch (e) {}
|
|
||||||
local.clearingCache = false;
|
|
||||||
local.render();
|
|
||||||
alert("API Cache Cleared");
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{local.clearingCache ? "Clearing Cache..." : "Clear API Cache"}
|
{local.clearingCache ? "Clearing Cache..." : "Clear API Cache"}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { createRouter } from "radix3";
|
import { createRouter } from "radix3";
|
||||||
import { validate } from "uuid";
|
import { validate } from "uuid";
|
||||||
import { type apiClient } from "web-utils";
|
import { apiProxy } from "../../../base/load/api/api-proxy";
|
||||||
import { createAPI, createDB, initApi } from "../../../utils/script/init-api";
|
import { dbProxy } from "../../../base/load/db/db-proxy";
|
||||||
import importModule from "../../editor/tools/dynamic-import";
|
import importModule from "../../editor/tools/dynamic-import";
|
||||||
import { LSite, PG } from "./global";
|
import { LSite, PG } from "./global";
|
||||||
import { validateLayout } from "./layout";
|
import { validateLayout } from "./layout";
|
||||||
|
|
@ -17,7 +17,6 @@ export const w = window as unknown as {
|
||||||
isDesktop: boolean;
|
isDesktop: boolean;
|
||||||
exports: any;
|
exports: any;
|
||||||
params: any;
|
params: any;
|
||||||
apiClient: typeof apiClient;
|
|
||||||
apiurl: string;
|
apiurl: string;
|
||||||
preload: (path: string) => void;
|
preload: (path: string) => void;
|
||||||
mobile?: ReturnType<typeof registerMobile>;
|
mobile?: ReturnType<typeof registerMobile>;
|
||||||
|
|
@ -94,7 +93,7 @@ export const initLive = async (p: PG, domain_or_siteid: string) => {
|
||||||
|
|
||||||
await validateLayout(p);
|
await validateLayout(p);
|
||||||
|
|
||||||
p.site.api_url = await initApi(site.config, "prod");
|
p.site.api_url = site.config.api_url || "";
|
||||||
|
|
||||||
w.apiurl = p.site.api_url;
|
w.apiurl = p.site.api_url;
|
||||||
|
|
||||||
|
|
@ -104,8 +103,8 @@ export const initLive = async (p: PG, domain_or_siteid: string) => {
|
||||||
const exec = (fn: string, scopes: any) => {
|
const exec = (fn: string, scopes: any) => {
|
||||||
if (p) {
|
if (p) {
|
||||||
if (p.site.api_url) {
|
if (p.site.api_url) {
|
||||||
scopes["api"] = createAPI(p.site.api_url);
|
scopes["api"] = apiProxy(p.site.api_url);
|
||||||
scopes["db"] = createDB(p.site.api_url);
|
scopes["db"] = dbProxy(p.site.api_url);
|
||||||
}
|
}
|
||||||
if (!w.params) {
|
if (!w.params) {
|
||||||
w.params = {};
|
w.params = {};
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { w } from "../../../utils/script/init-api";
|
import { w } from "../../../utils/types/general";
|
||||||
import { PG } from "./global";
|
import { PG } from "./global";
|
||||||
|
|
||||||
type NOTIF_ARG = {
|
type NOTIF_ARG = {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { FC } from "react";
|
import { FC } from "react";
|
||||||
import { createAPI, createDB } from "../../../utils/script/init-api";
|
import { apiProxy } from "../../../base/load/api/api-proxy";
|
||||||
|
import { dbProxy } from "../../../base/load/db/db-proxy";
|
||||||
import { FNCompDef } from "../../../utils/types/meta-fn";
|
import { FNCompDef } from "../../../utils/types/meta-fn";
|
||||||
import { LItem } from "../elements/l-item";
|
import { LItem } from "../elements/l-item";
|
||||||
import { PG } from "./global";
|
import { PG } from "./global";
|
||||||
|
|
@ -19,8 +20,8 @@ export const treePropEval = (
|
||||||
|
|
||||||
if (meta.item.type === "item" && meta.item.component) {
|
if (meta.item.type === "item" && meta.item.component) {
|
||||||
if (p.site.api_url) {
|
if (p.site.api_url) {
|
||||||
if (!p.script.db) p.script.db = createDB(p.site.api_url);
|
if (!p.script.db) p.script.db = dbProxy(p.site.api_url);
|
||||||
if (!p.script.api) p.script.api = createAPI(p.site.api_url);
|
if (!p.script.api) p.script.api = apiProxy(p.site.api_url);
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = meta.item.component.props;
|
const props = meta.item.component.props;
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
|
import hash_sum from "hash-sum";
|
||||||
import { FC, ReactNode, Suspense, useEffect, useState } from "react";
|
import { FC, ReactNode, Suspense, useEffect, useState } from "react";
|
||||||
import { deepClone } from "web-utils";
|
import { deepClone } from "web-utils";
|
||||||
import { createAPI, createDB } from "../../../utils/script/init-api";
|
import { apiProxy } from "../../../base/load/api/api-proxy";
|
||||||
|
import { dbProxy } from "../../../base/load/db/db-proxy";
|
||||||
import { ErrorBox } from "../../editor/elements/e-error";
|
import { ErrorBox } from "../../editor/elements/e-error";
|
||||||
import { ItemMeta, PG } from "./global";
|
import { ItemMeta, PG } from "./global";
|
||||||
import { extractNavigate, preload } from "./route";
|
import { extractNavigate, preload } from "./route";
|
||||||
import hash_sum from "hash-sum";
|
|
||||||
|
|
||||||
export const JS_DEBUG = false;
|
export const JS_DEBUG = false;
|
||||||
|
|
||||||
|
|
@ -43,8 +44,8 @@ export const treeScopeEval = (
|
||||||
|
|
||||||
// prepare args
|
// prepare args
|
||||||
if (p.site.api_url) {
|
if (p.site.api_url) {
|
||||||
if (!p.script.db) p.script.db = createDB(p.site.api_url);
|
if (!p.script.db) p.script.db = dbProxy(p.site.api_url);
|
||||||
if (!p.script.api) p.script.api = createAPI(p.site.api_url);
|
if (!p.script.api) p.script.api = apiProxy(p.site.api_url);
|
||||||
}
|
}
|
||||||
const w = window as any;
|
const w = window as any;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { w } from "../../utils/script/init-api";
|
import { w } from "../../utils/types/general";
|
||||||
import { Loader } from "../live/logic/global";
|
import { Loader } from "../live/logic/global";
|
||||||
|
|
||||||
const cache = {
|
const cache = {
|
||||||
|
|
@ -55,7 +55,7 @@ export const mobileLoader: Loader = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const load = async (url: string) => {
|
const load = async (url: string) => {
|
||||||
const res = await fetch(`${w.mobilepath}${url}`);
|
const res = await fetch(`${(w as any).mobilepath}${url}`);
|
||||||
try {
|
try {
|
||||||
const text = await res.text();
|
const text = await res.text();
|
||||||
const json = JSON.parse(text);
|
const json = JSON.parse(text);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { w } from "../../utils/script/init-api";
|
import { w } from "../../utils/types/general";
|
||||||
import { Loader } from "../live/logic/global";
|
import { Loader } from "../live/logic/global";
|
||||||
|
|
||||||
const base = `/_web/${(window as any).id_site}`;
|
const base = `/_web/${(window as any).id_site}`;
|
||||||
|
|
|
||||||
|
|
@ -1,154 +0,0 @@
|
||||||
import { createStore, get, set } from "idb-keyval";
|
|
||||||
import trim from "lodash.trim";
|
|
||||||
import { apiClient, dbClient, waitUntil } from "web-utils";
|
|
||||||
import { createFrameCors } from "web-utils";
|
|
||||||
export const w = window as unknown as {
|
|
||||||
prasiApi: Record<string, any>;
|
|
||||||
apiHeaders: any;
|
|
||||||
apiClient: typeof apiClient;
|
|
||||||
dbClient: typeof dbClient;
|
|
||||||
serverurl: string;
|
|
||||||
apiurl: string;
|
|
||||||
mobilepath: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const createAPI = (url: string) => {
|
|
||||||
if (!w.apiClient) {
|
|
||||||
w.apiClient = apiClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!w.prasiApi) {
|
|
||||||
w.prasiApi = {};
|
|
||||||
}
|
|
||||||
if (!url) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return w.apiClient(w.prasiApi[url]?.apiEntry, url);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const createDB = (url: string) => {
|
|
||||||
if (!w.dbClient) {
|
|
||||||
w.dbClient = dbClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
const dbc: typeof dbClient = w.dbClient;
|
|
||||||
return dbc("db", url);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const initApi = async (config: any, mode: "dev" | "prod" = "dev") => {
|
|
||||||
let url = "";
|
|
||||||
if (config.prasi) {
|
|
||||||
if (
|
|
||||||
!(
|
|
||||||
location.hostname === "prasi.app" ||
|
|
||||||
location.hostname === "api.prasi.app"
|
|
||||||
) // android localhost
|
|
||||||
) {
|
|
||||||
if (
|
|
||||||
location.hostname === "localhost" ||
|
|
||||||
location.hostname === "127.0.0.1" ||
|
|
||||||
location.hostname === "10.0.2.2"
|
|
||||||
) {
|
|
||||||
url = `https://${config.prasi.port}.prasi.world`;
|
|
||||||
} else {
|
|
||||||
url = `https://${location.hostname}:${config.prasi.port}`;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
url = `https://${config.prasi.port}.prasi.world`;
|
|
||||||
}
|
|
||||||
} else if (config.api_url) {
|
|
||||||
url = config.api_url;
|
|
||||||
}
|
|
||||||
if (!w.prasiApi) {
|
|
||||||
w.prasiApi = {};
|
|
||||||
}
|
|
||||||
if (url) {
|
|
||||||
if (!w.prasiApi[url]) {
|
|
||||||
try {
|
|
||||||
await reloadDBAPI(url, mode);
|
|
||||||
} catch (e) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return url;
|
|
||||||
};
|
|
||||||
|
|
||||||
const loadText = async (url: string, v2?: boolean) => {
|
|
||||||
const res = await fetch(url);
|
|
||||||
return await res.text();
|
|
||||||
};
|
|
||||||
|
|
||||||
export const reloadDBAPI = async (
|
|
||||||
url: string,
|
|
||||||
mode: "dev" | "prod" = "dev"
|
|
||||||
) => {
|
|
||||||
const base = trim(url, "/");
|
|
||||||
|
|
||||||
if (!w.prasiApi) {
|
|
||||||
w.prasiApi = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
const cache = createStore(`prasi-api`, "config");
|
|
||||||
|
|
||||||
const forceReload = async () => {
|
|
||||||
if (!w.prasiApi[url]) {
|
|
||||||
w.prasiApi[url] = {};
|
|
||||||
}
|
|
||||||
const frm = await createFrameCors(base);
|
|
||||||
const raw = await frm.sendRaw(`/_prasi/_`);
|
|
||||||
let ver = "";
|
|
||||||
if (raw && (raw as any).prasi) {
|
|
||||||
ver = (raw as any).prasi;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ver === "v2") {
|
|
||||||
await new Promise<void>((done) => {
|
|
||||||
const d = document;
|
|
||||||
const script = d.createElement("script");
|
|
||||||
script.onload = async () => {
|
|
||||||
done();
|
|
||||||
};
|
|
||||||
script.src = `${base}/_prasi/load.js?url=${url}${
|
|
||||||
mode === "dev" ? "&dev=1" : ""
|
|
||||||
}`;
|
|
||||||
d.body.appendChild(script);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
const apiTypes = await fetch(base + "/_prasi/api-types");
|
|
||||||
const apiEntry = await fetch(base + "/_prasi/api-entry");
|
|
||||||
w.prasiApi[url] = {
|
|
||||||
apiEntry: (await apiEntry.json()).srv,
|
|
||||||
prismaTypes: {
|
|
||||||
"prisma.d.ts": await loadText(`${base}/_prasi/prisma/index.d.ts`),
|
|
||||||
"runtime/index.d.ts": await loadText(
|
|
||||||
`${base}/_prasi/prisma/runtime/index.d.ts`
|
|
||||||
),
|
|
||||||
"runtime/library.d.ts": await loadText(
|
|
||||||
`${base}/_prasi/prisma/runtime/library.d.ts`
|
|
||||||
),
|
|
||||||
},
|
|
||||||
apiTypes: await apiTypes.text(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
await set(url, JSON.stringify(w.prasiApi[url]), cache);
|
|
||||||
};
|
|
||||||
const prasiBase = `${location.protocol}//${location.host}`;
|
|
||||||
|
|
||||||
try {
|
|
||||||
const found = await get(url, cache);
|
|
||||||
if (found) {
|
|
||||||
w.prasiApi[url] = JSON.parse(found);
|
|
||||||
await forceReload();
|
|
||||||
} else {
|
|
||||||
await forceReload();
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.warn("Failed to load API");
|
|
||||||
|
|
||||||
if (url === prasiBase) {
|
|
||||||
console.error("Failed to load prasi. Reloading...");
|
|
||||||
setTimeout(() => location.reload(), 3000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
@ -12,12 +12,12 @@ export type PageProps = {
|
||||||
|
|
||||||
export type PrasiAPI = {
|
export type PrasiAPI = {
|
||||||
apiEntry: any;
|
apiEntry: any;
|
||||||
prismaTypes: {
|
prismaTypes?: {
|
||||||
"prisma.d.ts": string;
|
"prisma.d.ts": string;
|
||||||
"runtime/library.d.ts": string;
|
"runtime/library.d.ts": string;
|
||||||
"runtime/index.d.ts": string;
|
"runtime/index.d.ts": string;
|
||||||
};
|
};
|
||||||
apiTypes: string;
|
apiTypes?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const w = window as unknown as {
|
export const w = window as unknown as {
|
||||||
|
|
@ -32,6 +32,7 @@ export const w = window as unknown as {
|
||||||
editorGlbDefault: string;
|
editorGlbDefault: string;
|
||||||
ts: number;
|
ts: number;
|
||||||
serverurl: string;
|
serverurl: string;
|
||||||
|
apiurl: string;
|
||||||
api: any;
|
api: any;
|
||||||
db: any;
|
db: any;
|
||||||
offline: boolean;
|
offline: boolean;
|
||||||
|
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
import { apiContext } from "../server/api/api-ctx";
|
|
||||||
import { g } from "../utils/global";
|
|
||||||
|
|
||||||
export const _ = {
|
|
||||||
url: "/_api_frm",
|
|
||||||
async api() {
|
|
||||||
const { req, res } = apiContext(this);
|
|
||||||
let allowUrl = req.headers.get("origin") || req.headers.get("referer");
|
|
||||||
|
|
||||||
res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT");
|
|
||||||
res.setHeader("Access-Control-Allow-Headers", "content-type");
|
|
||||||
res.setHeader("Access-Control-Allow-Credentials", "true");
|
|
||||||
if (allowUrl) {
|
|
||||||
res.setHeader("Access-Control-Allow-Origin", allowUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
res.setHeader("content-type", "text/html");
|
|
||||||
res.setHeader("etag", g.frm.etag);
|
|
||||||
res.send(`<script>${g.frm.js}</script>`);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
@ -2,8 +2,8 @@ import { apiContext } from "../server/api/api-ctx";
|
||||||
import { DBArg, execQuery } from "../utils/query";
|
import { DBArg, execQuery } from "../utils/query";
|
||||||
|
|
||||||
export const _ = {
|
export const _ = {
|
||||||
url: "/_dbs/:dbName/:action",
|
url: "/_dbs/:action",
|
||||||
async api(dbName: any, action?: string) {
|
async api(action?: string) {
|
||||||
const { req, res } = apiContext(this);
|
const { req, res } = apiContext(this);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import { createRouter } from "radix3";
|
import { createRouter } from "radix3";
|
||||||
import { g } from "utils/global";
|
import { g } from "utils/global";
|
||||||
import { createResponse } from "./api/api-ctx";
|
import { createResponse } from "./api/api-ctx";
|
||||||
import { prepareApiRoutes } from "./api/api-scan";
|
|
||||||
|
|
||||||
export const serveAPI = {
|
export const serveAPI = {
|
||||||
init: async () => {
|
init: async () => {
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,6 @@ export const serveStatic = {
|
||||||
if (filename) {
|
if (filename) {
|
||||||
const path = join("static", filename);
|
const path = join("static", filename);
|
||||||
const file = Bun.file(dir.path(`app/${path}`));
|
const file = Bun.file(dir.path(`app/${path}`));
|
||||||
console.log(_, filename);
|
|
||||||
if (await file.exists()) {
|
if (await file.exists()) {
|
||||||
cache.static[`/${filename}`] = {
|
cache.static[`/${filename}`] = {
|
||||||
type: mime.getType(path) || "application/octet-stream",
|
type: mime.getType(path) || "application/octet-stream",
|
||||||
|
|
|
||||||
|
|
@ -1,205 +0,0 @@
|
||||||
import { waitUntil } from "web-utils";
|
|
||||||
import { createId } from "@paralleldrive/cuid2";
|
|
||||||
const cuid = createId;
|
|
||||||
|
|
||||||
(BigInt.prototype as any).toJSON = function (): string {
|
|
||||||
return `BigInt::` + this.toString();
|
|
||||||
};
|
|
||||||
|
|
||||||
export const createFrameCors = async (url: string, win?: any) => {
|
|
||||||
let w = window;
|
|
||||||
if (!!win) {
|
|
||||||
w = win;
|
|
||||||
}
|
|
||||||
const document = w.document;
|
|
||||||
|
|
||||||
const id = `__` + url.replace(/\W/g, "");
|
|
||||||
|
|
||||||
if (typeof document !== "undefined" && !document.querySelector(`#${id}`)) {
|
|
||||||
const iframe = document.createElement("iframe");
|
|
||||||
iframe.style.display = "none";
|
|
||||||
iframe.id = id;
|
|
||||||
|
|
||||||
const _url = new URL(url);
|
|
||||||
_url.pathname = "/_api_frm";
|
|
||||||
iframe.src = _url.toString();
|
|
||||||
|
|
||||||
await new Promise<void>((resolve, reject) => {
|
|
||||||
iframe.onload = () => {
|
|
||||||
if (!iframe.contentDocument) {
|
|
||||||
setTimeout(() => {
|
|
||||||
if (!iframe.contentDocument) {
|
|
||||||
reject(
|
|
||||||
`Cannot load iframe ${_url.toString()}. content document not found.`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}, 100);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const onInit = (e: any) => {
|
|
||||||
if (e.data === "initialized") {
|
|
||||||
iframe.setAttribute("loaded", "y");
|
|
||||||
w.removeEventListener("message", onInit);
|
|
||||||
resolve();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
w.addEventListener("message", onInit);
|
|
||||||
|
|
||||||
document.body.appendChild(iframe);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const wm = {} as Record<string, any>;
|
|
||||||
|
|
||||||
const sendRaw = async (
|
|
||||||
input: RequestInfo | URL,
|
|
||||||
init?: RequestInit | undefined
|
|
||||||
) => {
|
|
||||||
if (w.document && w.document.querySelector) {
|
|
||||||
const iframe = w.document.querySelector(`#${id}`) as HTMLIFrameElement;
|
|
||||||
|
|
||||||
if (
|
|
||||||
!iframe ||
|
|
||||||
!iframe.contentWindow ||
|
|
||||||
(iframe && iframe.getAttribute("loaded") !== "y")
|
|
||||||
) {
|
|
||||||
await waitUntil(
|
|
||||||
() =>
|
|
||||||
iframe &&
|
|
||||||
iframe.contentWindow &&
|
|
||||||
iframe.getAttribute("loaded") === "y"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return await new Promise((resolve, reject) => {
|
|
||||||
if (iframe && iframe.contentWindow) {
|
|
||||||
const id = cuid();
|
|
||||||
wm[id] = (e: any) => {
|
|
||||||
if (id === e.data.id) {
|
|
||||||
w.removeEventListener("message", wm[id]);
|
|
||||||
delete wm[id];
|
|
||||||
if (e.data.error) {
|
|
||||||
let err = e.data.error;
|
|
||||||
if (typeof err === "string") {
|
|
||||||
reject(
|
|
||||||
err.replace(
|
|
||||||
/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g,
|
|
||||||
""
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
resolve(e.data.result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
w.addEventListener("message", wm[id]);
|
|
||||||
|
|
||||||
let _input = input;
|
|
||||||
if (typeof input === "string") {
|
|
||||||
if (!input.startsWith("http")) {
|
|
||||||
_input = `${url}${input}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
iframe.contentWindow.postMessage({ input: _input, init, id }, "*");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
sendRaw,
|
|
||||||
async send(input: string | RequestInfo | URL, data?: any, _headers?: any) {
|
|
||||||
const uri = input.toString();
|
|
||||||
const headers = { ..._headers };
|
|
||||||
|
|
||||||
let body = data;
|
|
||||||
let isFile = false;
|
|
||||||
|
|
||||||
const formatSingle = async (data: any) => {
|
|
||||||
if (!(data instanceof w.FormData || data instanceof w.File)) {
|
|
||||||
headers["content-type"] = "application/json";
|
|
||||||
} else {
|
|
||||||
if (data instanceof w.File) {
|
|
||||||
isFile = true;
|
|
||||||
let ab = await new Promise<ArrayBuffer | undefined>((resolve) => {
|
|
||||||
const reader = new FileReader();
|
|
||||||
reader.addEventListener("load", (e) => {
|
|
||||||
resolve(e.target?.result as ArrayBuffer);
|
|
||||||
});
|
|
||||||
reader.readAsArrayBuffer(data);
|
|
||||||
});
|
|
||||||
if (ab) {
|
|
||||||
data = new File([ab], data.name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (Array.isArray(data)) {
|
|
||||||
body = await Promise.all(data.map((e) => formatSingle(e)));
|
|
||||||
} else {
|
|
||||||
body = await formatSingle(data);
|
|
||||||
}
|
|
||||||
if (!isFile) {
|
|
||||||
body = JSON.stringify(body);
|
|
||||||
}
|
|
||||||
|
|
||||||
return await sendRaw(
|
|
||||||
`${url.endsWith("/") ? url : `${url}/`}${
|
|
||||||
uri.startsWith("/") ? uri.substring(1) : uri
|
|
||||||
}`,
|
|
||||||
data
|
|
||||||
? {
|
|
||||||
method: "post",
|
|
||||||
headers,
|
|
||||||
body,
|
|
||||||
}
|
|
||||||
: {}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const fetchSendApi = async (
|
|
||||||
rawUrl: string,
|
|
||||||
params: any,
|
|
||||||
parentWindow?: any
|
|
||||||
) => {
|
|
||||||
let w: any = typeof window === "object" ? window : globalThis;
|
|
||||||
|
|
||||||
const win = parentWindow || w;
|
|
||||||
const url = new URL(rawUrl);
|
|
||||||
let frm: Awaited<ReturnType<typeof createFrameCors>>;
|
|
||||||
|
|
||||||
const base = `${url.protocol}//${url.host}`;
|
|
||||||
|
|
||||||
if (!win.frmapi) {
|
|
||||||
win.frmapi = {};
|
|
||||||
}
|
|
||||||
if (!win.frmapi[base]) {
|
|
||||||
win.frmapi[base] = await createFrameCors(base, win);
|
|
||||||
}
|
|
||||||
|
|
||||||
frm = win.frmapi[base];
|
|
||||||
|
|
||||||
if (!win.apiHeaders) {
|
|
||||||
win.apiHeaders = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!frm) {
|
|
||||||
await waitUntil(() => {
|
|
||||||
frm = win.frmapi[base];
|
|
||||||
return frm;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (url.pathname.startsWith("//")) {
|
|
||||||
url.pathname = url.pathname.substring(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return await frm.send(url.pathname, params, win.apiHeaders);
|
|
||||||
};
|
|
||||||
|
|
@ -7,7 +7,4 @@ export * from "./page";
|
||||||
export * from "./global";
|
export * from "./global";
|
||||||
export * from "./define-react";
|
export * from "./define-react";
|
||||||
export * from "./define-window";
|
export * from "./define-window";
|
||||||
export * from './client-api';
|
|
||||||
export * from './client-frame';
|
|
||||||
export * from './client-db';
|
|
||||||
export const React = _React;
|
export const React = _React;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue