Application Android et IOS pour l'amicale des élèves
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

WebData.ts 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /*
  2. * Copyright (c) 2019 - 2020 Arnaud Vergnet.
  3. *
  4. * This file is part of Campus INSAT.
  5. *
  6. * Campus INSAT is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Campus INSAT is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
  18. */
  19. export const ERROR_TYPE = {
  20. SUCCESS: 0,
  21. BAD_CREDENTIALS: 1,
  22. BAD_TOKEN: 2,
  23. NO_CONSENT: 3,
  24. TOKEN_SAVE: 4,
  25. TOKEN_RETRIEVE: 5,
  26. BAD_INPUT: 400,
  27. FORBIDDEN: 403,
  28. CONNECTION_ERROR: 404,
  29. SERVER_ERROR: 500,
  30. UNKNOWN: 999,
  31. };
  32. export type ApiDataLoginType = {
  33. token: string;
  34. };
  35. export type ApiGenericDataType = {[key: string]: any};
  36. type ApiResponseType<T> = {
  37. error: number;
  38. data: T;
  39. };
  40. const API_ENDPOINT = 'https://www.amicale-insat.fr/api/';
  41. /**
  42. * Checks if the given API response is valid.
  43. *
  44. * For a request to be valid, it must match the response_format as defined in this file.
  45. *
  46. * @param response
  47. * @returns {boolean}
  48. */
  49. export function isApiResponseValid<T>(response: ApiResponseType<T>): boolean {
  50. return (
  51. response != null &&
  52. response.error != null &&
  53. response.data != null &&
  54. typeof response.data === 'object'
  55. );
  56. }
  57. /**
  58. * Sends a request to the Amicale Website backend
  59. *
  60. * In case of failure, the promise will be rejected with the error code.
  61. * In case of success, the promise will return the data object.
  62. *
  63. * @param path The API path from the API endpoint
  64. * @param method The HTTP method to use (GET or POST)
  65. * @param params The params to use for this request
  66. * @returns {Promise<ApiGenericDataType>}
  67. */
  68. export async function apiRequest<T>(
  69. path: string,
  70. method: string,
  71. params?: object,
  72. ): Promise<T> {
  73. return new Promise(
  74. (resolve: (data: T) => void, reject: (error: number) => void) => {
  75. let requestParams = {};
  76. if (params != null) {
  77. requestParams = {...params};
  78. }
  79. fetch(API_ENDPOINT + path, {
  80. method,
  81. headers: new Headers({
  82. Accept: 'application/json',
  83. 'Content-Type': 'application/json',
  84. }),
  85. body: JSON.stringify(requestParams),
  86. })
  87. .then(
  88. async (response: Response): Promise<ApiResponseType<T>> =>
  89. response.json(),
  90. )
  91. .then((response: ApiResponseType<T>) => {
  92. if (isApiResponseValid(response)) {
  93. if (response.error === ERROR_TYPE.SUCCESS) {
  94. resolve(response.data);
  95. } else {
  96. reject(response.error);
  97. }
  98. } else {
  99. reject(ERROR_TYPE.SERVER_ERROR);
  100. }
  101. })
  102. .catch((): void => reject(ERROR_TYPE.CONNECTION_ERROR));
  103. },
  104. );
  105. }
  106. /**
  107. * Reads data from the given url and returns it.
  108. *
  109. * Only use this function for non API calls.
  110. * For Amicale API calls, please use the apiRequest function.
  111. *
  112. * If no data was found, returns an empty object
  113. *
  114. * @param url The urls to fetch data from
  115. * @return Promise<any>
  116. */
  117. export async function readData(url: string): Promise<any> {
  118. return new Promise((resolve: (response: any) => void, reject: () => void) => {
  119. fetch(url)
  120. .then(async (response: Response): Promise<any> => response.json())
  121. .then((data: any): void => resolve(data))
  122. .catch((): void => reject());
  123. });
  124. }