Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a82c3e725d | |||
| 08124f212a | |||
| 631999e135 | |||
| 7674d9a299 | |||
| 9cd71ab601 |
2
pom.xml
2
pom.xml
@@ -3,7 +3,7 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>kangaroo-and-rabbit</groupId>
|
<groupId>kangaroo-and-rabbit</groupId>
|
||||||
<artifactId>archidata</artifactId>
|
<artifactId>archidata</artifactId>
|
||||||
<version>0.7.2</version>
|
<version>0.7.3</version>
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.version>3.1</maven.compiler.version>
|
<maven.compiler.version>3.1</maven.compiler.version>
|
||||||
<maven.compiler.source>21</maven.compiler.source>
|
<maven.compiler.source>21</maven.compiler.source>
|
||||||
|
|||||||
12
src/org/kar/archidata/annotation/TypeScriptProgress.java
Normal file
12
src/org/kar/archidata/annotation/TypeScriptProgress.java
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package org.kar.archidata.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/** In case of the update parameter with String input to detect null element. */
|
||||||
|
@Target({ ElementType.PARAMETER, ElementType.METHOD })
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface TypeScriptProgress {
|
||||||
|
}
|
||||||
@@ -319,8 +319,8 @@ public class DataResource {
|
|||||||
return Response.status(404).entity("{\"error\":\"media Does not exist: " + id + "\"}").type("application/json").build();
|
return Response.status(404).entity("{\"error\":\"media Does not exist: " + id + "\"}").type("application/json").build();
|
||||||
}
|
}
|
||||||
if (value.mimeType.contentEquals("image/jpeg") || value.mimeType.contentEquals("image/png")
|
if (value.mimeType.contentEquals("image/jpeg") || value.mimeType.contentEquals("image/png")
|
||||||
// || value.mimeType.contentEquals("image/webp")
|
// || value.mimeType.contentEquals("image/webp")
|
||||||
) {
|
) {
|
||||||
// reads input image
|
// reads input image
|
||||||
final BufferedImage inputImage = ImageIO.read(inputFile);
|
final BufferedImage inputImage = ImageIO.read(inputFile);
|
||||||
final int scaledWidth = 250;
|
final int scaledWidth = 250;
|
||||||
@@ -355,13 +355,12 @@ public class DataResource {
|
|||||||
return buildStream(filePathName, range, value.mimeType);
|
return buildStream(filePathName, range, value.mimeType);
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Secured
|
|
||||||
@GET
|
@GET
|
||||||
@Path("{id}/{name}")
|
@Path("{id}/{name}")
|
||||||
@PermitTokenInURI
|
@PermitTokenInURI
|
||||||
@RolesAllowed("USER")
|
@RolesAllowed("USER")
|
||||||
@Produces(MediaType.APPLICATION_OCTET_STREAM)
|
@Produces(MediaType.APPLICATION_OCTET_STREAM)
|
||||||
@Operation(description = "Get back some data from the data environment (with a beautifull name (permit download with basic name)", tags = "SYSTEM")
|
@Operation(description = "Get back some data from the data environment (with a beautiful name (permit download with basic name)", tags = "SYSTEM")
|
||||||
public Response retrieveDataFull(@Context final SecurityContext sc, @QueryParam(HttpHeaders.AUTHORIZATION) final String token, @HeaderParam("Range") final String range,
|
public Response retrieveDataFull(@Context final SecurityContext sc, @QueryParam(HttpHeaders.AUTHORIZATION) final String token, @HeaderParam("Range") final String range,
|
||||||
@PathParam("id") final UUID id, @PathParam("name") final String name) throws Exception {
|
@PathParam("id") final UUID id, @PathParam("name") final String name) throws Exception {
|
||||||
final GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
final GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||||
|
|||||||
@@ -921,7 +921,9 @@ public class DataAccess {
|
|||||||
}
|
}
|
||||||
// ps.execute();
|
// ps.execute();
|
||||||
} catch (final SQLException ex) {
|
} catch (final SQLException ex) {
|
||||||
|
LOGGER.error("Fail SQL request: {}", ex.getMessage());
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
|
throw new DataAccessException("Fail to Insert data in DB : " + ex.getMessage());
|
||||||
} finally {
|
} finally {
|
||||||
entry.close();
|
entry.close();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import java.util.Set;
|
|||||||
|
|
||||||
import org.glassfish.jersey.media.multipart.FormDataParam;
|
import org.glassfish.jersey.media.multipart.FormDataParam;
|
||||||
import org.kar.archidata.annotation.AsyncType;
|
import org.kar.archidata.annotation.AsyncType;
|
||||||
|
import org.kar.archidata.annotation.TypeScriptProgress;
|
||||||
import org.kar.archidata.catcher.RestErrorResponse;
|
import org.kar.archidata.catcher.RestErrorResponse;
|
||||||
import org.kar.archidata.dataAccess.DataFactoryZod.ClassElement;
|
import org.kar.archidata.dataAccess.DataFactoryZod.ClassElement;
|
||||||
import org.kar.archidata.dataAccess.DataFactoryZod.GeneratedTypes;
|
import org.kar.archidata.dataAccess.DataFactoryZod.GeneratedTypes;
|
||||||
@@ -56,7 +57,7 @@ public class DataFactoryTsApi {
|
|||||||
/**
|
/**
|
||||||
* API of the server (auto-generated code)
|
* API of the server (auto-generated code)
|
||||||
*/
|
*/
|
||||||
import { HTTPMimeType, HTTPRequestModel, ModelResponseHttp, RESTConfig, RESTRequestJson, RESTRequestJsonArray, RESTRequestVoid } from "./rest-tools"
|
import { HTTPMimeType, HTTPRequestModel, ModelResponseHttp, RESTConfig, RESTCallbacks, RESTRequestJson, RESTRequestJsonArray, RESTRequestVoid } from "./rest-tools"
|
||||||
import { """;
|
import { """;
|
||||||
|
|
||||||
for (final Class<?> clazz : classs) {
|
for (final Class<?> clazz : classs) {
|
||||||
@@ -125,6 +126,14 @@ public class DataFactoryTsApi {
|
|||||||
return Arrays.asList(((Produces) annotation[0]).value());
|
return Arrays.asList(((Produces) annotation[0]).value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean apiAnnotationTypeScriptProgress(final Method element) throws Exception {
|
||||||
|
final Annotation[] annotation = element.getDeclaredAnnotationsByType(TypeScriptProgress.class);
|
||||||
|
if (annotation.length == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public static List<String> apiAnnotationProduces(final Class<?> clazz, final Method method) throws Exception {
|
public static List<String> apiAnnotationProduces(final Class<?> clazz, final Method method) throws Exception {
|
||||||
final List<String> data = apiAnnotationProduces(method);
|
final List<String> data = apiAnnotationProduces(method);
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
@@ -261,6 +270,7 @@ public class DataFactoryTsApi {
|
|||||||
if (methodDescription != null) {
|
if (methodDescription != null) {
|
||||||
LOGGER.trace(" description: {}", methodDescription);
|
LOGGER.trace(" description: {}", methodDescription);
|
||||||
}
|
}
|
||||||
|
final boolean needGenerateProgress = apiAnnotationTypeScriptProgress(method);
|
||||||
Class<?> returnTypeModel = apiAnnotationGetAsyncType(method);
|
Class<?> returnTypeModel = apiAnnotationGetAsyncType(method);
|
||||||
if (returnTypeModel == null) {
|
if (returnTypeModel == null) {
|
||||||
returnTypeModel = method.getReturnType();
|
returnTypeModel = method.getReturnType();
|
||||||
@@ -387,6 +397,9 @@ public class DataFactoryTsApi {
|
|||||||
} else if (formDataParams.size() != 0) {
|
} else if (formDataParams.size() != 0) {
|
||||||
builder.append(" data,");
|
builder.append(" data,");
|
||||||
}
|
}
|
||||||
|
if (needGenerateProgress) {
|
||||||
|
builder.append(" callback,");
|
||||||
|
}
|
||||||
builder.append(" }: {");
|
builder.append(" }: {");
|
||||||
builder.append("\n\t\trestConfig: RESTConfig,");
|
builder.append("\n\t\trestConfig: RESTConfig,");
|
||||||
if (!queryParams.isEmpty()) {
|
if (!queryParams.isEmpty()) {
|
||||||
@@ -454,6 +467,9 @@ public class DataFactoryTsApi {
|
|||||||
}
|
}
|
||||||
builder.append(",");
|
builder.append(",");
|
||||||
}
|
}
|
||||||
|
if (needGenerateProgress) {
|
||||||
|
builder.append("\n\t\tcallback?: RESTCallbacks,");
|
||||||
|
}
|
||||||
builder.append("\n\t}): Promise<");
|
builder.append("\n\t}): Promise<");
|
||||||
builder.append(tmpReturn.tsTypeName);
|
builder.append(tmpReturn.tsTypeName);
|
||||||
if (returnModelIsArray) {
|
if (returnModelIsArray) {
|
||||||
@@ -519,6 +535,9 @@ public class DataFactoryTsApi {
|
|||||||
} else if (formDataParams.size() != 0) {
|
} else if (formDataParams.size() != 0) {
|
||||||
builder.append("\n\t\t\tdata,");
|
builder.append("\n\t\t\tdata,");
|
||||||
}
|
}
|
||||||
|
if (needGenerateProgress) {
|
||||||
|
builder.append("\n\t\t\tcallback,");
|
||||||
|
}
|
||||||
builder.append("\n\t\t}");
|
builder.append("\n\t\t}");
|
||||||
if (tmpReturn.tsCheckType != null) {
|
if (tmpReturn.tsCheckType != null) {
|
||||||
builder.append(", ");
|
builder.append(", ");
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import java.sql.PreparedStatement;
|
|||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.kar.archidata.annotation.AnnotationTools;
|
import org.kar.archidata.annotation.AnnotationTools;
|
||||||
import org.kar.archidata.dataAccess.CountInOut;
|
import org.kar.archidata.dataAccess.CountInOut;
|
||||||
@@ -14,6 +15,7 @@ import org.kar.archidata.dataAccess.DataFactory;
|
|||||||
import org.kar.archidata.dataAccess.LazyGetter;
|
import org.kar.archidata.dataAccess.LazyGetter;
|
||||||
import org.kar.archidata.dataAccess.QueryOptions;
|
import org.kar.archidata.dataAccess.QueryOptions;
|
||||||
import org.kar.archidata.exception.DataAccessException;
|
import org.kar.archidata.exception.DataAccessException;
|
||||||
|
import org.kar.archidata.tools.UuidUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@@ -51,10 +53,33 @@ public class AddOnManyToOne implements DataAccessAddOn {
|
|||||||
public void insertData(final PreparedStatement ps, final Field field, final Object rootObject, final CountInOut iii) throws Exception {
|
public void insertData(final PreparedStatement ps, final Field field, final Object rootObject, final CountInOut iii) throws Exception {
|
||||||
final Object data = field.get(rootObject);
|
final Object data = field.get(rootObject);
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
ps.setNull(iii.value, Types.BIGINT);
|
if (field.getType() == Long.class) {
|
||||||
|
ps.setNull(iii.value, Types.BIGINT);
|
||||||
|
} else if (field.getType() == Integer.class) {
|
||||||
|
ps.setNull(iii.value, Types.INTEGER);
|
||||||
|
} else if (field.getType() == Short.class) {
|
||||||
|
ps.setNull(iii.value, Types.INTEGER);
|
||||||
|
} else if (field.getType() == String.class) {
|
||||||
|
ps.setNull(iii.value, Types.VARCHAR);
|
||||||
|
} else if (field.getType() == UUID.class) {
|
||||||
|
ps.setNull(iii.value, Types.BINARY);
|
||||||
|
}
|
||||||
} else if (field.getType() == Long.class) {
|
} else if (field.getType() == Long.class) {
|
||||||
final Long dataLong = (Long) data;
|
final Long dataTyped = (Long) data;
|
||||||
ps.setLong(iii.value, dataLong);
|
ps.setLong(iii.value, dataTyped);
|
||||||
|
} else if (field.getType() == Integer.class) {
|
||||||
|
final Integer dataTyped = (Integer) data;
|
||||||
|
ps.setInt(iii.value, dataTyped);
|
||||||
|
} else if (field.getType() == Short.class) {
|
||||||
|
final Short dataTyped = (Short) data;
|
||||||
|
ps.setShort(iii.value, dataTyped);
|
||||||
|
} else if (field.getType() == String.class) {
|
||||||
|
final String dataTyped = (String) data;
|
||||||
|
ps.setString(iii.value, dataTyped);
|
||||||
|
} else if (field.getType() == UUID.class) {
|
||||||
|
final UUID dataTyped = (UUID) data;
|
||||||
|
final byte[] dataByte = UuidUtils.asBytes(dataTyped);
|
||||||
|
ps.setBytes(iii.value, dataByte);
|
||||||
} else {
|
} else {
|
||||||
final Field idField = AnnotationTools.getFieldOfId(field.getType());
|
final Field idField = AnnotationTools.getFieldOfId(field.getType());
|
||||||
final Object uid = idField.get(data);
|
final Object uid = idField.get(data);
|
||||||
@@ -71,7 +96,11 @@ public class AddOnManyToOne implements DataAccessAddOn {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canInsert(final Field field) {
|
public boolean canInsert(final Field field) {
|
||||||
if (field.getType() == Long.class) {
|
if (field.getType() == Long.class
|
||||||
|
|| field.getType() == Integer.class
|
||||||
|
|| field.getType() == Short.class
|
||||||
|
|| field.getType() == String.class
|
||||||
|
|| field.getType() == UUID.class) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
final ManyToOne decorators = field.getDeclaredAnnotation(ManyToOne.class);
|
final ManyToOne decorators = field.getDeclaredAnnotation(ManyToOne.class);
|
||||||
@@ -88,7 +117,11 @@ public class AddOnManyToOne implements DataAccessAddOn {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canRetrieve(final Field field) {
|
public boolean canRetrieve(final Field field) {
|
||||||
if (field.getType() == Long.class) {
|
if (field.getType() == Long.class
|
||||||
|
|| field.getType() == Integer.class
|
||||||
|
|| field.getType() == Short.class
|
||||||
|
|| field.getType() == String.class
|
||||||
|
|| field.getType() == UUID.class) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
final ManyToOne decorators = field.getDeclaredAnnotation(ManyToOne.class);
|
final ManyToOne decorators = field.getDeclaredAnnotation(ManyToOne.class);
|
||||||
@@ -101,7 +134,11 @@ public class AddOnManyToOne implements DataAccessAddOn {
|
|||||||
@Override
|
@Override
|
||||||
public void generateQuerry(@NotNull final String tableName, @NotNull final Field field, @NotNull final StringBuilder querrySelect, @NotNull final StringBuilder querry, @NotNull final String name,
|
public void generateQuerry(@NotNull final String tableName, @NotNull final Field field, @NotNull final StringBuilder querrySelect, @NotNull final StringBuilder querry, @NotNull final String name,
|
||||||
@NotNull final CountInOut elemCount, final QueryOptions options) throws Exception {
|
@NotNull final CountInOut elemCount, final QueryOptions options) throws Exception {
|
||||||
if (field.getType() == Long.class) {
|
if (field.getType() == Long.class
|
||||||
|
|| field.getType() == Integer.class
|
||||||
|
|| field.getType() == Short.class
|
||||||
|
|| field.getType() == String.class
|
||||||
|
|| field.getType() == UUID.class) {
|
||||||
querrySelect.append(" ");
|
querrySelect.append(" ");
|
||||||
querrySelect.append(tableName);
|
querrySelect.append(tableName);
|
||||||
querrySelect.append(".");
|
querrySelect.append(".");
|
||||||
@@ -150,6 +187,39 @@ public class AddOnManyToOne implements DataAccessAddOn {
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (field.getType() == Integer.class) {
|
||||||
|
final Integer foreignKey = rs.getInt(count.value);
|
||||||
|
count.inc();
|
||||||
|
if (!rs.wasNull()) {
|
||||||
|
field.set(data, foreignKey);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (field.getType() == Short.class) {
|
||||||
|
final Short foreignKey = rs.getShort(count.value);
|
||||||
|
count.inc();
|
||||||
|
if (!rs.wasNull()) {
|
||||||
|
field.set(data, foreignKey);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (field.getType() == String.class) {
|
||||||
|
final String foreignKey = rs.getString(count.value);
|
||||||
|
count.inc();
|
||||||
|
if (!rs.wasNull()) {
|
||||||
|
field.set(data, foreignKey);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (field.getType() == UUID.class) {
|
||||||
|
final byte[] tmp = rs.getBytes(count.value);
|
||||||
|
count.inc();
|
||||||
|
if (!rs.wasNull()) {
|
||||||
|
final UUID foreignKey = UuidUtils.asUuid(tmp);
|
||||||
|
field.set(data, foreignKey);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
final Class<?> objectClass = field.getType();
|
final Class<?> objectClass = field.getType();
|
||||||
final ManyToOne decorators = field.getDeclaredAnnotation(ManyToOne.class);
|
final ManyToOne decorators = field.getDeclaredAnnotation(ManyToOne.class);
|
||||||
if (decorators == null) {
|
if (decorators == null) {
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ export interface RESTModel {
|
|||||||
accept?: HTTPMimeType;
|
accept?: HTTPMimeType;
|
||||||
// Content of the local data.
|
// Content of the local data.
|
||||||
contentType?: HTTPMimeType;
|
contentType?: HTTPMimeType;
|
||||||
// Mode of the TOKEN in urk or Header
|
// Mode of the TOKEN in URL or Header (?token:${tokenInUrl})
|
||||||
tokenInUrl?: boolean;
|
tokenInUrl?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,22 +67,48 @@ export function isArrayOf<TYPE>(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type RESTRequestType = {
|
function isNullOrUndefined(data: any): data is undefined | null {
|
||||||
|
return data === undefined || data === null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// generic progression callback
|
||||||
|
export type ProgressCallback = (count: number, total: number) => void;
|
||||||
|
|
||||||
|
export interface RESTAbort {
|
||||||
|
abort?: () => boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Rest generic callback have a basic model to upload and download advancement.
|
||||||
|
export interface RESTCallbacks {
|
||||||
|
progressUpload?: ProgressCallback,
|
||||||
|
progressDownload?: ProgressCallback,
|
||||||
|
abortHandle?: RESTAbort,
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface RESTRequestType {
|
||||||
restModel: RESTModel,
|
restModel: RESTModel,
|
||||||
restConfig: RESTConfig,
|
restConfig: RESTConfig,
|
||||||
data?: any,
|
data?: any,
|
||||||
params?: object,
|
params?: object,
|
||||||
queries?: object,
|
queries?: object,
|
||||||
|
callback?: RESTCallbacks,
|
||||||
};
|
};
|
||||||
|
|
||||||
function removeTrailingSlashes(input: string): string {
|
function removeTrailingSlashes(input: string): string {
|
||||||
|
if (isNullOrUndefined(input)) {
|
||||||
|
return "undefined";
|
||||||
|
}
|
||||||
return input.replace(/\/+$/, '');
|
return input.replace(/\/+$/, '');
|
||||||
}
|
}
|
||||||
function removeLeadingSlashes(input: string): string {
|
function removeLeadingSlashes(input: string): string {
|
||||||
|
if (isNullOrUndefined(input)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
return input.replace(/^\/+/, '');
|
return input.replace(/^\/+/, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function RESTUrl({ restModel, restConfig, data, params, queries }: RESTRequestType): string {
|
export function RESTUrl({ restModel, restConfig, params, queries }: RESTRequestType): string {
|
||||||
// Create the URL PATH:
|
// Create the URL PATH:
|
||||||
let generateUrl = `${removeTrailingSlashes(restConfig.server)}/${removeLeadingSlashes(restModel.endPoint)}`;
|
let generateUrl = `${removeTrailingSlashes(restConfig.server)}/${removeLeadingSlashes(restModel.endPoint)}`;
|
||||||
if (params !== undefined) {
|
if (params !== undefined) {
|
||||||
@@ -91,7 +117,7 @@ export function RESTUrl({ restModel, restConfig, data, params, queries }: RESTRe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (queries === undefined && (restConfig.token === undefined || restModel.tokenInUrl !== true)) {
|
if (queries === undefined && (restConfig.token === undefined || restModel.tokenInUrl !== true)) {
|
||||||
return generateUrl;
|
return generateUrl;
|
||||||
}
|
}
|
||||||
const searchParams = new URLSearchParams();
|
const searchParams = new URLSearchParams();
|
||||||
if (queries !== undefined) {
|
if (queries !== undefined) {
|
||||||
@@ -112,7 +138,92 @@ export function RESTUrl({ restModel, restConfig, data, params, queries }: RESTRe
|
|||||||
return generateUrl + "?" + searchParams.toString();
|
return generateUrl + "?" + searchParams.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function RESTRequest({ restModel, restConfig, data, params, queries }: RESTRequestType): Promise<ModelResponseHttp> {
|
|
||||||
|
export function fetchProgress(generateUrl: string, { method, headers, body }: {
|
||||||
|
method: HTTPRequestModel,
|
||||||
|
headers: any,
|
||||||
|
body: any,
|
||||||
|
}, { progressUpload, progressDownload, abortHandle }: RESTCallbacks): Promise<Response> {
|
||||||
|
const xhr = {
|
||||||
|
io: new XMLHttpRequest()
|
||||||
|
}
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
// Stream the upload progress
|
||||||
|
if (progressUpload) {
|
||||||
|
xhr.io.upload.addEventListener("progress", (dataEvent) => {
|
||||||
|
if (dataEvent.lengthComputable) {
|
||||||
|
//console.log(` ==> has a progress event: ${dataEvent.loaded} / ${dataEvent.total}`);
|
||||||
|
progressUpload(dataEvent.loaded, dataEvent.total);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Stream the download progress
|
||||||
|
if (progressDownload) {
|
||||||
|
xhr.io.addEventListener("progress", (dataEvent) => {
|
||||||
|
if (dataEvent.lengthComputable) {
|
||||||
|
//console.log(` ==> download progress:: ${dataEvent.loaded} / ${dataEvent.total}`);
|
||||||
|
progressUpload(dataEvent.loaded, dataEvent.total);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (abortHandle) {
|
||||||
|
abortHandle.abort = () => {
|
||||||
|
if (xhr.io) {
|
||||||
|
console.log(`Request abort on the XMLHttpRequest: ${generateUrl}`);
|
||||||
|
xhr.io.abort();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
console.log(`Request abort (FAIL) on the XMLHttpRequest: ${generateUrl}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Check if we have an internal Fail:
|
||||||
|
xhr.io.addEventListener('error', () => {
|
||||||
|
xhr.io = undefined;
|
||||||
|
reject(new TypeError('Failed to fetch'))
|
||||||
|
});
|
||||||
|
|
||||||
|
// Capture the end of the stream
|
||||||
|
xhr.io.addEventListener("loadend", () => {
|
||||||
|
if (xhr.io.readyState !== XMLHttpRequest.DONE) {
|
||||||
|
//console.log(` ==> READY state`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (xhr.io.status === 0) {
|
||||||
|
//the stream has been aborted
|
||||||
|
reject(new TypeError('Fetch has been aborted'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Stream is ended, transform in a generic response:
|
||||||
|
const response = new Response(xhr.io.response, {
|
||||||
|
status: xhr.io.status,
|
||||||
|
statusText: xhr.io.statusText
|
||||||
|
});
|
||||||
|
const headersArray = xhr.io.getAllResponseHeaders().trim().replaceAll("\r\n", "\n").split('\n');
|
||||||
|
headersArray.forEach(function (header) {
|
||||||
|
const firstColonIndex = header.indexOf(':');
|
||||||
|
if (firstColonIndex !== -1) {
|
||||||
|
var key = header.substring(0, firstColonIndex).trim();
|
||||||
|
var value = header.substring(firstColonIndex + 1).trim();
|
||||||
|
response.headers.set(key, value);
|
||||||
|
} else {
|
||||||
|
response.headers.set(header, "");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
xhr.io = undefined;
|
||||||
|
resolve(response);
|
||||||
|
});
|
||||||
|
xhr.io.open(method, generateUrl, true);
|
||||||
|
if (!isNullOrUndefined(headers)) {
|
||||||
|
for (const [key, value] of Object.entries(headers)) {
|
||||||
|
xhr.io.setRequestHeader(key, value as string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xhr.io.send(body);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function RESTRequest({ restModel, restConfig, data, params, queries, callback }: RESTRequestType): Promise<ModelResponseHttp> {
|
||||||
// Create the URL PATH:
|
// Create the URL PATH:
|
||||||
let generateUrl = RESTUrl({ restModel, restConfig, data, params, queries });
|
let generateUrl = RESTUrl({ restModel, restConfig, data, params, queries });
|
||||||
let headers: any = {};
|
let headers: any = {};
|
||||||
@@ -139,23 +250,37 @@ export function RESTRequest({ restModel, restConfig, data, params, queries }: RE
|
|||||||
}
|
}
|
||||||
body = formData
|
body = formData
|
||||||
}
|
}
|
||||||
console.log(`Call ${generateUrl}`)
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
fetch(generateUrl, {
|
let action: undefined | Promise<Response> = undefined;
|
||||||
method: restModel.requestType,
|
if (isNullOrUndefined(callback)
|
||||||
headers,
|
|| (isNullOrUndefined(callback.progressDownload)
|
||||||
body,
|
&& isNullOrUndefined(callback.progressUpload)
|
||||||
}).then((response: Response) => {
|
&& isNullOrUndefined(callback.abortHandle))) {
|
||||||
|
// No information needed: call the generic fetch interface
|
||||||
|
action = fetch(generateUrl, {
|
||||||
|
method: restModel.requestType,
|
||||||
|
headers,
|
||||||
|
body,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// need progression information: call old fetch model (XMLHttpRequest) that permit to keep % upload and % download for HTTP1.x
|
||||||
|
action = fetchProgress(generateUrl, {
|
||||||
|
method: restModel.requestType ?? HTTPRequestModel.GET,
|
||||||
|
headers,
|
||||||
|
body,
|
||||||
|
}, callback);
|
||||||
|
}
|
||||||
|
action.then((response: Response) => {
|
||||||
if (response.status >= 200 && response.status <= 299) {
|
if (response.status >= 200 && response.status <= 299) {
|
||||||
const contentType = response.headers.get('Content-Type');
|
const contentType = response.headers.get('Content-Type');
|
||||||
if (restModel.accept !== contentType) {
|
if (restModel.accept !== contentType) {
|
||||||
reject({
|
reject({
|
||||||
name: `REST check wrong type: ${restModel.accept} != ${contentType}`,
|
|
||||||
message: "rest-tools.ts Wrong type in the message return type",
|
|
||||||
time: Date().toString(),
|
time: Date().toString(),
|
||||||
status: 901,
|
status: 901,
|
||||||
|
error: `REST check wrong type: ${restModel.accept} != ${contentType}`,
|
||||||
statusMessage: "Fetch error",
|
statusMessage: "Fetch error",
|
||||||
});
|
message: "rest-tools.ts Wrong type in the message return type"
|
||||||
|
} as RestErrorResponse);
|
||||||
} else if (contentType === HTTPMimeType.JSON) {
|
} else if (contentType === HTTPMimeType.JSON) {
|
||||||
response
|
response
|
||||||
.json()
|
.json()
|
||||||
@@ -165,37 +290,39 @@ export function RESTRequest({ restModel, restConfig, data, params, queries }: RE
|
|||||||
})
|
})
|
||||||
.catch((reason: any) => {
|
.catch((reason: any) => {
|
||||||
reject({
|
reject({
|
||||||
name: `REST parse json fail: ${reason}`,
|
|
||||||
message: "rest-tools.ts Wrong message model to parse",
|
|
||||||
time: Date().toString(),
|
time: Date().toString(),
|
||||||
status: 902,
|
status: 902,
|
||||||
|
error: `REST parse json fail: ${reason}`,
|
||||||
statusMessage: "Fetch parse error",
|
statusMessage: "Fetch parse error",
|
||||||
});
|
message: "rest-tools.ts Wrong message model to parse"
|
||||||
|
} as RestErrorResponse);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
resolve({ status: response.status, data: response.body });
|
resolve({ status: response.status, data: response.body });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
reject({
|
reject({
|
||||||
name: `${response.body}`,
|
|
||||||
message: "rest-tools.ts Wrong return code",
|
|
||||||
time: Date().toString(),
|
time: Date().toString(),
|
||||||
status: response.status,
|
status: response.status,
|
||||||
|
error: `${response.body}`,
|
||||||
statusMessage: "Fetch code error",
|
statusMessage: "Fetch code error",
|
||||||
});
|
message: "rest-tools.ts Wrong return code"
|
||||||
|
} as RestErrorResponse);
|
||||||
}
|
}
|
||||||
}).catch((error: any) => {
|
}).catch((error: any) => {
|
||||||
reject({
|
reject({
|
||||||
name: error,
|
|
||||||
message: "http-wrapper.ts detect an error in the fetch request",
|
|
||||||
time: Date(),
|
time: Date(),
|
||||||
status: 999,
|
status: 999,
|
||||||
statusMessage: "Fetch catch error"
|
error: error,
|
||||||
|
statusMessage: "Fetch catch error",
|
||||||
|
message: "rest-tools.ts detect an error in the fetch request"
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export function RESTRequestJson<TYPE>(request: RESTRequestType, checker: (data: any) => data is TYPE): Promise<TYPE> {
|
export function RESTRequestJson<TYPE>(request: RESTRequestType, checker: (data: any) => data is TYPE): Promise<TYPE> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
RESTRequest(request).then((value: ModelResponseHttp) => {
|
RESTRequest(request).then((value: ModelResponseHttp) => {
|
||||||
@@ -203,12 +330,12 @@ export function RESTRequestJson<TYPE>(request: RESTRequestType, checker: (data:
|
|||||||
resolve(value.data);
|
resolve(value.data);
|
||||||
} else {
|
} else {
|
||||||
reject({
|
reject({
|
||||||
name: "REST Fail to verify the data",
|
|
||||||
message: "api.ts Check type as fail",
|
|
||||||
time: Date().toString(),
|
time: Date().toString(),
|
||||||
status: 950,
|
status: 950,
|
||||||
|
error: "REST Fail to verify the data",
|
||||||
statusMessage: "API cast ERROR",
|
statusMessage: "API cast ERROR",
|
||||||
});
|
message: "api.ts Check type as fail"
|
||||||
|
} as RestErrorResponse);
|
||||||
}
|
}
|
||||||
}).catch((reason: RestErrorResponse) => {
|
}).catch((reason: RestErrorResponse) => {
|
||||||
reject(reason);
|
reject(reason);
|
||||||
@@ -222,12 +349,12 @@ export function RESTRequestJsonArray<TYPE>(request: RESTRequestType, checker: (d
|
|||||||
resolve(value.data);
|
resolve(value.data);
|
||||||
} else {
|
} else {
|
||||||
reject({
|
reject({
|
||||||
name: "REST Fail to verify the data",
|
|
||||||
message: "api.ts Check type as fail",
|
|
||||||
time: Date().toString(),
|
time: Date().toString(),
|
||||||
status: 950,
|
status: 950,
|
||||||
|
error: "REST Fail to verify the data",
|
||||||
statusMessage: "API cast ERROR",
|
statusMessage: "API cast ERROR",
|
||||||
});
|
message: "api.ts Check type as fail"
|
||||||
|
} as RestErrorResponse);
|
||||||
}
|
}
|
||||||
}).catch((reason: RestErrorResponse) => {
|
}).catch((reason: RestErrorResponse) => {
|
||||||
reject(reason);
|
reject(reason);
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
0.7.2
|
0.7.3
|
||||||
|
|||||||
Reference in New Issue
Block a user