@carbonorm/carbonnode 1.6.33 → 1.6.35
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/dist/index.cjs.js +49 -20
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +49 -20
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/api/restRequest.ts +197 -144
package/src/api/restRequest.ts
CHANGED
|
@@ -781,246 +781,299 @@ export default function restApi<
|
|
|
781
781
|
// https://rapidapi.com/guides/axios-async-await
|
|
782
782
|
return axiosActiveRequest.then(async (response): Promise<AxiosResponse<ResponseDataType, any>> => {
|
|
783
783
|
|
|
784
|
-
|
|
784
|
+
if (typeof response.data === 'string') {
|
|
785
785
|
|
|
786
|
-
|
|
786
|
+
if (isTest) {
|
|
787
787
|
|
|
788
|
-
|
|
788
|
+
console.trace()
|
|
789
789
|
|
|
790
|
-
|
|
790
|
+
throw new Error('The response data was a string this typically indicated html was sent. Make sure all cookies (' + JSON.stringify(response.config.headers) + ') needed are present! (' + response.data + ')')
|
|
791
|
+
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
return Promise.reject(response);
|
|
791
795
|
|
|
792
796
|
}
|
|
793
797
|
|
|
794
|
-
|
|
798
|
+
if (cachingConfirmed) {
|
|
795
799
|
|
|
796
|
-
|
|
800
|
+
const cacheIndex = apiRequestCache.findIndex(cache => cache.requestArgumentsSerialized === querySerialized);
|
|
797
801
|
|
|
798
|
-
|
|
802
|
+
apiRequestCache[cacheIndex].final = false === returnGetNextPageFunction
|
|
799
803
|
|
|
800
|
-
|
|
804
|
+
// only cache get method requests
|
|
805
|
+
apiRequestCache[cacheIndex].response = response
|
|
801
806
|
|
|
802
|
-
|
|
807
|
+
}
|
|
803
808
|
|
|
804
|
-
|
|
805
|
-
apiRequestCache[cacheIndex].response = response
|
|
809
|
+
apiResponse = TestRestfulResponse(response, request?.success, request?.error ?? "An unexpected API error occurred!")
|
|
806
810
|
|
|
807
|
-
|
|
811
|
+
if (false === apiResponse) {
|
|
808
812
|
|
|
809
|
-
|
|
813
|
+
if (request.debug && isLocal) {
|
|
810
814
|
|
|
811
|
-
|
|
815
|
+
toast.warning("DEVS: TestRestfulResponse returned false for (" + operatingTable + ").", toastOptionsDevs);
|
|
812
816
|
|
|
813
|
-
|
|
817
|
+
}
|
|
814
818
|
|
|
815
|
-
|
|
819
|
+
return response;
|
|
816
820
|
|
|
817
821
|
}
|
|
818
822
|
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
}
|
|
823
|
+
// stateful operations are done in the response callback - its leverages rest generated functions
|
|
824
|
+
responseCallback(response, request, apiResponse)
|
|
822
825
|
|
|
823
|
-
|
|
824
|
-
responseCallback(response, request, apiResponse)
|
|
826
|
+
if (C6.GET === requestMethod) {
|
|
825
827
|
|
|
826
|
-
|
|
828
|
+
const responseData = response.data as iGetC6RestResponse<any>;
|
|
827
829
|
|
|
828
|
-
|
|
830
|
+
returnGetNextPageFunction = 1 !== query?.[C6.PAGINATION]?.[C6.LIMIT] &&
|
|
831
|
+
query?.[C6.PAGINATION]?.[C6.LIMIT] === responseData.rest.length
|
|
829
832
|
|
|
830
|
-
|
|
831
|
-
query?.[C6.PAGINATION]?.[C6.LIMIT] === responseData.rest.length
|
|
833
|
+
if (false === isTest || true === isVerbose) {
|
|
832
834
|
|
|
833
|
-
|
|
835
|
+
console.groupCollapsed('%c API: Response (' + requestMethod + ' ' + tableName + ') returned length (' + responseData.rest?.length + ') of possible (' + query?.[C6.PAGINATION]?.[C6.LIMIT] + ') limit!', 'color: #0c0')
|
|
834
836
|
|
|
835
|
-
|
|
837
|
+
console.log('%c ' + requestMethod + ' ' + tableName, 'color: #0c0')
|
|
836
838
|
|
|
837
|
-
|
|
839
|
+
console.log('%c Request Data (note you may see the success and/or error prompt):', 'color: #0c0', request)
|
|
838
840
|
|
|
839
|
-
|
|
841
|
+
console.log('%c Response Data:', 'color: #0c0', responseData.rest)
|
|
840
842
|
|
|
841
|
-
|
|
843
|
+
console.log('%c Will return get next page function:' + (1 !== query?.[C6.PAGINATION]?.[C6.LIMIT] ? '' : ' (Will not return with explicit limit 1 set)'), 'color: #0c0', true === returnGetNextPageFunction)
|
|
842
844
|
|
|
843
|
-
|
|
845
|
+
console.trace();
|
|
844
846
|
|
|
845
|
-
|
|
847
|
+
console.groupEnd()
|
|
846
848
|
|
|
847
|
-
|
|
849
|
+
}
|
|
848
850
|
|
|
849
|
-
|
|
851
|
+
if (false === returnGetNextPageFunction
|
|
852
|
+
&& true === request.debug
|
|
853
|
+
&& isLocal) {
|
|
850
854
|
|
|
851
|
-
|
|
852
|
-
&& true === request.debug
|
|
853
|
-
&& isLocal) {
|
|
855
|
+
toast.success("DEVS: Response returned length (" + responseData.rest?.length + ") less than limit (" + query?.[C6.PAGINATION]?.[C6.LIMIT] + ").", toastOptionsDevs);
|
|
854
856
|
|
|
855
|
-
|
|
857
|
+
}
|
|
856
858
|
|
|
857
|
-
|
|
859
|
+
request.fetchDependencies ??= eFetchDependencies.NONE;
|
|
860
|
+
|
|
861
|
+
if (request.fetchDependencies
|
|
862
|
+
&& 'number' === typeof request.fetchDependencies
|
|
863
|
+
&& responseData.rest.length > 0) {
|
|
864
|
+
|
|
865
|
+
const fetchDependencies = request.fetchDependencies as number;
|
|
866
|
+
|
|
867
|
+
console.groupCollapsed('%c API: Fetch Dependencies segment (' + requestMethod + ' ' + tableName + ')'
|
|
868
|
+
+ (fetchDependencies & eFetchDependencies.CHILDREN ? ' | (CHILDREN|REFERENCED) ' : '')
|
|
869
|
+
+ (fetchDependencies & eFetchDependencies.PARENTS ? ' | (PARENTS|REFRENCED_BY)' : '')
|
|
870
|
+
+ (fetchDependencies & eFetchDependencies.C6ENTITY ? ' | (C6ENTITY)' : '')
|
|
871
|
+
+ (fetchDependencies & eFetchDependencies.RECURSIVE ? ' | (RECURSIVE)' : ''), 'color: #33ccff')
|
|
872
|
+
|
|
873
|
+
console.groupCollapsed('Collapsed JS Trace');
|
|
874
|
+
console.trace(); // hidden in collapsed group
|
|
875
|
+
console.groupEnd();
|
|
876
|
+
|
|
877
|
+
// noinspection JSBitwiseOperatorUsage
|
|
878
|
+
let dependencies: {
|
|
879
|
+
[key: string]: iConstraint[]
|
|
880
|
+
} = {};
|
|
881
|
+
|
|
882
|
+
if (fetchDependencies & eFetchDependencies.C6ENTITY) {
|
|
883
|
+
|
|
884
|
+
|
|
885
|
+
dependencies = operatingTable.endsWith("carbon_carbons")
|
|
886
|
+
? {
|
|
887
|
+
// the context of the entity system is a bit different
|
|
888
|
+
...fetchDependencies & eFetchDependencies.CHILDREN // REFERENCED === CHILDREN
|
|
889
|
+
? C6.TABLES[operatingTable].TABLE_REFERENCED_BY
|
|
890
|
+
: {},
|
|
891
|
+
...fetchDependencies & eFetchDependencies.PARENTS // REFERENCES === PARENTS
|
|
892
|
+
? C6.TABLES[operatingTable].TABLE_REFERENCES
|
|
893
|
+
: {}
|
|
894
|
+
} : {
|
|
895
|
+
// the context of the entity system is a bit different
|
|
896
|
+
...fetchDependencies & eFetchDependencies.CHILDREN // REFERENCED === CHILDREN
|
|
897
|
+
? {
|
|
898
|
+
...Object.keys(C6.TABLES[operatingTable].TABLE_REFERENCES).reduce((accumulator, columnName) => {
|
|
899
|
+
|
|
900
|
+
if (!C6.TABLES[operatingTable].PRIMARY_SHORT.includes(columnName)) {
|
|
901
|
+
accumulator[columnName] = C6.TABLES[operatingTable].TABLE_REFERENCES[columnName]
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
return accumulator
|
|
905
|
+
}, {}),
|
|
906
|
+
...C6.TABLES[operatingTable].TABLE_REFERENCED_BY // it is unlikely that a C6 table will have any TABLE_REFERENCED_BY
|
|
907
|
+
}
|
|
908
|
+
: {},
|
|
909
|
+
...fetchDependencies & eFetchDependencies.PARENTS // REFERENCES === PARENTS
|
|
910
|
+
? C6.TABLES[operatingTable].PRIMARY_SHORT.reduce((accumulator, primaryKey) => {
|
|
911
|
+
accumulator[primaryKey] = C6.TABLES[operatingTable].TABLE_REFERENCES[primaryKey]
|
|
912
|
+
return accumulator
|
|
913
|
+
}, {})
|
|
914
|
+
: {}
|
|
915
|
+
}
|
|
858
916
|
|
|
859
|
-
|
|
917
|
+
} else {
|
|
860
918
|
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
919
|
+
// this is the natural mysql context
|
|
920
|
+
dependencies = {
|
|
921
|
+
...fetchDependencies & eFetchDependencies.REFERENCED // REFERENCED === CHILDREN
|
|
922
|
+
? C6.TABLES[operatingTable].TABLE_REFERENCED_BY
|
|
923
|
+
: {},
|
|
924
|
+
...fetchDependencies & eFetchDependencies.REFERENCES // REFERENCES === PARENTS
|
|
925
|
+
? C6.TABLES[operatingTable].TABLE_REFERENCES
|
|
926
|
+
: {}
|
|
927
|
+
};
|
|
864
928
|
|
|
865
|
-
|
|
929
|
+
}
|
|
866
930
|
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
931
|
+
let fetchReferences: {
|
|
932
|
+
[externalTable: string]: {
|
|
933
|
+
[column: string]: string[]
|
|
934
|
+
}
|
|
935
|
+
} = {}
|
|
872
936
|
|
|
873
|
-
|
|
874
|
-
console.trace(); // hidden in collapsed group
|
|
875
|
-
console.groupEnd();
|
|
937
|
+
let apiRequestPromises: Array<Awaited<apiReturn<iGetC6RestResponse<any>>>> = []
|
|
876
938
|
|
|
877
|
-
|
|
878
|
-
let dependencies: { [key: string]: iConstraint[] } = {
|
|
879
|
-
...fetchDependencies & eFetchDependencies.REFERENCED ? C6.TABLES[operatingTable].TABLE_REFERENCED_BY : {},
|
|
880
|
-
...fetchDependencies & eFetchDependencies.REFERENCES ? C6.TABLES[operatingTable].TABLE_REFERENCES : {}
|
|
881
|
-
};
|
|
939
|
+
console.log('%c Dependencies', 'color: #005555', dependencies)
|
|
882
940
|
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
941
|
+
Object.keys(
|
|
942
|
+
dependencies
|
|
943
|
+
).forEach(column => dependencies[column].forEach((constraint) => {
|
|
944
|
+
fetchReferences[constraint.TABLE] ??= {};
|
|
945
|
+
fetchReferences[constraint.TABLE][constraint.COLUMN] ??= []
|
|
946
|
+
// carbon_users -> user_id | user_photo -> carbon_carbons -> entity_id
|
|
947
|
+
fetchReferences[constraint.TABLE][constraint.COLUMN].push(responseData.rest[column] ?? responseData.rest.map((row) => row[column]).filter(n => n)) // todo - we are mapping all carbons received to every fk reference despite its tag name
|
|
948
|
+
console.log('fetchReferences[constraint.TABLE][constraint.COLUMN]', constraint.TABLE, constraint.COLUMN, fetchReferences[constraint.TABLE][constraint.COLUMN], responseData.rest)
|
|
949
|
+
}));
|
|
888
950
|
|
|
889
|
-
|
|
951
|
+
console.log('fetchReferences', fetchReferences)
|
|
890
952
|
|
|
891
|
-
|
|
892
|
-
Object.keys(
|
|
893
|
-
dependencies
|
|
894
|
-
).forEach(column => dependencies[column].forEach((constraint) => {
|
|
895
|
-
fetchReferences[constraint.TABLE] ??= {};
|
|
896
|
-
fetchReferences[constraint.TABLE][constraint.COLUMN] ??= []
|
|
897
|
-
// carbon_users -> user_id | user_photo -> carbon_carbons -> entity_id
|
|
898
|
-
fetchReferences[constraint.TABLE][constraint.COLUMN].push(responseData.rest[column] ?? responseData.rest.map((row) => row[column]).filter(n => n)) // todo - we are mapping all carbons received to every fk reference despite its tag name
|
|
899
|
-
console.log('fetchReferences[constraint.TABLE][constraint.COLUMN]', constraint.TABLE, constraint.COLUMN, fetchReferences[constraint.TABLE][constraint.COLUMN], responseData.rest)
|
|
900
|
-
}));
|
|
953
|
+
for (const tableToFetch in fetchReferences) {
|
|
901
954
|
|
|
902
|
-
|
|
955
|
+
if (fetchDependencies & eFetchDependencies.C6ENTITY
|
|
956
|
+
&& 'string' === typeof tableName
|
|
957
|
+
&& tableName.endsWith("carbon_carbons")) {
|
|
903
958
|
|
|
904
|
-
|
|
959
|
+
// this more or less implies
|
|
960
|
+
// todo - rethink the table ref entity system - when tables are renamed? no hooks exist in mysql
|
|
961
|
+
// since were already filtering on column, we can assume the first row constraint is the same as the rest
|
|
905
962
|
|
|
906
|
-
|
|
907
|
-
|
|
963
|
+
const referencesTables: string[] = responseData.rest.reduce((accumulator: string[], row) => {
|
|
964
|
+
if ('entity_tag' in row && !accumulator.includes(row['entity_tag'])) {
|
|
965
|
+
accumulator.push(row['entity_tag']);
|
|
966
|
+
}
|
|
967
|
+
return accumulator;
|
|
968
|
+
}, []).map((entityTag) => entityTag.split('\\').pop().toLowerCase());
|
|
908
969
|
|
|
909
|
-
|
|
910
|
-
// todo - rethink the table ref entity system - when tables are renamed? no hooks exist in mysql
|
|
911
|
-
// since were already filtering on column, we can assume the first row constraint is the same as the rest
|
|
970
|
+
const shouldContinue = referencesTables.find((referencesTable) => tableToFetch.endsWith(referencesTable))
|
|
912
971
|
|
|
913
|
-
|
|
914
|
-
if ('entity_tag' in row && !accumulator.includes(row['entity_tag'])) {
|
|
915
|
-
accumulator.push(row['entity_tag']);
|
|
916
|
-
}
|
|
917
|
-
return accumulator;
|
|
918
|
-
}, []).map((entityTag) => entityTag.split('\\').pop().toLowerCase());
|
|
972
|
+
if (!shouldContinue) {
|
|
919
973
|
|
|
920
|
-
|
|
974
|
+
console.log('%c C6ENTITY: The constraintTableName (' + tableToFetch + ') did not end with any value in referencesTables', 'color: #c00', referencesTables)
|
|
921
975
|
|
|
922
|
-
|
|
976
|
+
continue;
|
|
923
977
|
|
|
924
|
-
|
|
978
|
+
}
|
|
925
979
|
|
|
926
|
-
|
|
980
|
+
console.log('%c C6ENTITY: The constraintTableName (' + tableToFetch + ') will be fetched.', 'color: #0c0')
|
|
927
981
|
|
|
928
982
|
}
|
|
929
983
|
|
|
930
|
-
|
|
984
|
+
const fetchTable = await C6.IMPORT(tableToFetch)
|
|
931
985
|
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
const fetchTable = await C6.IMPORT(table)
|
|
986
|
+
const RestApi = fetchTable.default
|
|
935
987
|
|
|
936
|
-
|
|
988
|
+
console.log('%c Fetch Dependencies will select (' + tableToFetch + ') using GET request', 'color: #33ccff')
|
|
937
989
|
|
|
938
|
-
|
|
990
|
+
let nextFetchDependencies = eFetchDependencies.NONE
|
|
939
991
|
|
|
940
|
-
|
|
992
|
+
if (fetchDependencies & eFetchDependencies.RECURSIVE) {
|
|
941
993
|
|
|
942
|
-
|
|
994
|
+
if (fetchDependencies & eFetchDependencies.ALL) {
|
|
943
995
|
|
|
944
|
-
|
|
996
|
+
throw Error('Recursive fetch dependencies with both PARENT and CHILD reference will result in an infin1ite loop. As there is not real ending condition, this is not supported.')
|
|
945
997
|
|
|
946
|
-
|
|
998
|
+
}
|
|
947
999
|
|
|
948
|
-
|
|
1000
|
+
nextFetchDependencies = fetchDependencies
|
|
949
1001
|
|
|
950
|
-
|
|
1002
|
+
} else if (fetchDependencies & eFetchDependencies.C6ENTITY) {
|
|
951
1003
|
|
|
952
|
-
|
|
1004
|
+
if (tableToFetch === "carbon_carbons") {
|
|
953
1005
|
|
|
954
|
-
|
|
1006
|
+
nextFetchDependencies = fetchDependencies
|
|
955
1007
|
|
|
956
|
-
|
|
1008
|
+
} else {
|
|
957
1009
|
|
|
958
|
-
|
|
1010
|
+
nextFetchDependencies = fetchDependencies ^ eFetchDependencies.C6ENTITY
|
|
959
1011
|
|
|
960
|
-
|
|
1012
|
+
}
|
|
961
1013
|
|
|
962
1014
|
}
|
|
963
1015
|
|
|
964
|
-
|
|
1016
|
+
console.log('fetchReferences', fetchReferences[tableToFetch], "Current fetchDependencies for (" + operatingTable + "):", fetchDependencies, "New fetchDependencies for (" + tableToFetch + "): ", nextFetchDependencies)
|
|
965
1017
|
|
|
966
|
-
|
|
1018
|
+
// todo - filter out ids that exist in state?!? note - remember that this does not necessarily mean the pk, but only known is its an FK to somewhere
|
|
1019
|
+
// it not certain that they are using carbons' entities either
|
|
967
1020
|
|
|
968
|
-
|
|
969
|
-
|
|
1021
|
+
// this is a dynamic call to the rest api, any generated table may resolve with (RestApi)
|
|
1022
|
+
// todo - using value to avoid joins.... but. maybe this should be a parameterizable option -- think race conditions; its safer to join
|
|
1023
|
+
apiRequestPromises.push(await RestApi.Get({
|
|
1024
|
+
[C6.WHERE]: {
|
|
1025
|
+
0: Object.keys(fetchReferences[tableToFetch]).reduce((sum, column) => {
|
|
970
1026
|
|
|
971
|
-
|
|
972
|
-
// todo - using value to avoid joins.... but. maybe this should be a parameterizable option -- think race conditions; its safer to join
|
|
973
|
-
apiRequestPromises.push(await RestApi.Get({
|
|
974
|
-
[C6.WHERE]: {
|
|
975
|
-
0: Object.keys(fetchReferences[table]).reduce((sum, column) => {
|
|
1027
|
+
fetchReferences[tableToFetch][column] = fetchReferences[tableToFetch][column].flat(Infinity)
|
|
976
1028
|
|
|
977
|
-
|
|
1029
|
+
if (0 === fetchReferences[tableToFetch][column].length) {
|
|
978
1030
|
|
|
979
|
-
|
|
1031
|
+
console.warn('The column (' + column + ') was not found in the response data. We will not fetch.', responseData)
|
|
980
1032
|
|
|
981
|
-
|
|
1033
|
+
return false;
|
|
982
1034
|
|
|
983
|
-
|
|
1035
|
+
}
|
|
984
1036
|
|
|
985
|
-
|
|
1037
|
+
sum[column] = fetchReferences[tableToFetch][column].length === 1
|
|
1038
|
+
? fetchReferences[tableToFetch][column][0]
|
|
1039
|
+
: [
|
|
1040
|
+
C6.IN, fetchReferences[tableToFetch][column]
|
|
1041
|
+
]
|
|
986
1042
|
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
1043
|
+
return sum
|
|
1044
|
+
}, {})
|
|
1045
|
+
},
|
|
1046
|
+
fetchDependencies: nextFetchDependencies
|
|
1047
|
+
}
|
|
1048
|
+
));
|
|
992
1049
|
|
|
993
|
-
|
|
994
|
-
}, {})
|
|
995
|
-
},
|
|
996
|
-
fetchDependencies: nextFetchDependencies
|
|
997
|
-
}
|
|
998
|
-
));
|
|
1050
|
+
}
|
|
999
1051
|
|
|
1000
|
-
|
|
1052
|
+
await Promise.all(apiRequestPromises)
|
|
1053
|
+
|
|
1054
|
+
request.fetchDependencies = apiRequestPromises
|
|
1001
1055
|
|
|
1002
|
-
|
|
1056
|
+
console.groupEnd()
|
|
1003
1057
|
|
|
1004
|
-
|
|
1058
|
+
}
|
|
1005
1059
|
|
|
1006
|
-
console.groupEnd()
|
|
1007
1060
|
|
|
1008
1061
|
}
|
|
1009
1062
|
|
|
1063
|
+
if (request.debug && isLocal) {
|
|
1010
1064
|
|
|
1011
|
-
|
|
1065
|
+
toast.success("DEVS: (" + requestMethod + ") request complete.", toastOptionsDevs);
|
|
1012
1066
|
|
|
1013
|
-
|
|
1067
|
+
}
|
|
1014
1068
|
|
|
1015
|
-
|
|
1069
|
+
return response;
|
|
1016
1070
|
|
|
1017
1071
|
}
|
|
1072
|
+
)
|
|
1073
|
+
;
|
|
1018
1074
|
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
});
|
|
1022
|
-
|
|
1023
|
-
} catch (error) {
|
|
1075
|
+
} catch
|
|
1076
|
+
(error) {
|
|
1024
1077
|
|
|
1025
1078
|
if (isTest) {
|
|
1026
1079
|
|