@dnax/core 0.2.4 → 0.2.6
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 +14 -0
- package/define/index.ts +21 -1
- package/driver/mongo/utils.ts +4 -4
- package/lib/cron/index.ts +49 -0
- package/lib/index.ts +3 -0
- package/lib/schema.ts +2 -2
- package/package.json +4 -3
- package/types/index.ts +36 -3
package/app/hono.ts
CHANGED
|
@@ -126,6 +126,18 @@ function HonoInstance(): typeof app {
|
|
|
126
126
|
let colAccess = col?.access?.hasOwnProperty(action) || null;
|
|
127
127
|
let nextLifecyle: any = false;
|
|
128
128
|
|
|
129
|
+
// Middleware for apis
|
|
130
|
+
for await (let midd of col?.middlewares!) {
|
|
131
|
+
await midd({
|
|
132
|
+
token: c.var["token"] || null,
|
|
133
|
+
action: action,
|
|
134
|
+
c: c,
|
|
135
|
+
isAuth: c.var?._v?.isAuth || false,
|
|
136
|
+
rest: new useRest({ tenant_id: tenant_id }),
|
|
137
|
+
session: session as any,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
|
|
129
141
|
if (col && col?.access?.beforeAction) {
|
|
130
142
|
await col?.access?.beforeAction({
|
|
131
143
|
token: c.var["token"] || null,
|
|
@@ -217,6 +229,7 @@ function HonoInstance(): typeof app {
|
|
|
217
229
|
if (action == "execService") {
|
|
218
230
|
if (!service) return fn.error("Service not found", 404);
|
|
219
231
|
response = await service.fx({
|
|
232
|
+
io: Cfg.io,
|
|
220
233
|
data: body?.data || {},
|
|
221
234
|
rest: rest,
|
|
222
235
|
error: fn.error,
|
|
@@ -243,6 +256,7 @@ function HonoInstance(): typeof app {
|
|
|
243
256
|
) {
|
|
244
257
|
if (action == "authCollection") {
|
|
245
258
|
let reponse;
|
|
259
|
+
|
|
246
260
|
if (!col?.auth?.enabled) fn.error("Auth not enabled", 401);
|
|
247
261
|
if (!col?.auth?.handler) fn.error("Auth handler not set", 401);
|
|
248
262
|
if (col?.auth?.handler) {
|
package/define/index.ts
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
Collection,
|
|
3
|
+
Config,
|
|
4
|
+
Endpoint,
|
|
5
|
+
Service,
|
|
6
|
+
Socket,
|
|
7
|
+
cronConfig,
|
|
8
|
+
cronCtx,
|
|
9
|
+
middlewareCtx,
|
|
10
|
+
} from "../types";
|
|
2
11
|
import { Cfg } from "../config/";
|
|
3
12
|
import { deepMerge, freeze } from "../utils";
|
|
4
13
|
import { config } from "valibot";
|
|
@@ -23,6 +32,14 @@ function WebSocket(config: Socket) {
|
|
|
23
32
|
return config;
|
|
24
33
|
}
|
|
25
34
|
|
|
35
|
+
function Middleware(ctx: middlewareCtx) {
|
|
36
|
+
return ctx;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function Task(config: cronConfig) {
|
|
40
|
+
return config;
|
|
41
|
+
}
|
|
42
|
+
|
|
26
43
|
const define = {
|
|
27
44
|
Service,
|
|
28
45
|
Config,
|
|
@@ -30,6 +47,9 @@ const define = {
|
|
|
30
47
|
Endpoint,
|
|
31
48
|
App: Config,
|
|
32
49
|
WebSocket,
|
|
50
|
+
Middleware,
|
|
51
|
+
Task,
|
|
52
|
+
Cron: Task,
|
|
33
53
|
};
|
|
34
54
|
|
|
35
55
|
export default define;
|
package/driver/mongo/utils.ts
CHANGED
|
@@ -60,13 +60,13 @@ function buildPipeline(params: findParam, col?: Collection | undefined | null) {
|
|
|
60
60
|
if (field) {
|
|
61
61
|
pipeline.push({
|
|
62
62
|
$lookup: {
|
|
63
|
-
from: field.
|
|
63
|
+
from: field.relation?.to,
|
|
64
64
|
localField: inc,
|
|
65
65
|
foreignField: "_id",
|
|
66
66
|
as: inc,
|
|
67
67
|
},
|
|
68
68
|
});
|
|
69
|
-
if (field.
|
|
69
|
+
if (!field.relation?.hasMany) {
|
|
70
70
|
pipeline.push({
|
|
71
71
|
$unwind: {
|
|
72
72
|
path: `$${inc}`,
|
|
@@ -81,7 +81,7 @@ function buildPipeline(params: findParam, col?: Collection | undefined | null) {
|
|
|
81
81
|
let field = getFieldCollection(inc?.localField, col);
|
|
82
82
|
pipeline.push({
|
|
83
83
|
$lookup: {
|
|
84
|
-
from: inc?.from || field?.
|
|
84
|
+
from: inc?.from || field?.relation?.to,
|
|
85
85
|
localField: inc?.localField || field?.name,
|
|
86
86
|
foreignField: inc?.foreignField || "_id",
|
|
87
87
|
as: inc?.as || inc?.localField || field?.name,
|
|
@@ -89,7 +89,7 @@ function buildPipeline(params: findParam, col?: Collection | undefined | null) {
|
|
|
89
89
|
},
|
|
90
90
|
});
|
|
91
91
|
|
|
92
|
-
if (field?.
|
|
92
|
+
if (!field?.relation?.hasMany) {
|
|
93
93
|
pipeline.push({
|
|
94
94
|
$unwind: {
|
|
95
95
|
path: `$${inc?.as || inc?.localField || field?.name}`,
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Cron } from "croner";
|
|
2
|
+
import { Glob } from "bun";
|
|
3
|
+
import { Cfg } from "../../config";
|
|
4
|
+
import path from "path";
|
|
5
|
+
import type { cronConfig } from "../../types";
|
|
6
|
+
import cleanDeep from "clean-deep";
|
|
7
|
+
import { useRest } from "../../driver/mongo";
|
|
8
|
+
async function initCron() {
|
|
9
|
+
let cronTasks = [];
|
|
10
|
+
if (Cfg?.tenants?.length) {
|
|
11
|
+
for await (let t of Cfg.tenants) {
|
|
12
|
+
let tenantPath = `${t.dir}/tasks/**/**.cron.{ts,js}`;
|
|
13
|
+
const glob = new Glob(tenantPath);
|
|
14
|
+
for await (let file of glob.scan({
|
|
15
|
+
cwd: Cfg.cwd,
|
|
16
|
+
})) {
|
|
17
|
+
let fullPathFile = path.join(Cfg.cwd || "", file);
|
|
18
|
+
await import(fullPathFile)
|
|
19
|
+
.then((inject) => {
|
|
20
|
+
let cronOpt = inject.default as cronConfig;
|
|
21
|
+
if (cronOpt?.enabled) {
|
|
22
|
+
let cronTask = new Cron(cronOpt.pattern, {
|
|
23
|
+
...cleanDeep(cronOpt.options),
|
|
24
|
+
});
|
|
25
|
+
cronOpt.handler({
|
|
26
|
+
io: Cfg.io,
|
|
27
|
+
rest: new useRest({
|
|
28
|
+
tenant_id: t.id,
|
|
29
|
+
}),
|
|
30
|
+
task: cronTask,
|
|
31
|
+
});
|
|
32
|
+
cronTasks.push({
|
|
33
|
+
tenant_id: t.id,
|
|
34
|
+
name: cronOpt.name,
|
|
35
|
+
cron: cronOpt,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
})
|
|
39
|
+
.catch((err) => {
|
|
40
|
+
console.error(err);
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
//Cfg.endpoints = endpoints;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export { initCron };
|
package/lib/index.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { loadAllCollections, syncCollectionDatabase } from "./collection";
|
|
|
2
2
|
import { connectTenantsDatabase } from "../driver";
|
|
3
3
|
import { loadEndpoints } from "./endpoint";
|
|
4
4
|
import { loadServices } from "./service";
|
|
5
|
+
import { initCron } from "./cron";
|
|
5
6
|
import { loadSocket } from "./socket";
|
|
6
7
|
// load all ressource
|
|
7
8
|
async function init(cf = { app: null }) {
|
|
@@ -21,6 +22,8 @@ async function init(cf = { app: null }) {
|
|
|
21
22
|
|
|
22
23
|
// load all loadEndpoints
|
|
23
24
|
await loadEndpoints();
|
|
25
|
+
|
|
26
|
+
await initCron();
|
|
24
27
|
}
|
|
25
28
|
|
|
26
29
|
export { init };
|
package/lib/schema.ts
CHANGED
|
@@ -49,11 +49,11 @@ function buildSchema(col: Collection) {
|
|
|
49
49
|
propertySchema[f.name] = v.string().email();
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
if (f?.type == "relationship"
|
|
52
|
+
if (f?.type == "relationship") {
|
|
53
53
|
propertySchema[f.name] = v.string().optional();
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
if (f?.type == "relationship" && f.
|
|
56
|
+
if (f?.type == "relationship" && f.relation?.hasMany) {
|
|
57
57
|
propertySchema[f.name] = v.array().optional();
|
|
58
58
|
}
|
|
59
59
|
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dnax/core",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.6",
|
|
4
4
|
"module": "index.ts",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
-
"
|
|
7
|
+
"dnaxi": "./bin/index.ts"
|
|
8
8
|
},
|
|
9
9
|
"devDependencies": {
|
|
10
10
|
"@types/bun": "latest",
|
|
@@ -20,12 +20,13 @@
|
|
|
20
20
|
"@lukeed/ms": "^2.0.2",
|
|
21
21
|
"@types/jsonwebtoken": "^9.0.6",
|
|
22
22
|
"boxen": "^7.1.1",
|
|
23
|
+
"bree": "^9.2.4",
|
|
23
24
|
"chokidar": "^3.6.0",
|
|
24
25
|
"clean-deep": "^3.4.0",
|
|
25
26
|
"collect.js": "^4.36.1",
|
|
26
27
|
"consola": "^3.2.3",
|
|
27
28
|
"cookie": "^0.6.0",
|
|
28
|
-
"croner": "^8.
|
|
29
|
+
"croner": "^8.1.1",
|
|
29
30
|
"find-open-port": "^2.0.3",
|
|
30
31
|
"generate-unique-id": "^2.0.3",
|
|
31
32
|
"hono": "^4.4.3",
|
package/types/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { AnySchema } from "joi";
|
|
2
|
+
import { Cron } from "croner";
|
|
2
3
|
import { updateParams } from "./../driver/mongo/@types";
|
|
3
4
|
import * as v from "valibot";
|
|
4
5
|
import type { Db, MongoClient } from "mongodb";
|
|
@@ -102,9 +103,12 @@ export type Field = {
|
|
|
102
103
|
unique?: boolean;
|
|
103
104
|
index?: boolean | "text" | "2dsphere";
|
|
104
105
|
description?: string;
|
|
105
|
-
|
|
106
|
+
relation?: {
|
|
107
|
+
to: string; // collection name
|
|
108
|
+
hasMany?: boolean;
|
|
109
|
+
};
|
|
106
110
|
sparse?: boolean;
|
|
107
|
-
relationType?: "ref-to-one" | "ref-to-many";
|
|
111
|
+
// relationType?: "ref-to-one" | "ref-to-many";
|
|
108
112
|
/**
|
|
109
113
|
* Overwrite custom validation schema
|
|
110
114
|
* use {v} from "@dnax/core"} to build your own validation
|
|
@@ -116,6 +120,34 @@ export type Field = {
|
|
|
116
120
|
relationTo?: string;
|
|
117
121
|
};
|
|
118
122
|
|
|
123
|
+
export type cronCtx = {
|
|
124
|
+
rest: InstanceType<typeof useRest>;
|
|
125
|
+
io: Io;
|
|
126
|
+
task: InstanceType<typeof Cron>;
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
export type cronConfig = {
|
|
130
|
+
name: string;
|
|
131
|
+
enabled?: boolean;
|
|
132
|
+
pattern: string;
|
|
133
|
+
options?: {
|
|
134
|
+
maxRuns?: Number;
|
|
135
|
+
startAt?: Date;
|
|
136
|
+
stopAt?: Date;
|
|
137
|
+
paused?: Boolean;
|
|
138
|
+
};
|
|
139
|
+
handler: (ctx: cronCtx) => void;
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
export type middlewareCtx = (ctx: {
|
|
143
|
+
token?: string;
|
|
144
|
+
action?: Actions;
|
|
145
|
+
c?: Context;
|
|
146
|
+
isAuth: boolean;
|
|
147
|
+
rest: InstanceType<typeof useRest>;
|
|
148
|
+
session: sessionCtx;
|
|
149
|
+
}) => boolean | undefined | void | Promise<any>;
|
|
150
|
+
|
|
119
151
|
export type accessCtx = (ctx: {
|
|
120
152
|
token?: string;
|
|
121
153
|
action?: Actions;
|
|
@@ -123,7 +155,7 @@ export type accessCtx = (ctx: {
|
|
|
123
155
|
isAuth: boolean;
|
|
124
156
|
rest: InstanceType<typeof useRest>;
|
|
125
157
|
session: sessionCtx;
|
|
126
|
-
}) => boolean | undefined | void
|
|
158
|
+
}) => boolean | undefined | void | Promise<any>;
|
|
127
159
|
|
|
128
160
|
export type sessionCtx = {
|
|
129
161
|
set: (session: { state: object | any; token?: string; _v?: object }) => void;
|
|
@@ -209,6 +241,7 @@ export type Collection = {
|
|
|
209
241
|
session: sessionCtx;
|
|
210
242
|
}) => boolean | any;
|
|
211
243
|
};
|
|
244
|
+
middlewares?: Array<middlewareCtx>;
|
|
212
245
|
hooks?: {
|
|
213
246
|
beforeOperation?: hooksCtx;
|
|
214
247
|
beforeFind?: hooksCtx;
|