@dnax/core 0.66.2 → 0.67.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/hono.ts +19 -36
- package/app/index.ts +87 -107
- package/config/index.ts +2 -18
- package/driver/mongo/@types.ts +15 -0
- package/driver/mongo/connect.ts +2 -2
- package/driver/mongo/database.ts +85 -0
- package/driver/mongo/rest.ts +6 -133
- package/index.ts +2 -4
- package/lib/asyncLocalStorage.ts +0 -1
- package/lib/bento/index.ts +1 -58
- package/lib/collection.ts +1 -1
- package/lib/index.ts +29 -5
- package/package.json +11 -11
- package/types/index.ts +1 -64
- package/utils/os.ts +22 -1
- package/utils/port.ts +41 -0
- package/utils/vine.ts +10 -0
- package/bin/_.ts +0 -121
- package/lib/meilisearch/index.ts +0 -25
package/app/hono.ts
CHANGED
|
@@ -15,7 +15,6 @@ import { consola } from "consola";
|
|
|
15
15
|
|
|
16
16
|
import { cors } from "hono/cors";
|
|
17
17
|
import { asyncLocalStorage, sessionStorage } from "../lib/asyncLocalStorage";
|
|
18
|
-
import { localSession } from "../lib/session";
|
|
19
18
|
import { crypt } from "../lib/crypto";
|
|
20
19
|
import {
|
|
21
20
|
cleanPath,
|
|
@@ -32,7 +31,6 @@ import { useRest } from "../driver/mongo/rest";
|
|
|
32
31
|
import moment from "moment";
|
|
33
32
|
import { Cfg } from "../config";
|
|
34
33
|
import { getService } from "../lib/service";
|
|
35
|
-
import { bentoCache, bentoKey } from "../lib/bento";
|
|
36
34
|
import { MediaDrive } from "../lib/media";
|
|
37
35
|
import { isStudio } from "../lib/studio";
|
|
38
36
|
|
|
@@ -45,14 +43,13 @@ import { csrf } from "hono/csrf";
|
|
|
45
43
|
import { v4 } from "uuid";
|
|
46
44
|
import type { SearchParams } from "meilisearch";
|
|
47
45
|
import { utils } from "..";
|
|
48
|
-
const cache = bentoCache.namespace("DNAX_API");
|
|
49
46
|
const app = new Hono();
|
|
50
47
|
const API_PATH = "/api";
|
|
51
48
|
|
|
52
49
|
function HonoInstance(): typeof app {
|
|
53
50
|
app.use(
|
|
54
51
|
cors({
|
|
55
|
-
origin: Cfg.server?.cors?.origin || ["*"],
|
|
52
|
+
origin: (Cfg.server?.cors?.origin as string[]) || ["*"],
|
|
56
53
|
credentials: Cfg.server?.cors?.credentials ?? false,
|
|
57
54
|
allowMethods: Cfg.server?.cors?.allowMethods || [
|
|
58
55
|
"GET",
|
|
@@ -73,6 +70,9 @@ function HonoInstance(): typeof app {
|
|
|
73
70
|
"X-Requested-With",
|
|
74
71
|
"Access-Control-Request-Method",
|
|
75
72
|
"Access-Control-Request-Headers",
|
|
73
|
+
"X-Forwarded-For",
|
|
74
|
+
"Cookie",
|
|
75
|
+
"X-Forwarded-Host",
|
|
76
76
|
],
|
|
77
77
|
})
|
|
78
78
|
);
|
|
@@ -95,7 +95,7 @@ function HonoInstance(): typeof app {
|
|
|
95
95
|
})
|
|
96
96
|
);
|
|
97
97
|
app.use(secureHeaders());
|
|
98
|
-
app.use(compress());
|
|
98
|
+
//app.use(compress());
|
|
99
99
|
|
|
100
100
|
//eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoibm9tIiwiaWF0IjoxNzE3Nzc0MDQzLCJleHAiOjE3MTc3NzQxMDN9.Ud4-0y8pa4SMIcSn8PU1A-sjC-hT4ZVe_u3AdChyIJU
|
|
101
101
|
// Middlewares Injection
|
|
@@ -126,8 +126,17 @@ function HonoInstance(): typeof app {
|
|
|
126
126
|
reqAt: moment().format().toString(),
|
|
127
127
|
setAt: sessionData?._v?.setAt || null,
|
|
128
128
|
};
|
|
129
|
+
let tenantId =
|
|
130
|
+
c.req.header()["tenant-id"] ||
|
|
131
|
+
c.req.query("tenant-id") ||
|
|
132
|
+
c.req.query("tenantId") ||
|
|
133
|
+
c.req.query("tenant_id") ||
|
|
134
|
+
null;
|
|
135
|
+
|
|
136
|
+
tenantId = tenantId ? String(tenantId) : null;
|
|
137
|
+
|
|
129
138
|
c.set("_v", _v);
|
|
130
|
-
c.set("tenant-id",
|
|
139
|
+
c.set("tenant-id", tenantId);
|
|
131
140
|
|
|
132
141
|
//console.log("_v", _v);
|
|
133
142
|
|
|
@@ -566,38 +575,12 @@ function HonoInstance(): typeof app {
|
|
|
566
575
|
});
|
|
567
576
|
}
|
|
568
577
|
}
|
|
578
|
+
|
|
569
579
|
// find
|
|
570
580
|
if (action == "find") {
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
query: c?.req?.query,
|
|
575
|
-
});
|
|
576
|
-
|
|
577
|
-
// if customCache
|
|
578
|
-
if (col?.cache?.fetch) {
|
|
579
|
-
let fetchFromCache = await col?.cache?.fetch({
|
|
580
|
-
key: keyCache,
|
|
581
|
-
action: action,
|
|
582
|
-
params: body?.params,
|
|
583
|
-
rest: rest,
|
|
584
|
-
session: sessionStorage(),
|
|
585
|
-
state: col?.cache?.state || {},
|
|
586
|
-
c: c,
|
|
587
|
-
});
|
|
588
|
-
if (!fetchFromCache?.isStale) {
|
|
589
|
-
response = fetchFromCache.data;
|
|
590
|
-
} else {
|
|
591
|
-
response = await rest.find(collection, body?.params || {}, {
|
|
592
|
-
withMeta: body?.withMeta || false,
|
|
593
|
-
});
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
} else {
|
|
597
|
-
response = await rest.find(collection, body?.params || {}, {
|
|
598
|
-
withMeta: body?.withMeta || false,
|
|
599
|
-
});
|
|
600
|
-
}
|
|
581
|
+
response = await rest.find(collection, body?.params || {}, {
|
|
582
|
+
withMeta: body?.withMeta || false,
|
|
583
|
+
});
|
|
601
584
|
}
|
|
602
585
|
|
|
603
586
|
if (action == "listActivity") {
|
package/app/index.ts
CHANGED
|
@@ -2,17 +2,16 @@ import consola from "consola";
|
|
|
2
2
|
import { Cfg, loadCfg } from "../config";
|
|
3
3
|
import { init } from "../lib";
|
|
4
4
|
import { hookDatabase } from "../lib/database";
|
|
5
|
-
import killPort from "kill-port";
|
|
6
5
|
import boxen from "boxen";
|
|
7
6
|
import { loadSocket } from "../lib/socket";
|
|
8
|
-
import pidusage from "pidusage";
|
|
9
7
|
import "@colors/colors";
|
|
10
8
|
import pkg from "../package.json";
|
|
11
|
-
import findPort from "
|
|
9
|
+
import { findPort } from "../utils/port";
|
|
12
10
|
import { webSocketServer } from "../lib/socket/instance";
|
|
13
11
|
import { HonoInstance } from "./hono";
|
|
14
12
|
import { utils } from "..";
|
|
15
13
|
import type { Server } from "bun";
|
|
14
|
+
import { getPidUsage } from "../utils/os";
|
|
16
15
|
type configRunApp = {
|
|
17
16
|
register?: Array<Function>;
|
|
18
17
|
beforeStart?: Array<Function>;
|
|
@@ -22,125 +21,106 @@ type configRunApp = {
|
|
|
22
21
|
dbSync?: Array<Function>;
|
|
23
22
|
};
|
|
24
23
|
async function runApp(config?: configRunApp, clb?: Function): Promise<Server> {
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
try {
|
|
25
|
+
hookDatabase.cb = config?.dbSync || [];
|
|
26
|
+
await loadCfg(); // Load Config
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
/* const PORT_SOCKET = Cfg.server?.socket?.port || 9000;
|
|
28
|
+
const PORT = Cfg.server?.port || process.env?.PORT || 4000;
|
|
29
|
+
const CLUSTER_MODE = Cfg?.clusterMode ?? false;
|
|
31
30
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
// available port Server
|
|
42
|
-
return await findPort
|
|
43
|
-
.isAvailable(PORT)
|
|
44
|
-
.then(async (available: boolean) => {
|
|
45
|
-
// Start App server
|
|
46
|
-
if (!available && !Cfg?.clusterMode) {
|
|
47
|
-
console.error(`⚠️ Port ${PORT} is not available`);
|
|
48
|
-
console.log("");
|
|
49
|
-
process.exit();
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
if (available) {
|
|
53
|
-
// Load all ressouce
|
|
54
|
-
await init();
|
|
55
|
-
const HonoApp = HonoInstance();
|
|
56
|
-
//await loadSocket(HonoApp);
|
|
57
|
-
//BeforeStart
|
|
58
|
-
if (config?.beforeStart) {
|
|
59
|
-
for (const fn of config?.beforeStart) {
|
|
60
|
-
await fn();
|
|
61
|
-
}
|
|
31
|
+
// available port Server
|
|
32
|
+
return await findPort
|
|
33
|
+
.isAvailable(Number(PORT))
|
|
34
|
+
.then(async (available: boolean) => {
|
|
35
|
+
// Start App server
|
|
36
|
+
if (!available && !Cfg?.clusterMode) {
|
|
37
|
+
console.error(`⚠️ Port ${PORT} is not available`);
|
|
38
|
+
console.log("");
|
|
39
|
+
process.exit();
|
|
62
40
|
}
|
|
63
41
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
42
|
+
if (available) {
|
|
43
|
+
// Load all ressouce
|
|
44
|
+
await init();
|
|
45
|
+
const HonoApp = HonoInstance();
|
|
46
|
+
//await loadSocket(HonoApp);
|
|
47
|
+
//BeforeStart
|
|
48
|
+
if (config?.beforeStart) {
|
|
49
|
+
for (const fn of config?.beforeStart) {
|
|
50
|
+
await fn();
|
|
71
51
|
}
|
|
52
|
+
}
|
|
72
53
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
54
|
+
var server: any = Bun.serve({
|
|
55
|
+
port: PORT,
|
|
56
|
+
reusePort: CLUSTER_MODE,
|
|
57
|
+
fetch: (req, server) => {
|
|
58
|
+
if (server.upgrade(req)) {
|
|
59
|
+
// handle authentication
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
78
62
|
|
|
79
|
-
|
|
80
|
-
|
|
63
|
+
return HonoApp.fetch(req, server);
|
|
64
|
+
},
|
|
65
|
+
maxRequestBodySize: 1024 * 1024 * 900,
|
|
66
|
+
websocket: webSocketServer(server),
|
|
67
|
+
});
|
|
81
68
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
borderStyle: "round",
|
|
85
|
-
title: `@dnax/server ${pkg.version}`,
|
|
86
|
-
padding: 1,
|
|
87
|
-
dimBorder: true,
|
|
88
|
-
titleAlignment: "center",
|
|
89
|
-
//float: "center",
|
|
90
|
-
//margin: 1,
|
|
91
|
-
borderColor: "gray",
|
|
92
|
-
})
|
|
93
|
-
); */
|
|
94
|
-
let info = "";
|
|
95
|
-
let envName = process.env?.NODE_ENV || "dev";
|
|
96
|
-
info += `${serverName}`.gray.underline.bold;
|
|
97
|
-
info += `\n`;
|
|
98
|
-
info += `\n`;
|
|
99
|
-
info += `Env: ${envName}`.green.bold + "\n";
|
|
100
|
-
info += `url: http://localhost:${PORT}\n`.gray.bold;
|
|
101
|
-
//info += `Jwt Secret: ${Cfg.server.jwt?.secret}\n`.gray;
|
|
102
|
-
info += `\n`;
|
|
103
|
-
info += "TENANTS :".gray.underline.bold;
|
|
104
|
-
info += `\n`;
|
|
105
|
-
Cfg.tenants?.map((t: any) => {
|
|
106
|
-
info += `\n${t?.name?.blue || "_"} : ${t?.id?.green}`.bold;
|
|
107
|
-
});
|
|
108
|
-
info += `\n\n`;
|
|
109
|
-
info += `🔄 ${new Date().toLocaleString()}`.gray;
|
|
69
|
+
let serverName =
|
|
70
|
+
process.env.SERVER_NAME || Cfg?.server?.name || "SERVER";
|
|
110
71
|
|
|
111
|
-
|
|
72
|
+
let info = "";
|
|
73
|
+
let envName = process.env?.NODE_ENV || "dev";
|
|
74
|
+
info += `${serverName}`.gray.underline.bold;
|
|
75
|
+
info += `\n`;
|
|
76
|
+
info += `\n`;
|
|
77
|
+
info += `Env: ${envName}`.green.bold + "\n";
|
|
78
|
+
info += `url: http://localhost:${PORT}\n`.gray.bold;
|
|
79
|
+
//info += `Jwt Secret: ${Cfg.server.jwt?.secret}\n`.gray;
|
|
80
|
+
info += `\n`;
|
|
81
|
+
info += "TENANTS :".gray.underline.bold;
|
|
82
|
+
info += `\n`;
|
|
83
|
+
Cfg.tenants?.map((t: any) => {
|
|
84
|
+
info += `\n${t?.name?.blue || "_"} : ${t?.id?.green}`.bold;
|
|
85
|
+
});
|
|
86
|
+
info += `\n\n`;
|
|
87
|
+
info += `🔄 ${new Date().toLocaleString()}`.gray;
|
|
112
88
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
89
|
+
if (clb) clb();
|
|
90
|
+
console.log(
|
|
91
|
+
boxen(info, {
|
|
92
|
+
borderStyle: "double",
|
|
93
|
+
title: `@dnax/server ${pkg.version}`,
|
|
94
|
+
padding: 1.5,
|
|
95
|
+
dimBorder: true,
|
|
120
96
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
97
|
+
titleAlignment: "center",
|
|
98
|
+
//float: "center",
|
|
99
|
+
//margin: 1,
|
|
100
|
+
borderColor: "gray",
|
|
101
|
+
})
|
|
102
|
+
);
|
|
127
103
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
104
|
+
//AfterStart
|
|
105
|
+
if (config?.afterStart) {
|
|
106
|
+
for (const fn of config?.afterStart) {
|
|
107
|
+
await fn({
|
|
108
|
+
config: utils.copy(Cfg),
|
|
109
|
+
});
|
|
110
|
+
}
|
|
134
111
|
}
|
|
135
112
|
}
|
|
136
|
-
}
|
|
137
113
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
114
|
+
return server;
|
|
115
|
+
})
|
|
116
|
+
.catch((err: any) => {
|
|
117
|
+
console.error(err);
|
|
118
|
+
process.exit(1);
|
|
119
|
+
});
|
|
120
|
+
} catch (err: any) {
|
|
121
|
+
consola.error(err?.message);
|
|
122
|
+
process.exit(1);
|
|
123
|
+
}
|
|
144
124
|
}
|
|
145
125
|
|
|
146
126
|
//process.on("exit", async () => {});
|
package/config/index.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { cors } from "hono/cors";
|
|
2
|
-
import { Config } from "./../types/index";
|
|
3
2
|
import type { Config } from "../types";
|
|
4
3
|
import fs from "fs-extra";
|
|
5
|
-
import { systemCache } from "../lib/bento";
|
|
6
4
|
import { Glob } from "bun";
|
|
7
5
|
import path from "path";
|
|
8
6
|
import { v4 } from "uuid";
|
|
7
|
+
import { consola } from "consola";
|
|
9
8
|
|
|
10
9
|
const ROOT_PATH = process.cwd();
|
|
11
10
|
const Cfg: Config = {
|
|
@@ -52,22 +51,7 @@ async function setCfg(config: Config) {
|
|
|
52
51
|
}
|
|
53
52
|
|
|
54
53
|
if (!Cfg?.server?.jwt?.secret) {
|
|
55
|
-
|
|
56
|
-
key: ".jwt.json",
|
|
57
|
-
});
|
|
58
|
-
if (!jwtSecret) {
|
|
59
|
-
jwtSecret = v4().replaceAll("-", "");
|
|
60
|
-
await systemCache.set({
|
|
61
|
-
key: ".jwt.json",
|
|
62
|
-
value: jwtSecret,
|
|
63
|
-
ttl: "2y",
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
Cfg.server.jwt.secret = jwtSecret;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if (!Cfg?.server.jwt?.secret) {
|
|
70
|
-
console.error("JWT_SECRET is not defined");
|
|
54
|
+
consola.error("JWT_SECRET is not defined".red);
|
|
71
55
|
process.exit(1);
|
|
72
56
|
}
|
|
73
57
|
|
package/driver/mongo/@types.ts
CHANGED
|
@@ -24,6 +24,21 @@ export type findParam = {
|
|
|
24
24
|
};
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
+
export type restEventType = [
|
|
28
|
+
"*",
|
|
29
|
+
"insertOne",
|
|
30
|
+
"insertMany",
|
|
31
|
+
"updateOne",
|
|
32
|
+
"updateMany",
|
|
33
|
+
"deleteOne",
|
|
34
|
+
"deleteMany",
|
|
35
|
+
"find",
|
|
36
|
+
"findOne",
|
|
37
|
+
"findAndUpdate",
|
|
38
|
+
"findOneAndUpdate",
|
|
39
|
+
"aggregate",
|
|
40
|
+
"count"
|
|
41
|
+
];
|
|
27
42
|
export type findOneParam = {
|
|
28
43
|
$match: object;
|
|
29
44
|
$include?: Array<object>;
|
package/driver/mongo/connect.ts
CHANGED
|
@@ -13,8 +13,8 @@ async function connectToMongo(t: Tenant) {
|
|
|
13
13
|
await client
|
|
14
14
|
.connect()
|
|
15
15
|
.then((e) => {
|
|
16
|
-
console.log("\n");
|
|
17
|
-
consola.success(`DB connected : [${t.id}] ✅`.green);
|
|
16
|
+
//console.log("\n");
|
|
17
|
+
// consola.success(`DB connected : [${t.id}] ✅`.green);
|
|
18
18
|
t.database.isConnected = true;
|
|
19
19
|
t.database.client = client;
|
|
20
20
|
t.database.db = client.db();
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
type options = {
|
|
2
|
+
uri: string;
|
|
3
|
+
binPath?: string;
|
|
4
|
+
};
|
|
5
|
+
import { consola } from "consola";
|
|
6
|
+
import { $ } from "bun";
|
|
7
|
+
import moment from "moment";
|
|
8
|
+
|
|
9
|
+
class DatabaseTools {
|
|
10
|
+
options: options;
|
|
11
|
+
constructor(options: options) {
|
|
12
|
+
this.options = options;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* @param output - path to the output file
|
|
16
|
+
*/
|
|
17
|
+
async backup(
|
|
18
|
+
filename: string,
|
|
19
|
+
path: string,
|
|
20
|
+
options?: {
|
|
21
|
+
debug?: boolean;
|
|
22
|
+
}
|
|
23
|
+
) {
|
|
24
|
+
try {
|
|
25
|
+
consola.log("🔄 Backuping database to", path);
|
|
26
|
+
const { uri, binPath } = this.options;
|
|
27
|
+
const cmdBin = binPath ? `${binPath}/mongodump` : "mongodump";
|
|
28
|
+
let outputPath = path + "/" + filename + ".gz";
|
|
29
|
+
if (options?.debug) {
|
|
30
|
+
const output =
|
|
31
|
+
await $`${cmdBin} --uri ${uri} --archive=${outputPath} --gzip`;
|
|
32
|
+
console.log(output);
|
|
33
|
+
} else {
|
|
34
|
+
const output =
|
|
35
|
+
await $`${cmdBin} --uri ${uri} --archive=${outputPath} --gzip`.quiet();
|
|
36
|
+
}
|
|
37
|
+
console.log();
|
|
38
|
+
|
|
39
|
+
consola.log(`✅ Backup [${filename}] completed to [${path}]`.bold);
|
|
40
|
+
} catch (err: any) {
|
|
41
|
+
consola.error(err?.message);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async export(
|
|
46
|
+
collectionName: string,
|
|
47
|
+
databaseName: string,
|
|
48
|
+
path: string,
|
|
49
|
+
options?: {
|
|
50
|
+
debug?: boolean;
|
|
51
|
+
format?: "json" | "gz";
|
|
52
|
+
}
|
|
53
|
+
) {
|
|
54
|
+
try {
|
|
55
|
+
consola.log(
|
|
56
|
+
`🔄 Exporting collection [${collectionName}] to [${path}]`.bold
|
|
57
|
+
);
|
|
58
|
+
let format = options?.format || "json";
|
|
59
|
+
const { uri, binPath } = this.options;
|
|
60
|
+
const cmdBin = binPath ? `${binPath}/mongoexport` : "mongoexport";
|
|
61
|
+
let outputPath = path + "/" + collectionName + ".json";
|
|
62
|
+
if (options?.debug) {
|
|
63
|
+
const output =
|
|
64
|
+
await $`${cmdBin} --uri ${uri} --db=${databaseName} --collection=${collectionName} --out=${outputPath} --jsonArray --pretty`;
|
|
65
|
+
console.log(output);
|
|
66
|
+
} else {
|
|
67
|
+
const output =
|
|
68
|
+
await $`${cmdBin} --uri ${uri} --db=${databaseName} --collection=${collectionName} --out=${outputPath} --jsonArray --pretty`.quiet();
|
|
69
|
+
}
|
|
70
|
+
console.log();
|
|
71
|
+
|
|
72
|
+
consola.log(
|
|
73
|
+
`✅[${collectionName}]'s collection exported to [${path}]`.bold
|
|
74
|
+
);
|
|
75
|
+
} catch (err: any) {
|
|
76
|
+
consola.error(err?.message);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function useDatabaseTools(options: options): DatabaseTools {
|
|
82
|
+
return new DatabaseTools(options);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export { useDatabaseTools };
|
package/driver/mongo/rest.ts
CHANGED
|
@@ -23,6 +23,7 @@ import type {
|
|
|
23
23
|
findOneParam,
|
|
24
24
|
findParam,
|
|
25
25
|
queryParam,
|
|
26
|
+
restEventType,
|
|
26
27
|
updateParams,
|
|
27
28
|
} from "./@types";
|
|
28
29
|
import {
|
|
@@ -462,17 +463,6 @@ class useRest {
|
|
|
462
463
|
});
|
|
463
464
|
}
|
|
464
465
|
|
|
465
|
-
try {
|
|
466
|
-
col?.cache?.watch({
|
|
467
|
-
action: "insertOne",
|
|
468
|
-
c: this.#c,
|
|
469
|
-
session: sessionStorage(),
|
|
470
|
-
rest: this,
|
|
471
|
-
state: col?.cache?.state || {},
|
|
472
|
-
result: toJson(data),
|
|
473
|
-
});
|
|
474
|
-
} catch (err) {}
|
|
475
|
-
|
|
476
466
|
// meilisearch engine
|
|
477
467
|
if (
|
|
478
468
|
this.#tenant?.searchEngine?.meilisearch?.enabled &&
|
|
@@ -621,16 +611,6 @@ class useRest {
|
|
|
621
611
|
});
|
|
622
612
|
}
|
|
623
613
|
|
|
624
|
-
try {
|
|
625
|
-
col?.cache?.watch({
|
|
626
|
-
action: "insertMany",
|
|
627
|
-
c: this.#c,
|
|
628
|
-
session: sessionStorage(),
|
|
629
|
-
rest: this,
|
|
630
|
-
state: col?.cache?.state || {},
|
|
631
|
-
result: toJson(data),
|
|
632
|
-
});
|
|
633
|
-
} catch (err) {}
|
|
634
614
|
if (
|
|
635
615
|
this.#tenant?.searchEngine?.meilisearch?.enabled &&
|
|
636
616
|
col?.searchEngine?.meilisearch?.dispatchAction == "auto"
|
|
@@ -663,6 +643,8 @@ class useRest {
|
|
|
663
643
|
}
|
|
664
644
|
});
|
|
665
645
|
}
|
|
646
|
+
|
|
647
|
+
//on(event: restEventType, clb: Function) {}
|
|
666
648
|
/**
|
|
667
649
|
*
|
|
668
650
|
* @param queries
|
|
@@ -711,19 +693,14 @@ class useRest {
|
|
|
711
693
|
collection: string,
|
|
712
694
|
params?: findParam,
|
|
713
695
|
options?: optionCb
|
|
714
|
-
): Promise<
|
|
715
|
-
object[] | { data: object[]; meta: { total: number; count: number } }
|
|
716
|
-
> {
|
|
696
|
+
): Promise<{ _id: string; [key: string]: any }[]> {
|
|
717
697
|
return new Promise(async (resolve, reject) => {
|
|
718
698
|
try {
|
|
719
699
|
if (!params) params = {};
|
|
720
700
|
if (options?.cleanDeep) {
|
|
721
701
|
params = cleanDeep(params);
|
|
722
702
|
}
|
|
723
|
-
|
|
724
|
-
total: 0,
|
|
725
|
-
count: 0,
|
|
726
|
-
};
|
|
703
|
+
|
|
727
704
|
let useHook = options?.useHook ?? this.#useHook;
|
|
728
705
|
let useCustomApi = options?.useCustomApi ?? this.#useCustomApi;
|
|
729
706
|
let sharedData = {};
|
|
@@ -789,22 +766,6 @@ class useRest {
|
|
|
789
766
|
|
|
790
767
|
result.docs = toJson(result.docs);
|
|
791
768
|
|
|
792
|
-
if (options?.withMeta) {
|
|
793
|
-
meta.count = await this.#tenant.database.db
|
|
794
|
-
?.collection(collection)
|
|
795
|
-
.countDocuments({
|
|
796
|
-
...(params?.$match || {}),
|
|
797
|
-
})
|
|
798
|
-
.then((e) => e || 0)
|
|
799
|
-
.catch((err) => 0);
|
|
800
|
-
meta.total = await this.#tenant.database.db
|
|
801
|
-
?.collection(collection)
|
|
802
|
-
.estimatedDocumentCount();
|
|
803
|
-
} else {
|
|
804
|
-
meta.total = result.docs.length;
|
|
805
|
-
meta.count = result.docs.length;
|
|
806
|
-
}
|
|
807
|
-
|
|
808
769
|
if (col?.hooks?.afterFind && useHook) {
|
|
809
770
|
await col.hooks.afterFind({
|
|
810
771
|
sharedData: sharedData,
|
|
@@ -830,13 +791,6 @@ class useRest {
|
|
|
830
791
|
resultDocs = resultDocs[options?.elementAt] ?? null;
|
|
831
792
|
}
|
|
832
793
|
|
|
833
|
-
if (options?.withMeta) {
|
|
834
|
-
return resolve({
|
|
835
|
-
data: resultDocs,
|
|
836
|
-
meta: meta,
|
|
837
|
-
});
|
|
838
|
-
}
|
|
839
|
-
|
|
840
794
|
return resolve(resultDocs);
|
|
841
795
|
} catch (err) {
|
|
842
796
|
return reject(err);
|
|
@@ -847,10 +801,7 @@ class useRest {
|
|
|
847
801
|
async count(
|
|
848
802
|
collection: string,
|
|
849
803
|
params: findParam,
|
|
850
|
-
options?: Omit<
|
|
851
|
-
optionCb,
|
|
852
|
-
"useCustomApi" | "withMeta" | "elementAt" | "useHook"
|
|
853
|
-
>
|
|
804
|
+
options?: Omit<optionCb, "useCustomApi" | "withMeta" | "elementAt">
|
|
854
805
|
): Promise<number> {
|
|
855
806
|
return new Promise(async (resolve, reject) => {
|
|
856
807
|
try {
|
|
@@ -1264,16 +1215,6 @@ class useRest {
|
|
|
1264
1215
|
});
|
|
1265
1216
|
}
|
|
1266
1217
|
|
|
1267
|
-
try {
|
|
1268
|
-
col?.cache?.watch({
|
|
1269
|
-
action: "insertMany",
|
|
1270
|
-
c: this.#c,
|
|
1271
|
-
session: sessionStorage(),
|
|
1272
|
-
rest: this,
|
|
1273
|
-
state: col?.cache?.state || {},
|
|
1274
|
-
result: toJson(result?.doc || {}),
|
|
1275
|
-
});
|
|
1276
|
-
} catch (err) {}
|
|
1277
1218
|
if (
|
|
1278
1219
|
this.#tenant?.searchEngine?.meilisearch?.enabled &&
|
|
1279
1220
|
col?.searchEngine?.meilisearch?.dispatchAction == "auto"
|
|
@@ -1544,44 +1485,6 @@ class useRest {
|
|
|
1544
1485
|
});
|
|
1545
1486
|
}
|
|
1546
1487
|
|
|
1547
|
-
async search(
|
|
1548
|
-
collection: string,
|
|
1549
|
-
term: string,
|
|
1550
|
-
searchOptions: SearchParams
|
|
1551
|
-
): Promise<{
|
|
1552
|
-
hits: Array<object>;
|
|
1553
|
-
limit: number;
|
|
1554
|
-
offset: number;
|
|
1555
|
-
total: number;
|
|
1556
|
-
processingTimeMs: number;
|
|
1557
|
-
facetDistribution?: object;
|
|
1558
|
-
facetsStats?: object;
|
|
1559
|
-
estimatedTotalHits?: number;
|
|
1560
|
-
totalHits?: number;
|
|
1561
|
-
hitsPerPage?: number;
|
|
1562
|
-
page?: number;
|
|
1563
|
-
}> {
|
|
1564
|
-
return new Promise(async (resolve, reject) => {
|
|
1565
|
-
try {
|
|
1566
|
-
let index = getCollection(collection, this.#tenant_id)?.searchEngine
|
|
1567
|
-
?.meilisearch?.index!;
|
|
1568
|
-
|
|
1569
|
-
if (!index)
|
|
1570
|
-
return reject({
|
|
1571
|
-
code: 400,
|
|
1572
|
-
message: "Search engine Index required",
|
|
1573
|
-
});
|
|
1574
|
-
|
|
1575
|
-
let result = this.meilisearch.client.index(index).search(term, {
|
|
1576
|
-
...searchOptions,
|
|
1577
|
-
});
|
|
1578
|
-
resolve(result);
|
|
1579
|
-
} catch (err) {
|
|
1580
|
-
return reject(err);
|
|
1581
|
-
}
|
|
1582
|
-
});
|
|
1583
|
-
}
|
|
1584
|
-
|
|
1585
1488
|
async updateMany(
|
|
1586
1489
|
collection: string,
|
|
1587
1490
|
ids: Array<string>,
|
|
@@ -1746,16 +1649,6 @@ class useRest {
|
|
|
1746
1649
|
});
|
|
1747
1650
|
}
|
|
1748
1651
|
|
|
1749
|
-
try {
|
|
1750
|
-
col?.cache?.watch({
|
|
1751
|
-
action: "updateMany",
|
|
1752
|
-
c: this.#c,
|
|
1753
|
-
session: sessionStorage(),
|
|
1754
|
-
rest: this,
|
|
1755
|
-
state: col?.cache?.state || {},
|
|
1756
|
-
result: toJson(result?.docs || []),
|
|
1757
|
-
});
|
|
1758
|
-
} catch (err) {}
|
|
1759
1652
|
if (
|
|
1760
1653
|
this.#tenant?.searchEngine?.meilisearch?.enabled &&
|
|
1761
1654
|
col?.searchEngine?.meilisearch?.dispatchAction == "auto"
|
|
@@ -1885,16 +1778,6 @@ class useRest {
|
|
|
1885
1778
|
});
|
|
1886
1779
|
}
|
|
1887
1780
|
|
|
1888
|
-
try {
|
|
1889
|
-
col?.cache?.watch({
|
|
1890
|
-
action: "deleteOne",
|
|
1891
|
-
c: this.#c,
|
|
1892
|
-
session: sessionStorage(),
|
|
1893
|
-
rest: this,
|
|
1894
|
-
state: col?.cache?.state || {},
|
|
1895
|
-
result: toJson(doc || {}),
|
|
1896
|
-
});
|
|
1897
|
-
} catch (err) {}
|
|
1898
1781
|
if (
|
|
1899
1782
|
this.#tenant?.searchEngine?.meilisearch?.enabled &&
|
|
1900
1783
|
col?.searchEngine?.meilisearch?.dispatchAction == "auto"
|
|
@@ -2027,16 +1910,6 @@ class useRest {
|
|
|
2027
1910
|
});
|
|
2028
1911
|
}
|
|
2029
1912
|
|
|
2030
|
-
try {
|
|
2031
|
-
col?.cache?.watch({
|
|
2032
|
-
action: "deleteMany",
|
|
2033
|
-
c: this.#c,
|
|
2034
|
-
session: sessionStorage(),
|
|
2035
|
-
rest: this,
|
|
2036
|
-
state: col?.cache?.state || {},
|
|
2037
|
-
result: deletedIds || [],
|
|
2038
|
-
});
|
|
2039
|
-
} catch (err) {}
|
|
2040
1913
|
if (
|
|
2041
1914
|
this.#tenant?.searchEngine?.meilisearch?.enabled &&
|
|
2042
1915
|
col?.searchEngine?.meilisearch?.dispatchAction == "auto"
|
package/index.ts
CHANGED
|
@@ -6,13 +6,12 @@ import * as v from "joi";
|
|
|
6
6
|
import { $ } from "bun";
|
|
7
7
|
import define from "./define";
|
|
8
8
|
import * as utils from "./utils";
|
|
9
|
-
import { dataCache } from "./lib/bento";
|
|
10
9
|
import { FilesystemSftpAdapter, MinioAdapter } from "./lib/media";
|
|
11
10
|
import { crypt } from "./lib/crypto";
|
|
12
11
|
import { contextStorage } from "./lib/asyncLocalStorage";
|
|
13
12
|
import { Cron as Task } from "croner";
|
|
14
|
-
import { useWorkflow } from "./lib/workflow";
|
|
15
13
|
import { serveStatic } from "hono/bun";
|
|
14
|
+
import { useDatabaseTools } from "./driver/mongo/database";
|
|
16
15
|
// Adapter
|
|
17
16
|
|
|
18
17
|
const Adapter = {
|
|
@@ -32,11 +31,10 @@ export {
|
|
|
32
31
|
utils,
|
|
33
32
|
useRest,
|
|
34
33
|
v,
|
|
35
|
-
dataCache,
|
|
36
34
|
Task,
|
|
37
35
|
crypt,
|
|
38
36
|
$,
|
|
39
37
|
contextStorage,
|
|
40
38
|
Adapter,
|
|
41
|
-
|
|
39
|
+
useDatabaseTools,
|
|
42
40
|
};
|
package/lib/asyncLocalStorage.ts
CHANGED
package/lib/bento/index.ts
CHANGED
|
@@ -19,61 +19,4 @@ if (!fs?.existsSync(path.resolve(cacheDirectoryData + "bentocache"))) {
|
|
|
19
19
|
});
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
default: "systemCache",
|
|
24
|
-
|
|
25
|
-
stores: {
|
|
26
|
-
systemCache: bentostore().useL2Layer(
|
|
27
|
-
fileDriver({
|
|
28
|
-
directory: cacheDirectory,
|
|
29
|
-
pruneInterval: "1h",
|
|
30
|
-
//maxSize: 100 * 1024 * 1024,
|
|
31
|
-
})
|
|
32
|
-
),
|
|
33
|
-
},
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
const dataCache = new BentoCache({
|
|
37
|
-
default: "dataCache",
|
|
38
|
-
stores: {
|
|
39
|
-
dataCache: bentostore().useL2Layer(
|
|
40
|
-
fileDriver({
|
|
41
|
-
directory: cacheDirectoryData,
|
|
42
|
-
pruneInterval: false,
|
|
43
|
-
|
|
44
|
-
//maxSize: 100 * 1024 * 1024,
|
|
45
|
-
})
|
|
46
|
-
),
|
|
47
|
-
},
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
const bentoCache = new BentoCache({
|
|
51
|
-
default: "dnaxCache",
|
|
52
|
-
stores: {
|
|
53
|
-
dnaxCache: bentostore().useL1Layer(
|
|
54
|
-
memoryDriver({
|
|
55
|
-
maxSize: 100 * 1024 * 1024,
|
|
56
|
-
})
|
|
57
|
-
),
|
|
58
|
-
},
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
function bentoKey(data: object | string) {
|
|
62
|
-
let key = "";
|
|
63
|
-
if (data) {
|
|
64
|
-
if (typeof data == "object") {
|
|
65
|
-
key = JSON.stringify(data);
|
|
66
|
-
key = key.replace(/\s/g, "").trim();
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if (typeof data == "string") {
|
|
70
|
-
key = data.replace(/\s/g, "").trim();
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
return key;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const sessionCache = systemCache.namespace("tokens");
|
|
78
|
-
|
|
79
|
-
export { bentoCache, bentoKey, systemCache, sessionCache, dataCache };
|
|
22
|
+
export {};
|
package/lib/collection.ts
CHANGED
|
@@ -43,7 +43,7 @@ async function loadAllCollections() {
|
|
|
43
43
|
|
|
44
44
|
function getCollection(
|
|
45
45
|
name: string,
|
|
46
|
-
tenant_id: string
|
|
46
|
+
tenant_id: string
|
|
47
47
|
): Collection | undefined | null {
|
|
48
48
|
if (Cfg?.collections?.length) {
|
|
49
49
|
return Cfg.collections.find((col: Collection) => {
|
package/lib/index.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { loadAllCollections, syncCollectionDatabase } from "./collection";
|
|
2
|
-
import { syncMeilisearchClientOnTenant } from "./meilisearch";
|
|
3
2
|
import { connectTenantsDatabase } from "../driver";
|
|
4
3
|
import { loadEndpoints } from "./endpoint";
|
|
5
4
|
import { loadServices } from "./service";
|
|
@@ -10,41 +9,66 @@ import { loadAutoRoutes } from "./routes";
|
|
|
10
9
|
import { initScript } from "../lib/scripts";
|
|
11
10
|
import { syncAdapterFileSystem } from "./media";
|
|
12
11
|
import { runGenTypes } from "../types/gen";
|
|
12
|
+
import consola from "consola";
|
|
13
|
+
import ora from "ora";
|
|
13
14
|
|
|
14
15
|
// load all ressource
|
|
15
16
|
async function init(cf = { app: null }) {
|
|
17
|
+
console.log("\n");
|
|
18
|
+
const spinner = ora("Initializing...").start();
|
|
19
|
+
spinner.color = "green";
|
|
20
|
+
|
|
21
|
+
//console.log("🔄 Initializing...".blue);
|
|
16
22
|
await loadSocket();
|
|
23
|
+
//consola.success("Loaded socket");
|
|
17
24
|
// load all tenants database
|
|
18
25
|
await connectTenantsDatabase();
|
|
26
|
+
// consola.success("Loaded tenants database");
|
|
19
27
|
// load all collections
|
|
20
28
|
await loadAllCollections();
|
|
29
|
+
//consola.success("Loaded collections");
|
|
21
30
|
|
|
22
31
|
// load all permissions
|
|
23
32
|
await loadPermissions();
|
|
33
|
+
//consola.success("Loaded permissions");
|
|
24
34
|
|
|
25
35
|
// sync all collections database ( Indexes)
|
|
26
36
|
syncCollectionDatabase();
|
|
37
|
+
//consola.success("Synced collections database");
|
|
27
38
|
|
|
28
|
-
|
|
29
|
-
syncMeilisearchClientOnTenant();
|
|
39
|
+
runGenTypes();
|
|
30
40
|
|
|
31
41
|
// load Service
|
|
32
42
|
loadServices();
|
|
43
|
+
//consola.success("Loaded services");
|
|
33
44
|
|
|
34
45
|
// sync all adapter file system
|
|
35
46
|
syncAdapterFileSystem();
|
|
47
|
+
//consola.success(" adapter file system");
|
|
36
48
|
|
|
37
49
|
// load all loadEndpoints
|
|
38
50
|
await loadEndpoints();
|
|
51
|
+
// consola.success("Loaded endpoints");
|
|
39
52
|
|
|
40
53
|
// load auto routes
|
|
41
54
|
await loadAutoRoutes();
|
|
55
|
+
//consola.success("Loaded auto routes");
|
|
42
56
|
|
|
43
57
|
await initCron();
|
|
44
|
-
|
|
45
|
-
runGenTypes();
|
|
58
|
+
//consola.success("Loaded cron/Tasks");
|
|
46
59
|
|
|
47
60
|
initScript();
|
|
61
|
+
//consola.success("Loaded scripts");
|
|
62
|
+
//spinner.clear();
|
|
63
|
+
spinner.stop();
|
|
64
|
+
spinner.clear();
|
|
65
|
+
console.log(
|
|
66
|
+
"\n✨ Your server is up and running\n".green.bold +
|
|
67
|
+
"---------------------------------------\n".gray +
|
|
68
|
+
`🌍 Environment : ${process.env.NODE_ENV || "development"}\n`.gray +
|
|
69
|
+
`🕒 Started at : ${new Date().toLocaleString()}\n`.gray +
|
|
70
|
+
"---------------------------------------\n".gray
|
|
71
|
+
);
|
|
48
72
|
}
|
|
49
73
|
|
|
50
74
|
export { init };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dnax/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.67.0",
|
|
4
4
|
"module": "index.ts",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {},
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
"@types/dot-object": "^2.1.6",
|
|
10
10
|
"@types/fs-extra": "^11.0.4",
|
|
11
11
|
"@types/jsonwebtoken": "9.0.9",
|
|
12
|
-
"@types/mime-types": "^
|
|
12
|
+
"@types/mime-types": "^3.0.1",
|
|
13
13
|
"@types/minio": "^7.1.1",
|
|
14
|
-
"@types/nodemailer": "^6.4.
|
|
14
|
+
"@types/nodemailer": "^6.4.17",
|
|
15
15
|
"@types/pidusage": "^2.0.5",
|
|
16
16
|
"@types/ssh2-sftp-client": "^9.0.4",
|
|
17
17
|
"@types/uuid": "^10.0.0"
|
|
@@ -22,7 +22,10 @@
|
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"@colors/colors": "^1.6.0",
|
|
24
24
|
"@lukeed/ms": "^2.0.2",
|
|
25
|
-
"
|
|
25
|
+
"@types/blessed": "^0.1.25",
|
|
26
|
+
"@vinejs/vine": "^3.0.1",
|
|
27
|
+
"bentocache": "^1.5.0",
|
|
28
|
+
"blessed": "^0.1.81",
|
|
26
29
|
"boxen": "^7.1.1",
|
|
27
30
|
"chokidar": "3.6.0",
|
|
28
31
|
"clean-deep": "^3.4.0",
|
|
@@ -32,22 +35,19 @@
|
|
|
32
35
|
"croner": "8.1.1",
|
|
33
36
|
"deepcopy": "^2.1.0",
|
|
34
37
|
"dot-object": "2.1.5",
|
|
35
|
-
"find-open-port": "^2.0.3",
|
|
36
38
|
"fs-extra": "^11.2.0",
|
|
37
39
|
"generate-unique-id": "^2.0.3",
|
|
38
|
-
"hono": "4.
|
|
40
|
+
"hono": "4.8.9",
|
|
39
41
|
"joi": "17.13.3",
|
|
40
42
|
"json-joy": "16.8.0",
|
|
41
43
|
"jsonwebtoken": "^9.0.2",
|
|
42
|
-
"meilisearch": "^0.50.0",
|
|
43
44
|
"mime-types": "^2.1.35",
|
|
44
|
-
"mingo": "^6.5.0",
|
|
45
45
|
"minio": "^8.0.5",
|
|
46
46
|
"moment": "^2.30.1",
|
|
47
|
-
"mongodb": "6.
|
|
48
|
-
"nodemailer": "^
|
|
47
|
+
"mongodb": "6.18.0",
|
|
48
|
+
"nodemailer": "^7.0.5",
|
|
49
|
+
"ora": "^8.2.0",
|
|
49
50
|
"pidusage": "^4.0.0",
|
|
50
|
-
"pizzip": "^3.1.8",
|
|
51
51
|
"radash": "^12.1.0",
|
|
52
52
|
"rfc6902": "^5.1.2",
|
|
53
53
|
"sharp": "^0.33.5",
|
package/types/index.ts
CHANGED
|
@@ -320,70 +320,7 @@ export type Collection = {
|
|
|
320
320
|
findOne?: (ctx: ctxApi) => object;
|
|
321
321
|
count?: (ctx: ctxApi) => number;
|
|
322
322
|
};
|
|
323
|
-
|
|
324
|
-
meilisearch: {
|
|
325
|
-
/**
|
|
326
|
-
* unique name of the index on meilisearch
|
|
327
|
-
*/
|
|
328
|
-
index: string;
|
|
329
|
-
primaryKey?: string;
|
|
330
|
-
/**
|
|
331
|
-
* default value :auto
|
|
332
|
-
*/
|
|
333
|
-
dispatchAction: "auto" | "manual";
|
|
334
|
-
filterableAttributes?: Array<string>;
|
|
335
|
-
};
|
|
336
|
-
};
|
|
337
|
-
/**
|
|
338
|
-
* Cache available for action 'find' | 'findOne'
|
|
339
|
-
*/
|
|
340
|
-
cache?: {
|
|
341
|
-
enabled?: boolean;
|
|
342
|
-
state?: {
|
|
343
|
-
[key: string]: any;
|
|
344
|
-
};
|
|
345
|
-
init?: (ctx: {
|
|
346
|
-
rest: InstanceType<typeof useRest>;
|
|
347
|
-
state: {
|
|
348
|
-
[key: string]: any;
|
|
349
|
-
};
|
|
350
|
-
}) => void;
|
|
351
|
-
watch: (ctx: {
|
|
352
|
-
action:
|
|
353
|
-
| "insertOne"
|
|
354
|
-
| "insertMany"
|
|
355
|
-
| "updateOne"
|
|
356
|
-
| "updateMany"
|
|
357
|
-
| "deleteOne"
|
|
358
|
-
| "deleteMany"
|
|
359
|
-
| "findOneAndUpdate";
|
|
360
|
-
rest: InstanceType<typeof useRest>;
|
|
361
|
-
c?: Context;
|
|
362
|
-
session?: sessionCtx;
|
|
363
|
-
result: any;
|
|
364
|
-
state: {
|
|
365
|
-
[key: string]: any;
|
|
366
|
-
};
|
|
367
|
-
}) => void;
|
|
368
|
-
fetch?: (ctx: {
|
|
369
|
-
state: {
|
|
370
|
-
[key: string]: any;
|
|
371
|
-
};
|
|
372
|
-
body: {
|
|
373
|
-
params: findParam;
|
|
374
|
-
pipeline: Array<object>;
|
|
375
|
-
withMeta: boolean;
|
|
376
|
-
};
|
|
377
|
-
key: string;
|
|
378
|
-
action: "find" | "aggregate";
|
|
379
|
-
rest: InstanceType<typeof useRest>;
|
|
380
|
-
c: Context;
|
|
381
|
-
session: sessionCtx;
|
|
382
|
-
}) => {
|
|
383
|
-
isStale: boolean;
|
|
384
|
-
data: any;
|
|
385
|
-
};
|
|
386
|
-
};
|
|
323
|
+
|
|
387
324
|
schema?: object;
|
|
388
325
|
auth?: {
|
|
389
326
|
enabled?: boolean;
|
package/utils/os.ts
CHANGED
|
@@ -1 +1,22 @@
|
|
|
1
|
-
|
|
1
|
+
import pidusage from "pidusage";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Retourne les stats CPU/RAM pour un ou plusieurs PIDs.
|
|
5
|
+
* @param {number[]} pids - Liste des PIDs à surveiller.
|
|
6
|
+
* @returns {Promise<{ pid: number, cpu: number, ram: number, elapsed: number }[]>}
|
|
7
|
+
*/
|
|
8
|
+
export async function getPidUsage(pids = [process.pid]) {
|
|
9
|
+
try {
|
|
10
|
+
const stats = await pidusage(pids);
|
|
11
|
+
|
|
12
|
+
return Object.entries(stats).map(([pid, usage]) => ({
|
|
13
|
+
pid: Number(pid),
|
|
14
|
+
cpu: usage.cpu, // en %
|
|
15
|
+
ram: usage.memory / 1024 / 1024, // en MB
|
|
16
|
+
elapsed: usage.elapsed / 1000, // uptime en secondes
|
|
17
|
+
}));
|
|
18
|
+
} catch (err) {
|
|
19
|
+
console.error("Erreur getPidUsage:", err.message);
|
|
20
|
+
return [];
|
|
21
|
+
}
|
|
22
|
+
}
|
package/utils/port.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import net from "net";
|
|
2
|
+
import type { AddressInfo } from "net";
|
|
3
|
+
function findPort() {
|
|
4
|
+
return new Promise((resolve, reject) => {
|
|
5
|
+
const server = net.createServer();
|
|
6
|
+
server.on("error", reject);
|
|
7
|
+
server.listen(0, () => {
|
|
8
|
+
const { port, address } = server.address() as AddressInfo;
|
|
9
|
+
server.on("close", resolve.bind(null, port));
|
|
10
|
+
server.close();
|
|
11
|
+
});
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function isAvailable(port: number): Promise<boolean> {
|
|
16
|
+
return new Promise((resolve, reject) => {
|
|
17
|
+
const socket = net.connect(port);
|
|
18
|
+
socket.setTimeout(500, () => {
|
|
19
|
+
socket.destroy();
|
|
20
|
+
const error = new Error("ETIMEDOUT") as any;
|
|
21
|
+
error.code = "ETIMEDOUT";
|
|
22
|
+
reject(error);
|
|
23
|
+
});
|
|
24
|
+
socket.on("error", (error: any) => {
|
|
25
|
+
if (error.code === "ECONNREFUSED") {
|
|
26
|
+
return resolve(true);
|
|
27
|
+
}
|
|
28
|
+
return reject(error);
|
|
29
|
+
});
|
|
30
|
+
socket.on("connect", () => {
|
|
31
|
+
socket.destroy();
|
|
32
|
+
resolve(false);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
findPort.findPort = findPort;
|
|
38
|
+
findPort.default = findPort;
|
|
39
|
+
findPort.isAvailable = isAvailable;
|
|
40
|
+
|
|
41
|
+
export { findPort };
|
package/utils/vine.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import vine from "@vinejs/vine";
|
|
2
|
+
function partialSchema<T extends Record<string, any>>(schema: T) {
|
|
3
|
+
const entries = Object.entries(schema).map(([key, value]) => {
|
|
4
|
+
return [key, value.optional()];
|
|
5
|
+
});
|
|
6
|
+
//
|
|
7
|
+
return vine.object(Object.fromEntries(entries));
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export { partialSchema };
|
package/bin/_.ts
DELETED
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
#! /usr/bin/env bun
|
|
2
|
-
|
|
3
|
-
import ch from "chokidar";
|
|
4
|
-
import { spinner } from "@clack/prompts";
|
|
5
|
-
import "@colors/colors";
|
|
6
|
-
var exec;
|
|
7
|
-
var s = spinner();
|
|
8
|
-
function runPkg(
|
|
9
|
-
opts = {
|
|
10
|
-
stopSpinner: false,
|
|
11
|
-
}
|
|
12
|
-
) {
|
|
13
|
-
if (opts?.stopSpinner) {
|
|
14
|
-
s.stop();
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
exec = Bun.spawn([`bun`, `index.ts`], {
|
|
18
|
-
stdio: ["inherit", "inherit", "inherit"],
|
|
19
|
-
serialization: "json",
|
|
20
|
-
stdin: "inherit",
|
|
21
|
-
ipc(message, subprocess) {
|
|
22
|
-
console.log(message);
|
|
23
|
-
},
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// Écoutez le signal SIGINT (Ctrl + C)
|
|
28
|
-
process.on("SIGINT", () => {
|
|
29
|
-
if (exec?.kill) exec.kill();
|
|
30
|
-
process.exit(1); // Terminez le processus principal
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
ch.watch(".", {
|
|
34
|
-
cwd: process.cwd(),
|
|
35
|
-
ignored: [
|
|
36
|
-
/.*\.(jpg|jpeg|png|gif|bmp|svg|webp|dump|zip|rar|.git|.lockb|package.json)$/i,
|
|
37
|
-
/node_modules|node_modules\/.*/,
|
|
38
|
-
/node_modules/,
|
|
39
|
-
/(^|[\/\\])\../,
|
|
40
|
-
"node_modules/**/*",
|
|
41
|
-
".env.*",
|
|
42
|
-
".env",
|
|
43
|
-
".nitro",
|
|
44
|
-
".git",
|
|
45
|
-
".output",
|
|
46
|
-
".vscode",
|
|
47
|
-
".idea",
|
|
48
|
-
".DS_Store",
|
|
49
|
-
".env.local",
|
|
50
|
-
".env.development",
|
|
51
|
-
".env.test",
|
|
52
|
-
".env.production",
|
|
53
|
-
"node_modules",
|
|
54
|
-
"package.json",
|
|
55
|
-
"package-lock.json",
|
|
56
|
-
"yarn.lock",
|
|
57
|
-
"yarn-error.log",
|
|
58
|
-
"bun.lockb",
|
|
59
|
-
"bun.lock",
|
|
60
|
-
"*.docs",
|
|
61
|
-
".docx",
|
|
62
|
-
".pdf",
|
|
63
|
-
".xlsx",
|
|
64
|
-
".pptx",
|
|
65
|
-
".zip",
|
|
66
|
-
"package-lock.json",
|
|
67
|
-
"yarn.lock",
|
|
68
|
-
"tsconfig.json",
|
|
69
|
-
"tsconfig.tsbuildinfo",
|
|
70
|
-
"*.tsbuildinfo",
|
|
71
|
-
"*.log",
|
|
72
|
-
"*.tgz",
|
|
73
|
-
"/.git",
|
|
74
|
-
"/.github",
|
|
75
|
-
"/.vscode",
|
|
76
|
-
"/.idea",
|
|
77
|
-
"/coverage",
|
|
78
|
-
"/dist",
|
|
79
|
-
"/build",
|
|
80
|
-
"/node_modules",
|
|
81
|
-
"/package-lock.json",
|
|
82
|
-
"/yarn.lock",
|
|
83
|
-
".cache",
|
|
84
|
-
"dist",
|
|
85
|
-
"*/dist",
|
|
86
|
-
"*.zip",
|
|
87
|
-
"*.log",
|
|
88
|
-
".DS_Store",
|
|
89
|
-
"*.tar",
|
|
90
|
-
"*.tar.gz",
|
|
91
|
-
"build",
|
|
92
|
-
"*.lockb",
|
|
93
|
-
"coverage",
|
|
94
|
-
"packages/*/dist",
|
|
95
|
-
"packages/*/build",
|
|
96
|
-
"packages/*/coverage",
|
|
97
|
-
"packages/*/node_modules",
|
|
98
|
-
],
|
|
99
|
-
})
|
|
100
|
-
.on("change", (path) => {
|
|
101
|
-
console.log("Changed file:".gray, path.green);
|
|
102
|
-
let dev = process.argv.includes("--dev");
|
|
103
|
-
if (dev && (path?.endsWith(".ts") || path?.endsWith(".js"))) {
|
|
104
|
-
s.start("Restarting due to changes ...");
|
|
105
|
-
if (exec?.kill) {
|
|
106
|
-
exec.kill();
|
|
107
|
-
}
|
|
108
|
-
setTimeout(() => {
|
|
109
|
-
runPkg({ stopSpinner: true });
|
|
110
|
-
}, 1500);
|
|
111
|
-
}
|
|
112
|
-
})
|
|
113
|
-
.on("ready", () => {
|
|
114
|
-
let dev = process.argv.includes("--dev");
|
|
115
|
-
let start = process.argv.includes("--start");
|
|
116
|
-
if (dev || start) {
|
|
117
|
-
runPkg();
|
|
118
|
-
} else {
|
|
119
|
-
process.exit();
|
|
120
|
-
}
|
|
121
|
-
});
|
package/lib/meilisearch/index.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { MeiliSearch } from "meilisearch";
|
|
2
|
-
import { Cfg } from "../../config";
|
|
3
|
-
function getClient(config: {
|
|
4
|
-
host: string;
|
|
5
|
-
apiKey?: string;
|
|
6
|
-
}): InstanceType<typeof MeiliSearch> {
|
|
7
|
-
const client = new MeiliSearch({
|
|
8
|
-
host: config?.host,
|
|
9
|
-
apiKey: config?.apiKey,
|
|
10
|
-
});
|
|
11
|
-
return client;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
async function syncMeilisearchClientOnTenant() {
|
|
15
|
-
for await (let t of Cfg.tenants) {
|
|
16
|
-
if (t?.searchEngine?.meilisearch?.enabled) {
|
|
17
|
-
t.searchEngine.meilisearch.client = getClient({
|
|
18
|
-
host: t.searchEngine.meilisearch.host,
|
|
19
|
-
apiKey: t.searchEngine.meilisearch.apiKey,
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export { MeiliSearch, getClient, syncMeilisearchClientOnTenant };
|