@dnax/core 0.18.5 → 0.18.7
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/define/index.ts +2 -0
- package/driver/mongo/rest.ts +2 -2
- package/index.ts +8 -0
- package/lib/index.ts +4 -0
- package/lib/media/SyncAdapter.ts +22 -0
- package/lib/{media.ts → media/index.ts} +3 -1
- package/lib/media/sftp.ts +123 -0
- package/lib/schema.ts +2 -2
- package/package.json +6 -5
- package/types/index.ts +2 -0
package/define/index.ts
CHANGED
package/driver/mongo/rest.ts
CHANGED
|
@@ -311,7 +311,7 @@ class useRest {
|
|
|
311
311
|
let result = await col?.customApi?.insertOne({
|
|
312
312
|
io: Cfg.io,
|
|
313
313
|
session: sessionStorage(),
|
|
314
|
-
data: data,
|
|
314
|
+
data: toJson(data),
|
|
315
315
|
rest: new useRest({
|
|
316
316
|
useHook: false,
|
|
317
317
|
tenant_id: this.#tenant_id,
|
|
@@ -433,7 +433,7 @@ class useRest {
|
|
|
433
433
|
let result = await col?.customApi?.insertMany({
|
|
434
434
|
io: Cfg.io,
|
|
435
435
|
session: sessionStorage(),
|
|
436
|
-
data: data,
|
|
436
|
+
data: toJson(data),
|
|
437
437
|
rest: new useRest({
|
|
438
438
|
useHook: false,
|
|
439
439
|
tenant_id: this.#tenant_id,
|
package/index.ts
CHANGED
|
@@ -7,9 +7,16 @@ import { $ } from "bun";
|
|
|
7
7
|
import define from "./define";
|
|
8
8
|
import * as utils from "./utils";
|
|
9
9
|
import { dataCache } from "./lib/bento";
|
|
10
|
+
import { FilesystemSftpAdapter } from "./lib/media";
|
|
10
11
|
import { crypt } from "./lib/crypto";
|
|
11
12
|
import { contextStorage } from "./lib/asyncLocalStorage";
|
|
12
13
|
|
|
14
|
+
// Adapter
|
|
15
|
+
|
|
16
|
+
const Adapter = {
|
|
17
|
+
FilesystemSftpAdapter,
|
|
18
|
+
};
|
|
19
|
+
|
|
13
20
|
/**
|
|
14
21
|
* v is internal data validation and based of Joi validation.
|
|
15
22
|
* Note : v is an alias of Joi object API .
|
|
@@ -27,4 +34,5 @@ export {
|
|
|
27
34
|
crypt,
|
|
28
35
|
$,
|
|
29
36
|
contextStorage,
|
|
37
|
+
Adapter,
|
|
30
38
|
};
|
package/lib/index.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { loadPermissions } from "./permissions";
|
|
|
7
7
|
import { loadSocket } from "../lib/socket";
|
|
8
8
|
import { loadAutoRoutes } from "./routes";
|
|
9
9
|
import { initScript } from "../lib/scripts";
|
|
10
|
+
import { syncAdapterFileSystem } from "./media";
|
|
10
11
|
// load all ressource
|
|
11
12
|
async function init(cf = { app: null }) {
|
|
12
13
|
await loadSocket();
|
|
@@ -24,6 +25,9 @@ async function init(cf = { app: null }) {
|
|
|
24
25
|
// load Service
|
|
25
26
|
loadServices();
|
|
26
27
|
|
|
28
|
+
// sync all adapter file system
|
|
29
|
+
syncAdapterFileSystem();
|
|
30
|
+
|
|
27
31
|
// load all loadEndpoints
|
|
28
32
|
await loadEndpoints();
|
|
29
33
|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Cfg } from "../../config";
|
|
2
|
+
import { FilesystemSftpAdapter } from "../media/sftp";
|
|
3
|
+
async function syncAdapterFileSystem() {
|
|
4
|
+
const mediaCollections = Cfg.collections?.filter(
|
|
5
|
+
(col) => col.type == "media" && col?.media?.enabled
|
|
6
|
+
);
|
|
7
|
+
|
|
8
|
+
mediaCollections?.map((col) => {
|
|
9
|
+
if (col?.media?.filesystemAdapter) {
|
|
10
|
+
let currentAdapter = col?.media?.filesystemAdapter;
|
|
11
|
+
// for sftp
|
|
12
|
+
if (currentAdapter?.type == "sftp") {
|
|
13
|
+
let setAdapter = col?.media?.filesystemAdapter as InstanceType<
|
|
14
|
+
typeof FilesystemSftpAdapter
|
|
15
|
+
>;
|
|
16
|
+
setAdapter.init(col);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export { syncAdapterFileSystem };
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { cleanDoubleSlashes } from "ufo";
|
|
2
|
+
import { FilesystemSftpAdapter } from "./sftp";
|
|
3
|
+
import { syncAdapterFileSystem } from "./SyncAdapter";
|
|
2
4
|
import fs from "fs";
|
|
3
5
|
import { v4 } from "uuid";
|
|
4
6
|
type driverOptions = {
|
|
@@ -71,4 +73,4 @@ class MediaDrive {
|
|
|
71
73
|
}
|
|
72
74
|
}
|
|
73
75
|
|
|
74
|
-
export { MediaDrive };
|
|
76
|
+
export { MediaDrive, FilesystemSftpAdapter, syncAdapterFileSystem };
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
type args = "--delete";
|
|
2
|
+
type config = {
|
|
3
|
+
host: string;
|
|
4
|
+
port?: number;
|
|
5
|
+
username: string;
|
|
6
|
+
password: string;
|
|
7
|
+
remoteDir: string;
|
|
8
|
+
ignorePatterns?: string[];
|
|
9
|
+
args?: args[];
|
|
10
|
+
};
|
|
11
|
+
import Client from "ssh2-sftp-client";
|
|
12
|
+
import chokidar from "chokidar";
|
|
13
|
+
import fs from "fs-extra";
|
|
14
|
+
import path from "path";
|
|
15
|
+
import { cleanDoubleSlashes } from "ufo";
|
|
16
|
+
import type { Collection } from "../../types";
|
|
17
|
+
|
|
18
|
+
class FilesystemSftpAdapter {
|
|
19
|
+
#sftp;
|
|
20
|
+
type: "sftp" = "sftp";
|
|
21
|
+
#connected: Boolean = false;
|
|
22
|
+
config;
|
|
23
|
+
constructor(config: config) {
|
|
24
|
+
this.config = config;
|
|
25
|
+
this.config.port = config?.port || 22;
|
|
26
|
+
this.#sftp = new Client();
|
|
27
|
+
this.type = "sftp";
|
|
28
|
+
return this;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async connect() {
|
|
32
|
+
await this.#sftp
|
|
33
|
+
.connect(this.config)
|
|
34
|
+
.then((e) => {
|
|
35
|
+
this.#connected = true;
|
|
36
|
+
})
|
|
37
|
+
.catch((err) => {
|
|
38
|
+
console.log(err, "error");
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async sync(
|
|
43
|
+
p: string,
|
|
44
|
+
type: "add" | "change" | "unlink" | "addDir" | "unlinkDir"
|
|
45
|
+
) {
|
|
46
|
+
try {
|
|
47
|
+
let remotePathDest =
|
|
48
|
+
this.config.remoteDir + p?.replace(process.cwd(), "");
|
|
49
|
+
let remoteDir = path.dirname(remotePathDest);
|
|
50
|
+
|
|
51
|
+
//let remoteFile = remotePathDest.replace(/\\/g, "/");
|
|
52
|
+
|
|
53
|
+
if (fs.existsSync(p)) {
|
|
54
|
+
let stats = fs.statSync(p);
|
|
55
|
+
if (stats.isFile()) {
|
|
56
|
+
await this.#sftp.mkdir(remoteDir, true).catch();
|
|
57
|
+
// Téléverser le fichier
|
|
58
|
+
let alreadyExists = await this.#sftp.exists(remotePathDest);
|
|
59
|
+
if (!alreadyExists) {
|
|
60
|
+
await this.#sftp.put(p, remotePathDest, {}).catch((err) => {
|
|
61
|
+
console.error("Fichier televerser", err?.message);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
} else {
|
|
66
|
+
// Supprimer le fichier
|
|
67
|
+
this.#sftp.delete(remotePathDest);
|
|
68
|
+
}
|
|
69
|
+
} catch (err: any) {
|
|
70
|
+
console.error(err?.message);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
watchDir(dir: string) {
|
|
75
|
+
try {
|
|
76
|
+
let local_dir = cleanDoubleSlashes(dir);
|
|
77
|
+
const watcher = chokidar.watch(path.resolve(local_dir), {
|
|
78
|
+
persistent: true,
|
|
79
|
+
ignoreInitial: false,
|
|
80
|
+
ignored: this?.config?.ignorePatterns || [],
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
watcher
|
|
84
|
+
.on("add", (path) => this.sync(path, "add"))
|
|
85
|
+
.on("change", (path) => this.sync(path, "change"))
|
|
86
|
+
.on("unlink", (path) => this.sync(path, "unlink"))
|
|
87
|
+
.on("addDir", (path) => this.sync(path, "addDir"))
|
|
88
|
+
.on("unlinkDir", (path) => this.sync(path, "unlinkDir"));
|
|
89
|
+
} catch (err: any) {
|
|
90
|
+
console.error(err?.message);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async init(col: Collection) {
|
|
95
|
+
let buildPath = "/uploads/";
|
|
96
|
+
if (!col?.media?.visibility && col?.media?.enabled) {
|
|
97
|
+
col.media.visibility = "public";
|
|
98
|
+
}
|
|
99
|
+
buildPath += col?.slug + "/" + col?.media?.visibility;
|
|
100
|
+
let watchLocalDir = path.resolve(process.cwd() + "/" + buildPath);
|
|
101
|
+
|
|
102
|
+
await this.connect().then(async (ops) => {
|
|
103
|
+
let remoteDir = this.config.remoteDir + buildPath;
|
|
104
|
+
|
|
105
|
+
let remoteDirExisis = await this.#sftp.exists(remoteDir);
|
|
106
|
+
|
|
107
|
+
//console.log("remoteDirExisis", remoteDir, remoteDirExisis);
|
|
108
|
+
|
|
109
|
+
if (!remoteDirExisis) {
|
|
110
|
+
await this.#sftp.mkdir(remoteDir, true).catch((err) => {});
|
|
111
|
+
// console.log("Watch", watchLocalDir);
|
|
112
|
+
|
|
113
|
+
setTimeout(() => {
|
|
114
|
+
this.watchDir(watchLocalDir);
|
|
115
|
+
}, 1000);
|
|
116
|
+
} else {
|
|
117
|
+
this.watchDir(watchLocalDir);
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export { FilesystemSftpAdapter };
|
package/lib/schema.ts
CHANGED
|
@@ -19,7 +19,7 @@ function buildSchema(col: Collection) {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
if (f?.type == "uuid") {
|
|
22
|
-
propertySchema[f.name] = v.string();
|
|
22
|
+
propertySchema[f.name] = v.string().uuid();
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
if (f?.type == "random") {
|
|
@@ -33,7 +33,7 @@ function buildSchema(col: Collection) {
|
|
|
33
33
|
propertySchema[f.name] = v.string().optional();
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
if (f?.type.match(/(string|richText|textarea|markdown)/)) {
|
|
36
|
+
if (f?.type.match(/(string|richText|textarea|markdown|color)/)) {
|
|
37
37
|
propertySchema[f.name] = v.string();
|
|
38
38
|
}
|
|
39
39
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dnax/core",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.7",
|
|
4
4
|
"module": "index.ts",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -8,13 +8,14 @@
|
|
|
8
8
|
},
|
|
9
9
|
"devDependencies": {
|
|
10
10
|
"@types/bun": "latest",
|
|
11
|
+
"@types/dot-object": "^2.1.6",
|
|
11
12
|
"@types/fs-extra": "^11.0.4",
|
|
13
|
+
"@types/jsonwebtoken": "9.0.6",
|
|
12
14
|
"@types/mime-types": "^2.1.4",
|
|
13
15
|
"@types/nodemailer": "^6.4.15",
|
|
14
16
|
"@types/pidusage": "^2.0.5",
|
|
15
|
-
"@types/
|
|
16
|
-
"@types/
|
|
17
|
-
"@types/jsonwebtoken": "9.0.6"
|
|
17
|
+
"@types/ssh2-sftp-client": "^9.0.4",
|
|
18
|
+
"@types/uuid": "^10.0.0"
|
|
18
19
|
},
|
|
19
20
|
"peerDependencies": {
|
|
20
21
|
"typescript": "^5.0.0"
|
|
@@ -23,7 +24,6 @@
|
|
|
23
24
|
"@clack/prompts": "^0.7.0",
|
|
24
25
|
"@colors/colors": "^1.6.0",
|
|
25
26
|
"@lukeed/ms": "^2.0.2",
|
|
26
|
-
"@orama/orama": "^2.0.23",
|
|
27
27
|
"bentocache": "^1.0.0-beta.9",
|
|
28
28
|
"boxen": "^7.1.1",
|
|
29
29
|
"chokidar": "3.6.0",
|
|
@@ -54,6 +54,7 @@
|
|
|
54
54
|
"rfc6902": "^5.1.2",
|
|
55
55
|
"sharp": "^0.33.5",
|
|
56
56
|
"signaldb": "^0.24.0",
|
|
57
|
+
"ssh2-sftp-client": "^11.0.0",
|
|
57
58
|
"ufo": "^1.5.3",
|
|
58
59
|
"urlencode": "^2.0.0",
|
|
59
60
|
"uuid": "^10.0.0"
|
package/types/index.ts
CHANGED
|
@@ -69,6 +69,7 @@ export type Field = {
|
|
|
69
69
|
| "number"
|
|
70
70
|
| "integer"
|
|
71
71
|
| "password"
|
|
72
|
+
| "color"
|
|
72
73
|
| "random"
|
|
73
74
|
| "relationship"
|
|
74
75
|
| "string"
|
|
@@ -238,6 +239,7 @@ export type Collection = {
|
|
|
238
239
|
* Mimie type to accept
|
|
239
240
|
*/
|
|
240
241
|
accept?: Array<string> | string;
|
|
242
|
+
filesystemAdapter?: any;
|
|
241
243
|
};
|
|
242
244
|
customApi?: {
|
|
243
245
|
insertOne?: (ctx: ctxApi) => object | null | undefined;
|