exodus-framework 2.0.9996 → 2.0.9998

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.
@@ -0,0 +1,25 @@
1
+ import NodeCache from 'node-cache';
2
+ import Service from '../../app/classes/service';
3
+ import MimeType from './classes/Mimetyp';
4
+ import { IMetaFile } from './contracts/meta';
5
+ declare class FileLibraryService extends Service {
6
+ protected cache: NodeCache;
7
+ protected path: string;
8
+ protected mime: MimeType;
9
+ onServiceInit(): Promise<void>;
10
+ onStart(): Promise<boolean>;
11
+ private loadLibrary;
12
+ private migratePublicPath;
13
+ getFilePath(md5: string): string;
14
+ getUrlPath(md5: string): Promise<string>;
15
+ getFileBuffer(md5: string): Promise<Buffer>;
16
+ deleteFile(md5: string): Promise<boolean>;
17
+ getFileMeta(md5: string): Promise<IMetaFile>;
18
+ saveAndRegisterFile(filePath: string): Promise<string>;
19
+ saveAndRegisterBuffer(buffer: Buffer, originalName: string, ext: string): Promise<string>;
20
+ getMD5FromFile(filePath: string): Promise<string>;
21
+ getMD5FromBuffer(buffer: Buffer): string;
22
+ isCached(md5: string): boolean;
23
+ }
24
+ export default FileLibraryService;
25
+ //# sourceMappingURL=FileLibrary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileLibrary.d.ts","sourceRoot":"","sources":["../../../src/services/file/FileLibrary.ts"],"names":[],"mappings":"AAEA,OAAO,SAAS,MAAM,YAAY,CAAC;AAEnC,OAAO,OAAO,MAAM,2BAA2B,CAAC;AAChD,OAAO,QAAQ,MAAM,mBAAmB,CAAC;AAIzC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,cAAM,kBAAmB,SAAQ,OAAO;IACtC,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC;IAC3B,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC;IAEZ,aAAa;IAQb,OAAO;YAMN,WAAW;YA2BX,iBAAiB;IAwBxB,WAAW,CAAC,GAAG,EAAE,MAAM;IAOjB,UAAU,CAAC,GAAG,EAAE,MAAM;IAO5B,aAAa,CAAC,GAAG,EAAE,MAAM;IAOnB,UAAU,CAAC,GAAG,EAAE,MAAM;IAWtB,WAAW,CAAC,GAAG,EAAE,MAAM;IAcvB,mBAAmB,CAAC,QAAQ,EAAE,MAAM;IAwCpC,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM;IA2B7E,cAAc,CAAC,QAAQ,EAAE,MAAM;IAW/B,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAMxC,QAAQ,CAAC,GAAG,EAAE,MAAM;CAG5B;AAED,eAAe,kBAAkB,CAAC"}
@@ -0,0 +1,179 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _crypto = require("crypto");
8
+ var _fsExtra = _interopRequireDefault(require("fs-extra"));
9
+ var _nodeCache = _interopRequireDefault(require("node-cache"));
10
+ var _path = _interopRequireDefault(require("path"));
11
+ var _service = _interopRequireDefault(require("../../app/classes/service"));
12
+ var _Mimetyp = _interopRequireDefault(require("./classes/Mimetyp"));
13
+ var _mimes = require("./constants/mimes");
14
+ var _core = _interopRequireDefault(require("../../app/core"));
15
+ var _FileCache = _interopRequireDefault(require("./classes/FileCache"));
16
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
17
+ class FileLibraryService extends _service.default {
18
+ cache;
19
+ path;
20
+ mime;
21
+ async onServiceInit() {
22
+ this.cache = new _nodeCache.default();
23
+ this.mime = new _Mimetyp.default(_mimes.MimeStandardTypes, _mimes.MimeOtherTypes);
24
+ this.path = _path.default.resolve(_core.default.getSettings().getHttp().publicPath + '/library');
25
+ await _fsExtra.default.ensureDir(this.path);
26
+ }
27
+ async onStart() {
28
+ await this.loadLibrary();
29
+ await this.migratePublicPath(_core.default.getSettings().getHttp().publicPath);
30
+ return true;
31
+ }
32
+ async loadLibrary() {
33
+ const files = await _fsExtra.default.readdir(this.path);
34
+ this.log(`Carregando biblioteca de arquivos. Encontrados ${files.length} arquivos`, 'info');
35
+ for (const file of files) {
36
+ const filePath = _path.default.join(this.path, file);
37
+ const fileCache = new _FileCache.default(filePath);
38
+ await fileCache.onInit();
39
+ if (!fileCache.isValid()) {
40
+ this.log(`arquivo inválido. excluindo:${filePath}`, 'warning');
41
+ await _fsExtra.default.unlink(filePath);
42
+ continue;
43
+ }
44
+ if (this.cache.has(fileCache.getMD5())) {
45
+ this.log(`arquivo duplicado. excluindo:${filePath}, `, 'warning');
46
+ await _fsExtra.default.unlink(filePath);
47
+ continue;
48
+ }
49
+ this.cache.set(fileCache.getMD5(), fileCache);
50
+ }
51
+ }
52
+ async migratePublicPath(target) {
53
+ if (target == this.path) return;
54
+ const items = await _fsExtra.default.readdir(target);
55
+ for (const item of items) {
56
+ const itemPath = _path.default.join(target, item);
57
+ const stat = await _fsExtra.default.stat(itemPath);
58
+ if (stat.isDirectory()) {
59
+ this.migratePublicPath(itemPath);
60
+ continue;
61
+ }
62
+ const md5 = await this.getMD5FromFile(itemPath);
63
+ if (md5 && !this.cache.has(md5)) {
64
+ await this.saveAndRegisterFile(itemPath);
65
+ }
66
+ await _fsExtra.default.unlink(itemPath);
67
+ }
68
+ }
69
+ getFilePath(md5) {
70
+ const cachedFile = this.cache.get(md5);
71
+ if (!cachedFile) return null;
72
+ return cachedFile.getFilePath();
73
+ }
74
+ async getUrlPath(md5) {
75
+ const cachedFile = this.cache.get(md5);
76
+ if (!cachedFile) return null;
77
+ return cachedFile.getPublicUrl();
78
+ }
79
+ getFileBuffer(md5) {
80
+ const cachedFile = this.cache.get(md5);
81
+ if (!cachedFile) return null;
82
+ return cachedFile.getBuffer();
83
+ }
84
+ async deleteFile(md5) {
85
+ const cachedFile = this.cache.get(md5);
86
+ if (!cachedFile) return false;
87
+ await _fsExtra.default.unlink(cachedFile.getFilePath());
88
+ await _fsExtra.default.unlink(cachedFile.getMetaFilePath());
89
+ this.cache.del(md5);
90
+ return true;
91
+ }
92
+ async getFileMeta(md5) {
93
+ const cachedFile = this.cache.get(md5);
94
+ if (!cachedFile) return null;
95
+ return cachedFile.getMetadata();
96
+ }
97
+
98
+ /**
99
+ * Save a file to the library and register it in the cache
100
+ *
101
+ * @param {string} filePath
102
+ * @return {string} MD5 hash of the saved file
103
+ * @memberof FileLibraryService
104
+ */
105
+ async saveAndRegisterFile(filePath) {
106
+ const md5 = await this.getMD5FromFile(filePath);
107
+ if (!md5) throw new Error('Falha ao gerar o md5 do arquivo');
108
+ if (this.isCached(md5)) return;
109
+ const ext = this.mime.getExtension(filePath);
110
+ const newFilePath = _path.default.join(this.path, `${md5}.${ext}`);
111
+ const metaFilePath = _path.default.join(this.path, `${md5}.meta`);
112
+ await _fsExtra.default.move(filePath, newFilePath, {
113
+ overwrite: true
114
+ });
115
+ const metaData = {
116
+ originalName: _path.default.basename(newFilePath),
117
+ extension: ext,
118
+ size: (await _fsExtra.default.stat(newFilePath)).size,
119
+ md5,
120
+ cachedAt: new Date().toISOString()
121
+ };
122
+ await _fsExtra.default.writeJSON(metaFilePath, metaData, {
123
+ spaces: 2
124
+ });
125
+ const cachedFile = new _FileCache.default(metaFilePath);
126
+ await cachedFile.onInit();
127
+ this.cache.set(cachedFile.getMD5(), cachedFile);
128
+ return cachedFile.getMD5();
129
+ }
130
+
131
+ /**
132
+ * Save a file buffer to the library and register it in the cache
133
+ *
134
+ * @param {Buffer} buffer
135
+ * @param {string} originalName
136
+ * @param {string} ext
137
+ * @return {string} MD5 hash of the saved file
138
+ * @memberof FileLibraryService
139
+ */
140
+ async saveAndRegisterBuffer(buffer, originalName, ext) {
141
+ const md5 = this.getMD5FromBuffer(buffer);
142
+ if (!md5) throw new Error('Falha ao gerar o md5 do arquivo');
143
+ const newFilePath = _path.default.join(this.path, `${md5}${ext}`);
144
+ const metaFilePath = _path.default.join(this.path, `${md5}.meta`);
145
+ await _fsExtra.default.outputFile(newFilePath, buffer);
146
+ const metaData = {
147
+ originalName: originalName,
148
+ extension: ext,
149
+ size: (await _fsExtra.default.stat(newFilePath)).size,
150
+ md5,
151
+ cachedAt: new Date().toISOString()
152
+ };
153
+ await _fsExtra.default.writeJSON(metaFilePath, metaData, {
154
+ spaces: 2
155
+ });
156
+ const cachedFile = new _FileCache.default(metaFilePath);
157
+ await cachedFile.onInit();
158
+ this.cache.set(cachedFile.getMD5(), cachedFile);
159
+ return cachedFile.getMD5();
160
+ }
161
+ getMD5FromFile(filePath) {
162
+ return new Promise((resolve, reject) => {
163
+ const hash = (0, _crypto.createHash)('md5');
164
+ const stream = _fsExtra.default.createReadStream(filePath);
165
+ stream.on('data', dados => hash.update(dados));
166
+ stream.on('error', error => reject(error));
167
+ stream.on('end', () => resolve(hash.digest('hex')));
168
+ });
169
+ }
170
+ getMD5FromBuffer(buffer) {
171
+ const hash = (0, _crypto.createHash)('md5');
172
+ hash.update(buffer);
173
+ return hash.digest('hex');
174
+ }
175
+ isCached(md5) {
176
+ return this.cache.has(md5);
177
+ }
178
+ }
179
+ var _default = exports.default = FileLibraryService;
@@ -0,0 +1,26 @@
1
+ import System from '../../../app/classes/system';
2
+ import { IMetaFile } from '../contracts/meta';
3
+ declare class FileCache extends System {
4
+ metaPath: string;
5
+ protected metadata: IMetaFile;
6
+ protected filePath: string;
7
+ protected valid: boolean;
8
+ constructor(metaPath: string);
9
+ onInit(): Promise<void>;
10
+ private loadFile;
11
+ private loadMetadata;
12
+ getMD5(): string;
13
+ getTitle(): string;
14
+ getExtension(): string;
15
+ getSize(): number;
16
+ getCachedAt(): string;
17
+ getFilePath(): string;
18
+ getMetaFilePath(): string;
19
+ getMetadata(): IMetaFile;
20
+ getBuffer(): Promise<Buffer>;
21
+ getCachedFileName(): string;
22
+ getPublicUrl(): string;
23
+ isValid(): boolean;
24
+ }
25
+ export default FileCache;
26
+ //# sourceMappingURL=FileCache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileCache.d.ts","sourceRoot":"","sources":["../../../../src/services/file/classes/FileCache.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,6BAA6B,CAAC;AAGjD,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAG9C,cAAM,SAAU,SAAQ,MAAM;IAKT,QAAQ,EAAE,MAAM;IAJnC,SAAS,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC9B,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC;gBAEN,QAAQ,EAAE,MAAM;IAItB,MAAM;YAIL,QAAQ;YAiBR,YAAY;IAInB,MAAM;IAIN,QAAQ;IAIR,YAAY;IAIZ,OAAO;IAIP,WAAW;IAIX,WAAW;IAIX,eAAe;IAIf,WAAW;IAIX,SAAS;IAIT,iBAAiB;IAIjB,YAAY;IAIZ,OAAO;CAGf;AAED,eAAe,SAAS,CAAC"}
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _system = _interopRequireDefault(require("../../../app/classes/system"));
8
+ var _fsExtra = _interopRequireDefault(require("fs-extra"));
9
+ var _path = _interopRequireDefault(require("path"));
10
+ var _core = _interopRequireDefault(require("../../../app/core"));
11
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
+ class FileCache extends _system.default {
13
+ metadata;
14
+ filePath;
15
+ valid;
16
+ constructor(metaPath) {
17
+ super();
18
+ this.metaPath = metaPath;
19
+ }
20
+ async onInit() {
21
+ this.valid = await this.loadFile();
22
+ }
23
+ async loadFile() {
24
+ const stat = await _fsExtra.default.stat(this.metaPath);
25
+ if (!stat.isFile()) return false;
26
+ await this.loadMetadata();
27
+ const hasFile = await _fsExtra.default.exists(this.getFilePath());
28
+ if (!hasFile) return false;
29
+ this.filePath = _path.default.resolve(_core.default.getSettings().getHttp().publicPath + '/library', this.getCachedFileName());
30
+ return true;
31
+ }
32
+ async loadMetadata() {
33
+ this.metadata = await _fsExtra.default.readJSON(this.metaPath, {
34
+ throws: false
35
+ });
36
+ }
37
+ getMD5() {
38
+ return this.metadata.md5;
39
+ }
40
+ getTitle() {
41
+ return this.metadata.originalName;
42
+ }
43
+ getExtension() {
44
+ return this.metadata.extension;
45
+ }
46
+ getSize() {
47
+ return this.metadata.size;
48
+ }
49
+ getCachedAt() {
50
+ return this.metadata.cachedAt;
51
+ }
52
+ getFilePath() {
53
+ return this.filePath;
54
+ }
55
+ getMetaFilePath() {
56
+ return this.metaPath;
57
+ }
58
+ getMetadata() {
59
+ return this.metadata;
60
+ }
61
+ getBuffer() {
62
+ return _fsExtra.default.readFile(this.filePath);
63
+ }
64
+ getCachedFileName() {
65
+ return `${this.getMD5()}.${this.getExtension()}`;
66
+ }
67
+ getPublicUrl() {
68
+ return '/public/library/' + this.getCachedFileName();
69
+ }
70
+ isValid() {
71
+ return this.valid;
72
+ }
73
+ }
74
+ var _default = exports.default = FileCache;
@@ -0,0 +1,20 @@
1
+ type TypeMap = {
2
+ [key: string]: string[];
3
+ };
4
+ declare class MimeType {
5
+ extensionToType: Map<string, string>;
6
+ typeToExtension: Map<string, string>;
7
+ typeToExtensions: Map<string, Set<string>>;
8
+ constructor(...args: TypeMap[]);
9
+ define(typeMap: TypeMap, force?: boolean): this;
10
+ getType(path: string): string;
11
+ getExtension(type: string): string;
12
+ getAllExtensions(type: string): Set<string>;
13
+ _freeze(): this;
14
+ _getTestState(): {
15
+ types: Map<string, string>;
16
+ extensions: Map<string, string>;
17
+ };
18
+ }
19
+ export default MimeType;
20
+ //# sourceMappingURL=Mimetyp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Mimetyp.d.ts","sourceRoot":"","sources":["../../../../src/services/file/classes/Mimetyp.ts"],"names":[],"mappings":"AAAA,KAAK,OAAO,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;CAAE,CAAC;AAE3C,cAAM,QAAQ;IACZ,eAAe,sBAA6B;IAC5C,eAAe,sBAA6B;IAC5C,gBAAgB,2BAAkC;gBAEtC,GAAG,IAAI,EAAE,OAAO,EAAE;IAMvB,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,UAAQ;IA8CtC,OAAO,CAAC,IAAI,EAAE,MAAM;IAqBpB,YAAY,CAAC,IAAI,EAAE,MAAM;IAYzB,gBAAgB,CAAC,IAAI,EAAE,MAAM;IAUpC,OAAO;IAgBP,aAAa;;;;CAMd;AAED,eAAe,QAAQ,CAAC"}
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ class MimeType {
8
+ extensionToType = new Map();
9
+ typeToExtension = new Map();
10
+ typeToExtensions = new Map();
11
+ constructor(...args) {
12
+ for (const arg of args) {
13
+ this.define(arg);
14
+ }
15
+ }
16
+ define(typeMap, force = false) {
17
+ for (let [type, extensions] of Object.entries(typeMap)) {
18
+ // Lowercase thingz
19
+ type = type.toLowerCase();
20
+ extensions = extensions.map(ext => ext.toLowerCase());
21
+ if (!this.typeToExtensions.has(type)) {
22
+ this.typeToExtensions.set(type, new Set());
23
+ }
24
+ const allExtensions = this.typeToExtensions.get(type);
25
+ let first = true;
26
+ for (let extension of extensions) {
27
+ const starred = extension.startsWith('*');
28
+ extension = starred ? extension.slice(1) : extension;
29
+
30
+ // Add to list of extensions for the type
31
+ allExtensions?.add(extension);
32
+ if (first) {
33
+ // Map type to default extension (first in list)
34
+ this.typeToExtension.set(type, extension);
35
+ }
36
+ first = false;
37
+
38
+ // Starred types are not eligible to be the default extension
39
+ if (starred) continue;
40
+
41
+ // Map extension to type
42
+ const currentType = this.extensionToType.get(extension);
43
+ if (currentType && currentType != type && !force) {
44
+ throw new Error(`"${type} -> ${extension}" conflicts with "${currentType} -> ${extension}". Pass \`force=true\` to override this definition.`);
45
+ }
46
+ this.extensionToType.set(extension, type);
47
+ }
48
+ }
49
+ return this;
50
+ }
51
+
52
+ /**
53
+ * Get mime type associated with an extension
54
+ */
55
+ getType(path) {
56
+ if (typeof path !== 'string') return null;
57
+
58
+ // Remove chars preceeding `/` or `\`
59
+ const last = path.replace(/^.*[/\\]/, '').toLowerCase();
60
+
61
+ // Remove chars preceeding '.'
62
+ const ext = last.replace(/^.*\./, '').toLowerCase();
63
+ const hasPath = last.length < path.length;
64
+ const hasDot = ext.length < last.length - 1;
65
+
66
+ // Extension-less file?
67
+ if (!hasDot && hasPath) return null;
68
+ return this.extensionToType.get(ext) ?? null;
69
+ }
70
+
71
+ /**
72
+ * Get default file extension associated with a mime type
73
+ */
74
+ getExtension(type) {
75
+ if (typeof type !== 'string') return null;
76
+
77
+ // Remove http header parameter(s) (specifically, charset)
78
+ type = type?.split?.(';')[0];
79
+ return (type && this.typeToExtension.get(type.trim().toLowerCase())) ?? null;
80
+ }
81
+
82
+ /**
83
+ * Get all file extensions associated with a mime type
84
+ */
85
+ getAllExtensions(type) {
86
+ if (typeof type !== 'string') return null;
87
+ return this.typeToExtensions.get(type.toLowerCase()) ?? null;
88
+ }
89
+
90
+ //
91
+ // Private API, for internal use only. These APIs may change at any time
92
+ //
93
+
94
+ _freeze() {
95
+ this.define = () => {
96
+ throw new Error('define() not allowed for built-in Mime objects. See https://github.com/broofa/mime/blob/main/README.md#custom-mime-instances');
97
+ };
98
+ Object.freeze(this);
99
+ for (const extensions of this.typeToExtensions.values()) {
100
+ Object.freeze(extensions);
101
+ }
102
+ return this;
103
+ }
104
+ _getTestState() {
105
+ return {
106
+ types: this.extensionToType,
107
+ extensions: this.typeToExtension
108
+ };
109
+ }
110
+ }
111
+ var _default = exports.default = MimeType;
@@ -0,0 +1,7 @@
1
+ export declare const MimeOtherTypes: {
2
+ [key: string]: string[];
3
+ };
4
+ export declare const MimeStandardTypes: {
5
+ [key: string]: string[];
6
+ };
7
+ //# sourceMappingURL=mimes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mimes.d.ts","sourceRoot":"","sources":["../../../../src/services/file/constants/mimes.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;CAupBrD,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;CA8VxD,CAAC"}