@dnax/core 0.0.1

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/lib/media.ts ADDED
@@ -0,0 +1,74 @@
1
+ import { cleanDoubleSlashes } from "ufo";
2
+ import fs from "fs";
3
+ import { v4 } from "uuid";
4
+ type driverOptions = {
5
+ location: string;
6
+ visibility?: "public" | "private";
7
+ };
8
+
9
+ function formatFileName(texte: string) {
10
+ texte = v4() + "-" + texte;
11
+ // Enlever les diacritiques
12
+ texte = texte?.normalize("NFD").replace(/[\u0300-\u036f]/g, "");
13
+ texte = texte?.replace(/\s/g, "");
14
+ return texte;
15
+ }
16
+
17
+ function formatPath(path: string) {
18
+ return cleanDoubleSlashes(path);
19
+ }
20
+
21
+ class MediaDrive {
22
+ options: driverOptions;
23
+ #driver: driverOptions;
24
+ constructor(options: driverOptions) {
25
+ this.options = options;
26
+ this.#driver = {
27
+ location:
28
+ process.cwd() +
29
+ "/uploads/" +
30
+ options.location +
31
+ "/" +
32
+ options?.visibility || "public/",
33
+ visibility: options.visibility,
34
+ };
35
+ this.initialize();
36
+ }
37
+
38
+ async initialize() {
39
+ if (!fs.existsSync(formatPath(this.#driver.location))) {
40
+ fs.mkdirSync(formatPath(this.#driver.location), { recursive: true });
41
+ }
42
+ }
43
+
44
+ async write(filename: string, contents: any) {
45
+ let name = filename;
46
+ filename = formatFileName(filename);
47
+
48
+ let dest = this.#driver.location + "/" + filename;
49
+ await Bun.write(formatPath(dest), contents);
50
+ let file = await Bun.file(dest);
51
+ let diskPath =
52
+ cleanDoubleSlashes(
53
+ "/files/" + this.options.location + "/" + this.options?.visibility ??
54
+ "/public//"
55
+ ) +
56
+ "/" +
57
+ filename;
58
+
59
+ return {
60
+ original_name: name,
61
+ name: filename,
62
+ type: file.type,
63
+ size: file.size,
64
+ path: diskPath,
65
+ //url: url,
66
+ };
67
+ }
68
+
69
+ async get(filename: string) {
70
+ return await Bun.file(formatPath(this.#driver.location + "/" + filename));
71
+ }
72
+ }
73
+
74
+ export { MediaDrive };
package/lib/schema.ts ADDED
@@ -0,0 +1,112 @@
1
+ import type { Collection } from "../types";
2
+ import * as v from "valibot";
3
+ function buildSchema(col: Collection) {
4
+ let propertySchema = {};
5
+
6
+ if (col?.media) {
7
+ propertySchema["_file"] = v.object({});
8
+ }
9
+
10
+ col?.fields?.map((f) => {
11
+ if (f?.type == "array") {
12
+ propertySchema[f.name] = v.array(v.any());
13
+ }
14
+
15
+ if (f?.type == "random" && f?.random?.toNumber) {
16
+ propertySchema[f.name] = v.number();
17
+ }
18
+ if (f?.type == "random" && !f?.random?.toNumber) {
19
+ propertySchema[f.name] = v.string();
20
+ }
21
+
22
+ if (f?.type.match(/(string|richText|textarea)/)) {
23
+ propertySchema[f.name] = v.string();
24
+ }
25
+
26
+ if (f.type == "number") {
27
+ propertySchema[f.name] = v.number();
28
+ }
29
+ if (f.type == "integer") {
30
+ propertySchema[f.name] = v.pipe(v.number(), v.integer());
31
+ }
32
+
33
+ if (f?.type == "boolean") {
34
+ propertySchema[f.name] = v.boolean();
35
+ }
36
+ if (f?.type == "json") {
37
+ propertySchema[f.name] = v.object({});
38
+ }
39
+ if (f?.type == "email") {
40
+ propertySchema[f.name] = v.pipe(v.string(), v.email());
41
+ }
42
+
43
+ if (f?.type == "relationship" && f.relationType == "ref-to-one") {
44
+ propertySchema[f.name] = v.string();
45
+ }
46
+
47
+ if (f?.type == "relationship" && f.relationType == "ref-to-many") {
48
+ propertySchema[f.name] = v.array(v.string());
49
+ }
50
+
51
+ if (f?.type?.match(/(date)/)) {
52
+ propertySchema[f.name] = v.date();
53
+ }
54
+
55
+ if (f?.type == "file") {
56
+ propertySchema[f.name] = v.object({});
57
+ }
58
+
59
+ if (f?.type == "url") {
60
+ propertySchema[f.name] = v.pipe(v.string(), v.url());
61
+ }
62
+
63
+ if (f?.type == "ipv4") {
64
+ propertySchema[f.name] = v.pipe(v.string(), v.ipv4());
65
+ }
66
+ if (f?.type == "ipv6") {
67
+ propertySchema[f.name] = v.pipe(v.string(), v.ipv6());
68
+ }
69
+
70
+ if (f?.type == "geojson") {
71
+ propertySchema[f.name] = v.object({
72
+ type: v.picklist(["Point", "LineString", "Polygon", "MultiPoint"]),
73
+ coordinates: v.array(v.number()),
74
+ });
75
+ }
76
+
77
+ if (f?.type == "random") {
78
+ propertySchema[f.name] = v.any();
79
+ }
80
+
81
+ if (f?.type == "password") {
82
+ propertySchema[f.name] = v.string();
83
+ }
84
+
85
+ if (f?.type == "enum") {
86
+ let items: Array<any> = [];
87
+ f?.enum?.items?.map((item) => {
88
+ if (typeof item == "string") {
89
+ items.push(item);
90
+ }
91
+ if (typeof item == "object") {
92
+ items.push(item?.value);
93
+ }
94
+ });
95
+ items = [...new Set(items)];
96
+
97
+ if (f?.enum?.multiple) {
98
+ propertySchema[f.name] = v.array(v.picklist(items || []));
99
+ } else {
100
+ propertySchema[f.name] = v.picklist(items || []);
101
+ }
102
+ }
103
+
104
+ if (f?.nullable) {
105
+ propertySchema[f.name] = v.nullish(propertySchema[f.name]);
106
+ }
107
+ });
108
+
109
+ return v.object(propertySchema, v.never());
110
+ }
111
+
112
+ export { buildSchema };
package/lib/service.ts ADDED
@@ -0,0 +1,43 @@
1
+ import { omit } from "radash";
2
+ import type { Collection, Endpoint, Field, Service } from "./../types/index";
3
+ import { Glob } from "bun";
4
+ import { Cfg } from "../config";
5
+ import { cleanPath, resolvePath } from "../utils";
6
+ import path from "path";
7
+ import { useRest } from "../driver/mongo/rest";
8
+
9
+ async function loadServices() {
10
+ let services: Service[] = [];
11
+ if (Cfg.tenants) {
12
+ for await (let t of Cfg.tenants) {
13
+ let tenantPath = `${t.dir}/services/**/**.service.{ts,js}`;
14
+ const glob = new Glob(tenantPath);
15
+ for await (let file of glob.scan({
16
+ cwd: Cfg.cwd,
17
+ })) {
18
+ let fullPathFile = path.join(Cfg.cwd || "", file);
19
+
20
+ await import(fullPathFile)
21
+ .then((inject) => {
22
+ services.push({
23
+ ...inject?.default,
24
+ tenant_id: t.id,
25
+ });
26
+ })
27
+ .catch((err) => {
28
+ console.error(err);
29
+ });
30
+ }
31
+ }
32
+ }
33
+
34
+ Cfg.services = services;
35
+ }
36
+
37
+ function getService(name: string, tenant_id: string): Service | undefined {
38
+ return Cfg.services?.find(
39
+ (s) => s?.tenant_id == tenant_id && s?.name == name && s?.fx
40
+ );
41
+ }
42
+
43
+ export { loadServices, getService };
package/lib/socket.ts ADDED
@@ -0,0 +1,51 @@
1
+ import { Cfg } from "../config";
2
+ import { Server } from "socket.io";
3
+ import consola from "consola";
4
+ import { Glob } from "bun";
5
+ import path from "path";
6
+ import { useRest } from "../driver/mongo";
7
+ async function loadSocket() {
8
+ var io = new Server(Number(Cfg.server?.socket?.port || 9000), {
9
+ cors: {
10
+ ...Cfg.server.cors,
11
+ credentials: true,
12
+ },
13
+ });
14
+ /* io.on("connection", (socket) => {
15
+ console.log("ok");
16
+ }); */
17
+ if (Cfg.tenants) {
18
+ for await (let t of Cfg.tenants) {
19
+ let tenantPath = `${t.dir}/sockets/**/**.ws.{ts,js}`;
20
+ const glob = new Glob(tenantPath);
21
+ for await (let file of glob.scan({
22
+ cwd: Cfg.cwd,
23
+ })) {
24
+ let fullPathFile = path.join(Cfg.cwd || "", file);
25
+ await import(fullPathFile)
26
+ .then((inject) => {
27
+ let socketInstance = inject?.default || null;
28
+ if (
29
+ socketInstance &&
30
+ socketInstance?.enabled &&
31
+ socketInstance?.handler
32
+ ) {
33
+ let rest = new useRest({
34
+ tenant_id: t.id,
35
+ });
36
+ socketInstance.handler({
37
+ io,
38
+ rest,
39
+ });
40
+ }
41
+ })
42
+ .catch((err) => {
43
+ consola.error(file || "", err?.message);
44
+ });
45
+ }
46
+ }
47
+ }
48
+ Cfg.io = io;
49
+ }
50
+
51
+ export { loadSocket };
package/lib/studio.ts ADDED
@@ -0,0 +1,12 @@
1
+ import { Cfg } from "../config";
2
+
3
+ function isStudio(key: string) {
4
+ if (!key) return false;
5
+
6
+ let canPerform = false;
7
+ if (Cfg.studio?.secretKey == key && Cfg.studio?.enabled) canPerform = true;
8
+
9
+ return canPerform;
10
+ }
11
+
12
+ export { isStudio };
package/lib/tenant.ts ADDED
@@ -0,0 +1,9 @@
1
+ import { Cfg } from "../config";
2
+ import type { Tenant } from "../types";
3
+
4
+ function getTenant(id: string): Tenant | any {
5
+ let tenant = Cfg.tenants.find((t) => t.id == id);
6
+ return tenant;
7
+ }
8
+
9
+ export { getTenant };
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@dnax/core",
3
+ "version": "0.0.1",
4
+ "module": "index.ts",
5
+ "type": "module",
6
+ "devDependencies": {
7
+ "@types/bun": "latest"
8
+ },
9
+ "peerDependencies": {
10
+ "typescript": "^5.0.0"
11
+ },
12
+ "dependencies": {
13
+ "@colors/colors": "^1.6.0",
14
+ "@google/generative-ai": "0.14.0",
15
+ "@lukeed/ms": "^2.0.2",
16
+ "@types/jsonwebtoken": "^9.0.6",
17
+ "boxen": "^7.1.1",
18
+ "clean-deep": "^3.4.0",
19
+ "consola": "^3.2.3",
20
+ "cookie": "^0.6.0",
21
+ "croner": "^8.0.2",
22
+ "find-open-port": "^2.0.3",
23
+ "generate-unique-id": "^2.0.3",
24
+ "hono": "^4.4.3",
25
+ "hono-sessions": "^0.5.8",
26
+ "json-joy": "^16.8.0",
27
+ "jsonwebtoken": "^9.0.2",
28
+ "mingo": "^6.4.15",
29
+ "moment": "^2.30.1",
30
+ "mongodb": "^6.7.0",
31
+ "radash": "^12.1.0",
32
+ "signaldb": "^0.9.0",
33
+ "socket.io": "^4.7.5",
34
+ "ufo": "^1.5.3",
35
+ "uuid": "^10.0.0",
36
+ "valibot": "^0.31.0"
37
+ }
38
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "compilerOptions": {
3
+ // Enable latest features
4
+ "lib": ["ESNext", "DOM"],
5
+ "target": "ESNext",
6
+ "module": "ESNext",
7
+ "moduleDetection": "force",
8
+ "jsx": "react-jsx",
9
+ "allowJs": true,
10
+
11
+ // Bundler mode
12
+ "moduleResolution": "bundler",
13
+ "allowImportingTsExtensions": true,
14
+ "verbatimModuleSyntax": true,
15
+ "noEmit": true,
16
+
17
+ // Best practices
18
+ "strict": true,
19
+ "skipLibCheck": true,
20
+ "noFallthroughCasesInSwitch": true,
21
+
22
+ // Some stricter flags (disabled by default)
23
+ "noUnusedLocals": false,
24
+ "noUnusedParameters": false,
25
+ "noPropertyAccessFromIndexSignature": false
26
+ }
27
+ }