spice-js 2.6.38 → 2.6.40
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/build/artificial_intelligence/AI.js +296 -0
- package/build/config/ai.js +3 -0
- package/build/index.js +8 -2
- package/build/mail/providers/File.js +9 -5
- package/build/models/SpiceModel.js +147 -265
- package/build/storage/providers/Local.js +6 -12
- package/build/utility/RestHelper.js +9 -3
- package/package.json +13 -13
- package/src/artificial_intelligence/Ai.js +244 -0
- package/src/config/ai.js +3 -0
- package/src/index.js +2 -1
- package/src/mail/providers/File.js +28 -28
- package/src/models/SpiceModel.js +174 -290
- package/src/storage/providers/Local.js +69 -60
- package/src/utility/RestHelper.js +33 -29
package/src/models/SpiceModel.js
CHANGED
|
@@ -784,333 +784,190 @@ export default class SpiceModel {
|
|
|
784
784
|
JSON.stringify(this);
|
|
785
785
|
}
|
|
786
786
|
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
787
|
+
prepColumns(columns) {
|
|
788
|
+
if (columns && columns !== "") {
|
|
789
|
+
let columnList = columns.split(",");
|
|
790
|
+
return _.join(
|
|
791
|
+
_.compact(
|
|
792
|
+
columnList.map((column) => {
|
|
793
|
+
if (column === "meta().id") return undefined;
|
|
794
|
+
if (!column.startsWith("`") && !column.endsWith("`")) {
|
|
795
|
+
column = `\`${column}\``;
|
|
796
|
+
}
|
|
797
|
+
if (
|
|
798
|
+
column &&
|
|
799
|
+
!column.includes(".") &&
|
|
800
|
+
!column.startsWith(this.type)
|
|
801
|
+
) {
|
|
802
|
+
column = `\`${this.type}\`.${column}`;
|
|
803
|
+
}
|
|
804
|
+
return column;
|
|
805
|
+
})
|
|
806
|
+
),
|
|
807
|
+
","
|
|
808
|
+
);
|
|
809
|
+
}
|
|
810
|
+
return columns;
|
|
811
|
+
}
|
|
792
812
|
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
column = `\`${that.type}\`.${column}`;
|
|
807
|
-
}
|
|
808
|
-
}
|
|
809
|
-
return column;
|
|
810
|
-
})
|
|
811
|
-
),
|
|
812
|
-
","
|
|
813
|
-
);
|
|
814
|
-
}
|
|
815
|
-
return columns;
|
|
816
|
-
}
|
|
813
|
+
filterResultsByColumns(data, columns) {
|
|
814
|
+
if (columns && columns !== "") {
|
|
815
|
+
columns = columns.replace(/`/g, "").replace(/meta\(\)\.id/g, "id");
|
|
816
|
+
let columnList = columns
|
|
817
|
+
.split(",")
|
|
818
|
+
.map((column) =>
|
|
819
|
+
column.includes(".") ? _.last(column.split(".")) : column
|
|
820
|
+
);
|
|
821
|
+
columnList.push("_permissions", "_permissions_", "id");
|
|
822
|
+
return data.map((entry) => _.pick(entry, columnList));
|
|
823
|
+
}
|
|
824
|
+
return data;
|
|
825
|
+
}
|
|
817
826
|
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
}); // Convert comma-separated string to array
|
|
828
|
-
columnList.push("_permissions"); // Always include _permissions
|
|
829
|
-
columnList.push("_permissions_"); // Always include _permissions
|
|
830
|
-
columnList.push("id"); // Always include _permissions
|
|
831
|
-
return _.map(data, (entry) => _.pick(entry, columnList));
|
|
832
|
-
}
|
|
833
|
-
return data;
|
|
827
|
+
extractNestings(string, localType) {
|
|
828
|
+
let returnVal = [];
|
|
829
|
+
let regex = /(`?\w+`?)\.(`?\w+`?)/g;
|
|
830
|
+
let match;
|
|
831
|
+
|
|
832
|
+
while ((match = regex.exec(string)) !== null) {
|
|
833
|
+
let first = match[1].replace(/`/g, "");
|
|
834
|
+
if (first !== localType) {
|
|
835
|
+
returnVal.push(first);
|
|
834
836
|
}
|
|
837
|
+
}
|
|
835
838
|
|
|
836
|
-
|
|
837
|
-
|
|
839
|
+
let queryRegex = /(ANY|EVERY)\s+\w+\s+IN\s+`?(\w+)`?/g;
|
|
840
|
+
let queryMatch;
|
|
838
841
|
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
+
while ((queryMatch = queryRegex.exec(string)) !== null) {
|
|
843
|
+
returnVal.push(queryMatch[2]);
|
|
844
|
+
}
|
|
842
845
|
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
let second = match[2].replace(/`/g, "");
|
|
846
|
-
if (first !== localType) {
|
|
847
|
-
returnVal.push(first);
|
|
848
|
-
}
|
|
849
|
-
}
|
|
850
|
-
// Regex for ANY/EVERY clauses
|
|
851
|
-
let queryRegex = /(ANY|EVERY)\s+\w+\s+IN\s+`?(\w+)`?/g;
|
|
852
|
-
let queryMatch;
|
|
846
|
+
return [...new Set(returnVal)];
|
|
847
|
+
}
|
|
853
848
|
|
|
854
|
-
|
|
855
|
-
|
|
849
|
+
createJoinSection(nestings) {
|
|
850
|
+
return nestings
|
|
851
|
+
.map((nesting) => {
|
|
852
|
+
if (
|
|
853
|
+
nesting.type === DataType.ARRAY ||
|
|
854
|
+
nesting.type === Array ||
|
|
855
|
+
nesting.type === "array"
|
|
856
|
+
) {
|
|
857
|
+
return `LEFT NEST \`${fixCollection(nesting.reference)}\` AS \`${nesting.alias}\` ON KEYS \`${this.type}\`.\`${nesting.alias}\``;
|
|
858
|
+
} else {
|
|
859
|
+
return `LEFT JOIN \`${fixCollection(nesting.reference)}\` AS \`${nesting.alias}\` ON KEYS \`${this.type}\`.\`${nesting.alias}\``;
|
|
856
860
|
}
|
|
861
|
+
})
|
|
862
|
+
.join(" ");
|
|
863
|
+
}
|
|
857
864
|
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
let regex = /(\w+)\.(\w+)/g;
|
|
864
|
-
let match;
|
|
865
|
-
|
|
866
|
-
while ((match = regex.exec(string)) !== null) {
|
|
867
|
-
if (match[1] !== localType) {
|
|
868
|
-
returnVal.push(match[1]);
|
|
869
|
-
} else {
|
|
870
|
-
returnVal.push(match[2]);
|
|
871
|
-
}
|
|
872
|
-
}
|
|
865
|
+
formatSortComponent(sortComponent) {
|
|
866
|
+
const parts = sortComponent.split(" ");
|
|
867
|
+
parts[0] = `\`${parts[0]}\``;
|
|
868
|
+
return parts.join(" ");
|
|
869
|
+
}
|
|
873
870
|
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
let returnVal = [];
|
|
878
|
-
let regex = /(\w+)\./g;
|
|
879
|
-
let match = regex.exec(string);
|
|
880
|
-
console.log("Local:", localType, match);
|
|
881
|
-
while (match) {
|
|
882
|
-
if (match[1] != localType) returnVal.push(match[1]);
|
|
883
|
-
}
|
|
884
|
-
return returnVal;
|
|
885
|
-
} */
|
|
871
|
+
removeSpaceAndSpecialCharacters(str) {
|
|
872
|
+
return str.replace(/[^a-zA-Z0-9]/g, "");
|
|
873
|
+
}
|
|
886
874
|
|
|
887
|
-
|
|
875
|
+
async list(args = {}) {
|
|
876
|
+
try {
|
|
877
|
+
args.columns = this.prepColumns(args.columns);
|
|
888
878
|
|
|
889
|
-
|
|
890
|
-
...extractNestings(args?.query, this.type),
|
|
891
|
-
...extractNestings(args?.columns, this.type),
|
|
892
|
-
...extractNestings(args?.sort, this.type),
|
|
879
|
+
const nestings = [
|
|
880
|
+
...this.extractNestings(args?.query, this.type),
|
|
881
|
+
...this.extractNestings(args?.columns, this.type),
|
|
882
|
+
...this.extractNestings(args?.sort, this.type),
|
|
893
883
|
];
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
};
|
|
906
|
-
}
|
|
907
|
-
}
|
|
884
|
+
|
|
885
|
+
const mappedNestings = _.compact(
|
|
886
|
+
_.uniq(nestings).map((nesting) => {
|
|
887
|
+
const prop = this.props[nesting];
|
|
888
|
+
if (prop?.map?.type === MapType.MODEL) {
|
|
889
|
+
return {
|
|
890
|
+
alias: nesting,
|
|
891
|
+
reference: prop.map.reference.toLowerCase(),
|
|
892
|
+
type: prop.type,
|
|
893
|
+
value_field: prop.map.value_field,
|
|
894
|
+
};
|
|
908
895
|
}
|
|
909
896
|
})
|
|
910
897
|
);
|
|
911
898
|
|
|
912
|
-
|
|
913
|
-
//create join section with nestings
|
|
914
|
-
let joinSection = "";
|
|
915
|
-
_.each(nestings, (nesting) => {
|
|
916
|
-
if (
|
|
917
|
-
nesting.type == DataType.ARRAY ||
|
|
918
|
-
nesting.type == Array ||
|
|
919
|
-
nesting.type == "array"
|
|
920
|
-
) {
|
|
921
|
-
joinSection += `LEFT NEST \`${fixCollection(nesting.reference)}\` AS \`${nesting.alias}\` ON KEYS \`${that.type}\`.\`${nesting.alias}\` `;
|
|
922
|
-
} else {
|
|
923
|
-
joinSection += `LEFT JOIN \`${fixCollection(nesting.reference)}\` AS \`${nesting.alias}\` ON KEYS \`${that.type}\`.\`${nesting.alias}\` `;
|
|
924
|
-
}
|
|
925
|
-
});
|
|
926
|
-
return joinSection;
|
|
927
|
-
}
|
|
928
|
-
let _join = createJoinSection(mappedNestings);
|
|
929
|
-
//console.log("Props", that.type, nestings, _join, args?.query);
|
|
930
|
-
|
|
931
|
-
args._join = _join;
|
|
899
|
+
args._join = this.createJoinSection(mappedNestings);
|
|
932
900
|
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
(args.is_custom_query && args.is_custom_query === "true")
|
|
936
|
-
) {
|
|
901
|
+
let query = "";
|
|
902
|
+
if (args.is_full_text === "true" || args.is_custom_query === "true") {
|
|
937
903
|
query = args.query;
|
|
938
904
|
} else {
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
args.query +
|
|
945
|
-
` AND (\`${this.type}\`.deleted = false OR \`${this.type}\`.deleted IS MISSING) `;
|
|
946
|
-
} else {
|
|
947
|
-
query = `(\`${this.type}\`.deleted = false OR \`${this.type}\`.deleted IS MISSING) `;
|
|
948
|
-
}
|
|
949
|
-
}
|
|
950
|
-
}
|
|
951
|
-
|
|
952
|
-
function formatSortComponent(sortComponent) {
|
|
953
|
-
// Split the string by spaces to get individual parts
|
|
954
|
-
const parts = sortComponent.split(" ");
|
|
955
|
-
// Assuming the first part is the column name, add backticks around it
|
|
956
|
-
parts[0] = `\`${parts[0]}\``;
|
|
957
|
-
// Rejoin the parts back into a string and return
|
|
958
|
-
return parts.join(" ");
|
|
905
|
+
query = args.filters
|
|
906
|
+
? this.makeQueryFromFilter(args.filters)
|
|
907
|
+
: args.query
|
|
908
|
+
? `${args.query} AND (\`${this.type}\`.deleted = false OR \`${this.type}\`.deleted IS MISSING)`
|
|
909
|
+
: `(\`${this.type}\`.deleted = false OR \`${this.type}\`.deleted IS MISSING)`;
|
|
959
910
|
}
|
|
960
911
|
|
|
961
912
|
if (hasSQLInjection(query)) {
|
|
962
913
|
return [];
|
|
963
914
|
}
|
|
964
|
-
if (args.limit) {
|
|
965
|
-
args.limit = Number(args.limit);
|
|
966
|
-
}
|
|
967
|
-
if (args.offset) {
|
|
968
|
-
args.offset = Number(args.offset);
|
|
969
|
-
}
|
|
970
915
|
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
)
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
}
|
|
986
|
-
args.sort = _.join(new_sort_array, ",");
|
|
987
|
-
}
|
|
988
|
-
if (args.skip_hooks != true) {
|
|
916
|
+
args.limit = Number(args.limit) || undefined;
|
|
917
|
+
args.offset = Number(args.offset) || 0;
|
|
918
|
+
args.sort = args.sort
|
|
919
|
+
? args.sort
|
|
920
|
+
.split(",")
|
|
921
|
+
.map((item) =>
|
|
922
|
+
item.includes(".")
|
|
923
|
+
? item
|
|
924
|
+
: `\`${this.type}\`.${this.formatSortComponent(item)}`
|
|
925
|
+
)
|
|
926
|
+
.join(",")
|
|
927
|
+
: `\`${this.type}\`.created_at DESC`;
|
|
928
|
+
|
|
929
|
+
if (args.skip_hooks !== true) {
|
|
989
930
|
await this.run_hook(this, "list", "before");
|
|
990
931
|
}
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
}
|
|
994
|
-
let key = removeSpaceAndSpecialCharacters(
|
|
932
|
+
|
|
933
|
+
const cacheKey = this.removeSpaceAndSpecialCharacters(
|
|
995
934
|
`list::${this.type}::${args._join}::${query}::${args.limit}::${args.offset}::${args.sort}::${args.do_count}::${args.statement_consistent}::${args.columns}::${args.is_full_text}::${args.is_custom_query}`
|
|
996
935
|
);
|
|
997
936
|
|
|
998
937
|
let results;
|
|
999
|
-
if (
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
)
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
key,
|
|
1013
|
-
{ value: results, time: new Date().getTime() },
|
|
1014
|
-
this.getCacheConfig(this.type)
|
|
1015
|
-
);
|
|
1016
|
-
}
|
|
1017
|
-
} else {
|
|
1018
|
-
results = await this.database.query(query);
|
|
1019
|
-
}
|
|
938
|
+
if (this.shouldUseCache(this.type)) {
|
|
939
|
+
const cachedResults = await this.getCacheProviderObject(this.type).get(
|
|
940
|
+
cacheKey
|
|
941
|
+
);
|
|
942
|
+
results = cachedResults?.value;
|
|
943
|
+
|
|
944
|
+
if (!results || (await this.shouldForceRefresh(cachedResults))) {
|
|
945
|
+
results = await this.fetchResults(args, query);
|
|
946
|
+
await this.getCacheProviderObject(this.type).set(
|
|
947
|
+
cacheKey,
|
|
948
|
+
{ value: results, time: new Date().getTime() },
|
|
949
|
+
this.getCacheConfig(this.type)
|
|
950
|
+
);
|
|
1020
951
|
}
|
|
1021
952
|
} else {
|
|
1022
|
-
|
|
1023
|
-
if (this.shouldUseCache(this.type)) {
|
|
1024
|
-
let cached_results = await this.getCacheProviderObject(
|
|
1025
|
-
this.type
|
|
1026
|
-
).get(key);
|
|
1027
|
-
results = cached_results?.value;
|
|
1028
|
-
if (
|
|
1029
|
-
cached_results?.value == undefined ||
|
|
1030
|
-
(await this.shouldForceRefresh(cached_results))
|
|
1031
|
-
) {
|
|
1032
|
-
results = await this.database.full_text_search(
|
|
1033
|
-
this.type,
|
|
1034
|
-
query || "",
|
|
1035
|
-
args.limit,
|
|
1036
|
-
args.offset,
|
|
1037
|
-
args._join
|
|
1038
|
-
);
|
|
1039
|
-
this.getCacheProviderObject(this.type).set(
|
|
1040
|
-
key,
|
|
1041
|
-
{ value: results, time: new Date().getTime() },
|
|
1042
|
-
this.getCacheConfig(this.type)
|
|
1043
|
-
);
|
|
1044
|
-
}
|
|
1045
|
-
} else {
|
|
1046
|
-
results = await this.database.full_text_search(
|
|
1047
|
-
this.type,
|
|
1048
|
-
query || "",
|
|
1049
|
-
args.limit,
|
|
1050
|
-
args.offset,
|
|
1051
|
-
args._join
|
|
1052
|
-
);
|
|
1053
|
-
}
|
|
1054
|
-
} else {
|
|
1055
|
-
if (this.shouldUseCache(this.type)) {
|
|
1056
|
-
let cached_results = await this.getCacheProviderObject(
|
|
1057
|
-
this.type
|
|
1058
|
-
).get(key);
|
|
1059
|
-
results = cached_results?.value;
|
|
1060
|
-
let shouleForceRefresh =
|
|
1061
|
-
await this.shouldForceRefresh(cached_results);
|
|
1062
|
-
if (cached_results?.value == undefined || shouleForceRefresh) {
|
|
1063
|
-
results = await this.database.search(
|
|
1064
|
-
this.type,
|
|
1065
|
-
args.columns || "",
|
|
1066
|
-
query || "",
|
|
1067
|
-
args.limit,
|
|
1068
|
-
args.offset,
|
|
1069
|
-
args.sort,
|
|
1070
|
-
args.do_count,
|
|
1071
|
-
args.statement_consistent,
|
|
1072
|
-
args._join
|
|
1073
|
-
);
|
|
1074
|
-
this.getCacheProviderObject(this.type).set(
|
|
1075
|
-
key,
|
|
1076
|
-
{ value: results, time: new Date().getTime() },
|
|
1077
|
-
this.getCacheConfig(this.type)
|
|
1078
|
-
);
|
|
1079
|
-
}
|
|
1080
|
-
} else {
|
|
1081
|
-
results = await this.database.search(
|
|
1082
|
-
this.type,
|
|
1083
|
-
args.columns || "",
|
|
1084
|
-
query || "",
|
|
1085
|
-
args.limit,
|
|
1086
|
-
args.offset,
|
|
1087
|
-
args.sort,
|
|
1088
|
-
args.do_count,
|
|
1089
|
-
args.statement_consistent,
|
|
1090
|
-
args._join
|
|
1091
|
-
);
|
|
1092
|
-
}
|
|
1093
|
-
}
|
|
953
|
+
results = await this.fetchResults(args, query);
|
|
1094
954
|
}
|
|
1095
|
-
try {
|
|
1096
|
-
if (args.skip_read_serialize != true && args.skip_serialize != true) {
|
|
1097
|
-
results.data = await this.do_serialize(
|
|
1098
|
-
results.data,
|
|
1099
|
-
"read",
|
|
1100
|
-
{},
|
|
1101
|
-
args,
|
|
1102
|
-
await this.propsToBeRemoved(results.data)
|
|
1103
|
-
);
|
|
1104
|
-
}
|
|
1105
|
-
if (this.type == "resourcedetail");
|
|
1106
955
|
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
956
|
+
if (args.skip_read_serialize !== true && args.skip_serialize !== true) {
|
|
957
|
+
results.data = await this.do_serialize(
|
|
958
|
+
results.data,
|
|
959
|
+
"read",
|
|
960
|
+
{},
|
|
961
|
+
args,
|
|
962
|
+
await this.propsToBeRemoved(results.data)
|
|
963
|
+
);
|
|
1112
964
|
}
|
|
1113
|
-
|
|
965
|
+
|
|
966
|
+
if (args.skip_hooks !== true) {
|
|
967
|
+
await this.run_hook(results.data, "list", "after");
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
results.data = this.filterResultsByColumns(results.data, args.columns);
|
|
1114
971
|
return results;
|
|
1115
972
|
} catch (e) {
|
|
1116
973
|
console.log(e.stack);
|
|
@@ -1118,6 +975,33 @@ export default class SpiceModel {
|
|
|
1118
975
|
}
|
|
1119
976
|
}
|
|
1120
977
|
|
|
978
|
+
async fetchResults(args, query) {
|
|
979
|
+
if (args.is_custom_query === "true" && args.ids.length > 0) {
|
|
980
|
+
return await this.database.query(query);
|
|
981
|
+
} else if (args.is_full_text === "true") {
|
|
982
|
+
return await this.database.full_text_search(
|
|
983
|
+
this.type,
|
|
984
|
+
query || "",
|
|
985
|
+
args.limit,
|
|
986
|
+
args.offset,
|
|
987
|
+
args._join
|
|
988
|
+
);
|
|
989
|
+
} else {
|
|
990
|
+
let result = await this.database.search(
|
|
991
|
+
this.type,
|
|
992
|
+
args.columns || "",
|
|
993
|
+
query || "",
|
|
994
|
+
args.limit,
|
|
995
|
+
args.offset,
|
|
996
|
+
args.sort,
|
|
997
|
+
args.do_count,
|
|
998
|
+
args.statement_consistent,
|
|
999
|
+
args._join
|
|
1000
|
+
);
|
|
1001
|
+
return result;
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1121
1005
|
addHook({ operation, when, execute }) {
|
|
1122
1006
|
this[_hooks][operation][when].push(execute);
|
|
1123
1007
|
}
|
|
@@ -1,69 +1,78 @@
|
|
|
1
|
-
let fs = require(
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
let uuid = require('uuid');
|
|
5
|
-
import _ from 'lodash';
|
|
1
|
+
let fs = require("fs-extra");
|
|
2
|
+
let uuid = require("uuid");
|
|
3
|
+
import _ from "lodash";
|
|
6
4
|
|
|
7
|
-
export default class Local{
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
5
|
+
export default class Local {
|
|
6
|
+
constructor(args = {}) {
|
|
7
|
+
this.args = args;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
async save({ files, path }) {
|
|
11
|
+
if (
|
|
12
|
+
_.has(files, "path") &&
|
|
13
|
+
_.has(files, "size") &&
|
|
14
|
+
_.has(files, "_writeStream")
|
|
15
|
+
) {
|
|
16
|
+
files = { files };
|
|
12
17
|
}
|
|
13
18
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
19
|
+
files = _.reduce(
|
|
20
|
+
_.map(_.values(files), (file) => {
|
|
21
|
+
if (!_.isArray(file)) {
|
|
22
|
+
return Array.of(file);
|
|
17
23
|
}
|
|
24
|
+
return file;
|
|
25
|
+
}),
|
|
26
|
+
(accu, item) => {
|
|
27
|
+
return [...accu, ...item];
|
|
28
|
+
},
|
|
29
|
+
[]
|
|
30
|
+
);
|
|
18
31
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
accu = _.join([accu, item], '/');
|
|
38
|
-
}
|
|
39
|
-
makeDirectory(accu);
|
|
40
|
-
return accu
|
|
41
|
-
}, pathArray[0])
|
|
32
|
+
function makeDirectory(dir) {
|
|
33
|
+
if (!fs.existsSync(dir)) {
|
|
34
|
+
fs.mkdirSync(dir);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// Create folders
|
|
38
|
+
let pathArray = path.split("/");
|
|
39
|
+
_.reduce(
|
|
40
|
+
pathArray,
|
|
41
|
+
(accu, item) => {
|
|
42
|
+
if (item != accu) {
|
|
43
|
+
accu = _.join([accu, item], "/");
|
|
44
|
+
}
|
|
45
|
+
makeDirectory(accu);
|
|
46
|
+
return accu;
|
|
47
|
+
},
|
|
48
|
+
pathArray[0]
|
|
49
|
+
);
|
|
42
50
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
51
|
+
// Create read stream
|
|
52
|
+
const readStreams = _.map(files, (file) => {
|
|
53
|
+
return { file, readStream: fs.createReadStream(file.path) };
|
|
54
|
+
});
|
|
55
|
+
// Create Write Stream
|
|
56
|
+
let paths = _.map(readStreams, (item) => {
|
|
57
|
+
let extension = _.last(item.file.name.split("."));
|
|
58
|
+
let file_name = _.last(uuid.v4().split("-"));
|
|
59
|
+
let writeStream = fs.createWriteStream(
|
|
60
|
+
`${path}/${file_name}.${extension}`
|
|
61
|
+
);
|
|
62
|
+
item.readStream.pipe(writeStream);
|
|
63
|
+
item.readStream.on("end", function (err) {
|
|
64
|
+
fs.unlink(item.file.path, function (obj) {});
|
|
65
|
+
});
|
|
66
|
+
return `${path}/${file_name}.${extension}`;
|
|
67
|
+
});
|
|
59
68
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
return paths;
|
|
69
|
+
if (paths.length == 1) {
|
|
70
|
+
return _.first(paths);
|
|
64
71
|
}
|
|
72
|
+
return paths;
|
|
73
|
+
}
|
|
65
74
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
75
|
+
async delete({ path }) {
|
|
76
|
+
console.log("Sending", this.args, path);
|
|
77
|
+
}
|
|
78
|
+
}
|