Compare commits
9 Commits
88b27e5f39
...
401e2ce3c5
Author | SHA1 | Date | |
---|---|---|---|
401e2ce3c5 | |||
693d59ab68 | |||
4eff2e55ef | |||
1e890f9524 | |||
dbb2527cb8 | |||
d65faa8810 | |||
9c9476b052 | |||
3e92c2b74a | |||
a7134c01ed |
@ -1,4 +1,4 @@
|
|||||||
Karideo
|
Karusic
|
||||||
=======
|
=======
|
||||||
|
|
||||||
**K**angaroo **A**nd **R**abbit (m)usic is a simple framework to propose music streaming for personal network
|
**K**angaroo **A**nd **R**abbit (m)usic is a simple framework to propose music streaming for personal network
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>kangaroo-and-rabbit</groupId>
|
<groupId>kangaroo-and-rabbit</groupId>
|
||||||
<artifactId>archidata</artifactId>
|
<artifactId>archidata</artifactId>
|
||||||
<version>0.23.6</version>
|
<version>0.25.4</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- Loopback of logger JDK logging API to SLF4J -->
|
<!-- Loopback of logger JDK logging API to SLF4J -->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -13,6 +13,7 @@ import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
|
|||||||
import org.glassfish.jersey.jackson.JacksonFeature;
|
import org.glassfish.jersey.jackson.JacksonFeature;
|
||||||
import org.glassfish.jersey.media.multipart.MultiPartFeature;
|
import org.glassfish.jersey.media.multipart.MultiPartFeature;
|
||||||
import org.glassfish.jersey.server.ResourceConfig;
|
import org.glassfish.jersey.server.ResourceConfig;
|
||||||
|
import org.glassfish.jersey.server.validation.ValidationFeature;
|
||||||
import org.kar.archidata.UpdateJwtPublicKey;
|
import org.kar.archidata.UpdateJwtPublicKey;
|
||||||
import org.kar.archidata.api.DataResource;
|
import org.kar.archidata.api.DataResource;
|
||||||
import org.kar.archidata.api.ProxyResource;
|
import org.kar.archidata.api.ProxyResource;
|
||||||
@ -151,6 +152,8 @@ public class WebLauncher {
|
|||||||
|
|
||||||
// add jackson to be discover when we are ins standalone server
|
// add jackson to be discover when we are ins standalone server
|
||||||
rc.register(JacksonFeature.class);
|
rc.register(JacksonFeature.class);
|
||||||
|
// enable jersey specific validations (@Valid)
|
||||||
|
rc.register(ValidationFeature.class);
|
||||||
// enable this to show low level request
|
// enable this to show low level request
|
||||||
// rc.property(LoggingFeature.LOGGING_FEATURE_LOGGER_LEVEL_SERVER, Level.WARNING.getName());
|
// rc.property(LoggingFeature.LOGGING_FEATURE_LOGGER_LEVEL_SERVER, Level.WARNING.getName());
|
||||||
|
|
||||||
|
@ -32,7 +32,6 @@ public class WebLauncherLocal extends WebLauncher {
|
|||||||
if (true) {
|
if (true) {
|
||||||
// for local test:
|
// for local test:
|
||||||
ConfigBaseVariable.apiAdress = "http://0.0.0.0:19080/karusic/api/";
|
ConfigBaseVariable.apiAdress = "http://0.0.0.0:19080/karusic/api/";
|
||||||
// ConfigBaseVariable.ssoAdress = "https://atria-soft.org/karso/api/";
|
|
||||||
ConfigBaseVariable.dbPort = "3906";
|
ConfigBaseVariable.dbPort = "3906";
|
||||||
ConfigBaseVariable.testMode = "true";
|
ConfigBaseVariable.testMode = "true";
|
||||||
}
|
}
|
||||||
|
@ -6,9 +6,9 @@ import java.util.UUID;
|
|||||||
|
|
||||||
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
|
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
|
||||||
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.apiGenerator.ApiAsyncType;
|
||||||
import org.kar.archidata.annotation.FormDataOptional;
|
import org.kar.archidata.annotation.apiGenerator.ApiInputOptional;
|
||||||
import org.kar.archidata.annotation.TypeScriptProgress;
|
import org.kar.archidata.annotation.apiGenerator.ApiTypeScriptProgress;
|
||||||
import org.kar.archidata.dataAccess.DBAccess;
|
import org.kar.archidata.dataAccess.DBAccess;
|
||||||
import org.kar.archidata.dataAccess.DataAccess;
|
import org.kar.archidata.dataAccess.DataAccess;
|
||||||
import org.kar.archidata.dataAccess.addOnSQL.AddOnDataJson;
|
import org.kar.archidata.dataAccess.addOnSQL.AddOnDataJson;
|
||||||
@ -74,7 +74,7 @@ public class AlbumResource {
|
|||||||
@RolesAllowed("ADMIN")
|
@RolesAllowed("ADMIN")
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
@Operation(description = "Update a specific album")
|
@Operation(description = "Update a specific album")
|
||||||
public Album patch(@PathParam("id") final Long id, @AsyncType(Album.class) final String jsonRequest) throws Exception {
|
public Album patch(@PathParam("id") final Long id, @ApiAsyncType(Album.class) final String jsonRequest) throws Exception {
|
||||||
// final Query<Album> query = this.morphiaService.getDatastore().find(Album.class).filter(Filters.eq("id", id));
|
// final Query<Album> query = this.morphiaService.getDatastore().find(Album.class).filter(Filters.eq("id", id));
|
||||||
// final UpdateOperations<Album> ops = this.morphiaService.getDatastore().createUpdateOperations(Album.class)
|
// final UpdateOperations<Album> ops = this.morphiaService.getDatastore().createUpdateOperations(Album.class)
|
||||||
// .set("name", master.getName());
|
// .set("name", master.getName());
|
||||||
@ -119,9 +119,9 @@ public class AlbumResource {
|
|||||||
@RolesAllowed("ADMIN")
|
@RolesAllowed("ADMIN")
|
||||||
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
||||||
@Operation(description = "Add a cover on a specific album")
|
@Operation(description = "Add a cover on a specific album")
|
||||||
@TypeScriptProgress
|
@ApiTypeScriptProgress
|
||||||
public Album uploadCover(@PathParam("id") final Long id, @FormDataOptional @FormDataParam("uri") final String uri, @FormDataOptional @FormDataParam("file") final InputStream fileInputStream,
|
public Album uploadCover(@PathParam("id") final Long id, @ApiInputOptional @FormDataParam("uri") final String uri, @ApiInputOptional @FormDataParam("file") final InputStream fileInputStream,
|
||||||
@FormDataOptional @FormDataParam("file") final FormDataContentDisposition fileMetaData) throws Exception {
|
@ApiInputOptional @FormDataParam("file") final FormDataContentDisposition fileMetaData) throws Exception {
|
||||||
try (DBAccess db = DBAccess.createInterface()) {
|
try (DBAccess db = DBAccess.createInterface()) {
|
||||||
if (uri != null) {
|
if (uri != null) {
|
||||||
DataTools.uploadCoverFromUri(db, Album.class, id, uri);
|
DataTools.uploadCoverFromUri(db, Album.class, id, uri);
|
||||||
|
@ -6,9 +6,8 @@ import java.util.List;
|
|||||||
import org.bson.types.ObjectId;
|
import org.bson.types.ObjectId;
|
||||||
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
|
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
|
||||||
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.apiGenerator.ApiInputOptional;
|
||||||
import org.kar.archidata.annotation.FormDataOptional;
|
import org.kar.archidata.annotation.apiGenerator.ApiTypeScriptProgress;
|
||||||
import org.kar.archidata.annotation.TypeScriptProgress;
|
|
||||||
import org.kar.archidata.dataAccess.DBAccess;
|
import org.kar.archidata.dataAccess.DBAccess;
|
||||||
import org.kar.archidata.dataAccess.DataAccess;
|
import org.kar.archidata.dataAccess.DataAccess;
|
||||||
import org.kar.archidata.dataAccess.addOnSQL.AddOnDataJson;
|
import org.kar.archidata.dataAccess.addOnSQL.AddOnDataJson;
|
||||||
@ -20,11 +19,12 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import jakarta.annotation.security.RolesAllowed;
|
import jakarta.annotation.security.RolesAllowed;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
import jakarta.ws.rs.Consumes;
|
import jakarta.ws.rs.Consumes;
|
||||||
import jakarta.ws.rs.DELETE;
|
import jakarta.ws.rs.DELETE;
|
||||||
import jakarta.ws.rs.GET;
|
import jakarta.ws.rs.GET;
|
||||||
import jakarta.ws.rs.PATCH;
|
|
||||||
import jakarta.ws.rs.POST;
|
import jakarta.ws.rs.POST;
|
||||||
|
import jakarta.ws.rs.PUT;
|
||||||
import jakarta.ws.rs.Path;
|
import jakarta.ws.rs.Path;
|
||||||
import jakarta.ws.rs.PathParam;
|
import jakarta.ws.rs.PathParam;
|
||||||
import jakarta.ws.rs.Produces;
|
import jakarta.ws.rs.Produces;
|
||||||
@ -56,12 +56,13 @@ public class ArtistResource {
|
|||||||
return DataAccess.insert(data, new CheckFunction(CHECKER));
|
return DataAccess.insert(data, new CheckFunction(CHECKER));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PATCH
|
@PUT
|
||||||
@Path("{id}")
|
@Path("{id}")
|
||||||
@RolesAllowed("ADMIN")
|
@RolesAllowed("ADMIN")
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
public Artist patch(@PathParam("id") final Long id, @AsyncType(Artist.class) final String jsonRequest) throws Exception {
|
public Artist patch(@PathParam("id") final Long id, @Valid final Artist jsonRequest) throws Exception {
|
||||||
DataAccess.updateWithJson(Artist.class, id, jsonRequest, new CheckFunction(CHECKER));
|
// new CheckFunction(CHECKER)
|
||||||
|
DataAccess.update(id, jsonRequest);
|
||||||
return DataAccess.get(Artist.class, id);
|
return DataAccess.get(Artist.class, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,9 +77,9 @@ public class ArtistResource {
|
|||||||
@Path("{id}/cover")
|
@Path("{id}/cover")
|
||||||
@RolesAllowed("ADMIN")
|
@RolesAllowed("ADMIN")
|
||||||
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
||||||
@TypeScriptProgress
|
@ApiTypeScriptProgress
|
||||||
public Artist uploadCover(@PathParam("id") final Long id, @FormDataOptional @FormDataParam("uri") final String uri, @FormDataOptional @FormDataParam("file") final InputStream fileInputStream,
|
public Artist uploadCover(@PathParam("id") final Long id, @ApiInputOptional @FormDataParam("uri") final String uri, @ApiInputOptional @FormDataParam("file") final InputStream fileInputStream,
|
||||||
@FormDataOptional @FormDataParam("file") final FormDataContentDisposition fileMetaData) throws Exception {
|
@ApiInputOptional @FormDataParam("file") final FormDataContentDisposition fileMetaData) throws Exception {
|
||||||
try (DBAccess db = DBAccess.createInterface()) {
|
try (DBAccess db = DBAccess.createInterface()) {
|
||||||
if (uri != null) {
|
if (uri != null) {
|
||||||
DataTools.uploadCoverFromUri(db, Artist.class, id, uri);
|
DataTools.uploadCoverFromUri(db, Artist.class, id, uri);
|
||||||
|
@ -6,9 +6,9 @@ import java.util.List;
|
|||||||
import org.bson.types.ObjectId;
|
import org.bson.types.ObjectId;
|
||||||
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
|
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
|
||||||
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.apiGenerator.ApiAsyncType;
|
||||||
import org.kar.archidata.annotation.FormDataOptional;
|
import org.kar.archidata.annotation.apiGenerator.ApiInputOptional;
|
||||||
import org.kar.archidata.annotation.TypeScriptProgress;
|
import org.kar.archidata.annotation.apiGenerator.ApiTypeScriptProgress;
|
||||||
import org.kar.archidata.dataAccess.DBAccess;
|
import org.kar.archidata.dataAccess.DBAccess;
|
||||||
import org.kar.archidata.dataAccess.DataAccess;
|
import org.kar.archidata.dataAccess.DataAccess;
|
||||||
import org.kar.archidata.dataAccess.addOnSQL.AddOnDataJson;
|
import org.kar.archidata.dataAccess.addOnSQL.AddOnDataJson;
|
||||||
@ -60,7 +60,7 @@ public class GenderResource {
|
|||||||
@Path("{id}")
|
@Path("{id}")
|
||||||
@RolesAllowed("ADMIN")
|
@RolesAllowed("ADMIN")
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
public Gender patch(@PathParam("id") final Long id, @AsyncType(Gender.class) final String jsonRequest) throws Exception {
|
public Gender patch(@PathParam("id") final Long id, @ApiAsyncType(Gender.class) final String jsonRequest) throws Exception {
|
||||||
DataAccess.updateWithJson(Gender.class, id, jsonRequest, new CheckFunction(CHECKER));
|
DataAccess.updateWithJson(Gender.class, id, jsonRequest, new CheckFunction(CHECKER));
|
||||||
return DataAccess.get(Gender.class, id);
|
return DataAccess.get(Gender.class, id);
|
||||||
}
|
}
|
||||||
@ -76,9 +76,9 @@ public class GenderResource {
|
|||||||
@Path("{id}/cover")
|
@Path("{id}/cover")
|
||||||
@RolesAllowed("ADMIN")
|
@RolesAllowed("ADMIN")
|
||||||
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
||||||
@TypeScriptProgress
|
@ApiTypeScriptProgress
|
||||||
public Gender uploadCover(@PathParam("id") final Long id, @FormDataOptional @FormDataParam("uri") final String uri, @FormDataOptional @FormDataParam("file") final InputStream fileInputStream,
|
public Gender uploadCover(@PathParam("id") final Long id, @ApiInputOptional @FormDataParam("uri") final String uri, @ApiInputOptional @FormDataParam("file") final InputStream fileInputStream,
|
||||||
@FormDataOptional @FormDataParam("file") final FormDataContentDisposition fileMetaData) throws Exception {
|
@ApiInputOptional @FormDataParam("file") final FormDataContentDisposition fileMetaData) throws Exception {
|
||||||
try (DBAccess db = DBAccess.createInterface()) {
|
try (DBAccess db = DBAccess.createInterface()) {
|
||||||
if (uri != null) {
|
if (uri != null) {
|
||||||
DataTools.uploadCoverFromUri(db, Gender.class, id, uri);
|
DataTools.uploadCoverFromUri(db, Gender.class, id, uri);
|
||||||
|
@ -6,7 +6,7 @@ import java.util.List;
|
|||||||
import org.bson.types.ObjectId;
|
import org.bson.types.ObjectId;
|
||||||
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
|
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
|
||||||
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.apiGenerator.ApiAsyncType;
|
||||||
import org.kar.archidata.dataAccess.DBAccess;
|
import org.kar.archidata.dataAccess.DBAccess;
|
||||||
import org.kar.archidata.dataAccess.DataAccess;
|
import org.kar.archidata.dataAccess.DataAccess;
|
||||||
import org.kar.archidata.dataAccess.addOnSQL.AddOnDataJson;
|
import org.kar.archidata.dataAccess.addOnSQL.AddOnDataJson;
|
||||||
@ -58,7 +58,7 @@ public class PlaylistResource {
|
|||||||
@Path("{id}")
|
@Path("{id}")
|
||||||
@RolesAllowed("ADMIN")
|
@RolesAllowed("ADMIN")
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
public Playlist patch(@PathParam("id") final Long id, @AsyncType(Playlist.class) final String jsonRequest) throws Exception {
|
public Playlist patch(@PathParam("id") final Long id, @ApiAsyncType(Playlist.class) final String jsonRequest) throws Exception {
|
||||||
DataAccess.updateWithJson(Playlist.class, id, jsonRequest, new CheckFunction(CHECKER));
|
DataAccess.updateWithJson(Playlist.class, id, jsonRequest, new CheckFunction(CHECKER));
|
||||||
return DataAccess.get(Playlist.class, id);
|
return DataAccess.get(Playlist.class, id);
|
||||||
}
|
}
|
||||||
@ -95,7 +95,7 @@ public class PlaylistResource {
|
|||||||
@Path("{id}/cover")
|
@Path("{id}/cover")
|
||||||
@RolesAllowed("ADMIN")
|
@RolesAllowed("ADMIN")
|
||||||
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
||||||
@AsyncType(Playlist.class)
|
@ApiAsyncType(Playlist.class)
|
||||||
public void uploadCover(@PathParam("id") final Long id, @FormDataParam("file") final InputStream fileInputStream, @FormDataParam("file") final FormDataContentDisposition fileMetaData)
|
public void uploadCover(@PathParam("id") final Long id, @FormDataParam("file") final InputStream fileInputStream, @FormDataParam("file") final FormDataContentDisposition fileMetaData)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
try (DBAccess db = DBAccess.createInterface()) {
|
try (DBAccess db = DBAccess.createInterface()) {
|
||||||
|
@ -9,9 +9,9 @@ import java.util.List;
|
|||||||
import org.bson.types.ObjectId;
|
import org.bson.types.ObjectId;
|
||||||
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
|
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
|
||||||
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.apiGenerator.ApiAsyncType;
|
||||||
import org.kar.archidata.annotation.FormDataOptional;
|
import org.kar.archidata.annotation.apiGenerator.ApiInputOptional;
|
||||||
import org.kar.archidata.annotation.TypeScriptProgress;
|
import org.kar.archidata.annotation.apiGenerator.ApiTypeScriptProgress;
|
||||||
import org.kar.archidata.dataAccess.DBAccess;
|
import org.kar.archidata.dataAccess.DBAccess;
|
||||||
import org.kar.archidata.dataAccess.DataAccess;
|
import org.kar.archidata.dataAccess.DataAccess;
|
||||||
import org.kar.archidata.dataAccess.addOnSQL.AddOnDataJson;
|
import org.kar.archidata.dataAccess.addOnSQL.AddOnDataJson;
|
||||||
@ -65,7 +65,7 @@ public class TrackResource {
|
|||||||
@Path("{id}")
|
@Path("{id}")
|
||||||
@RolesAllowed("ADMIN")
|
@RolesAllowed("ADMIN")
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
public Track patch(@PathParam("id") final Long id, @AsyncType(Track.class) final String jsonRequest) throws Exception {
|
public Track patch(@PathParam("id") final Long id, @ApiAsyncType(Track.class) final String jsonRequest) throws Exception {
|
||||||
DataAccess.updateWithJson(Track.class, id, jsonRequest, new CheckFunction(CHECKER));
|
DataAccess.updateWithJson(Track.class, id, jsonRequest, new CheckFunction(CHECKER));
|
||||||
return DataAccess.get(Track.class, id);
|
return DataAccess.get(Track.class, id);
|
||||||
}
|
}
|
||||||
@ -102,7 +102,7 @@ public class TrackResource {
|
|||||||
@Path("{id}/cover")
|
@Path("{id}/cover")
|
||||||
@RolesAllowed("ADMIN")
|
@RolesAllowed("ADMIN")
|
||||||
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
||||||
@TypeScriptProgress
|
@ApiTypeScriptProgress
|
||||||
public Track uploadCover(@PathParam("id") final Long id, @FormDataParam("uri") final String uri, @FormDataParam("file") final InputStream fileInputStream,
|
public Track uploadCover(@PathParam("id") final Long id, @FormDataParam("uri") final String uri, @FormDataParam("file") final InputStream fileInputStream,
|
||||||
@FormDataParam("file") final FormDataContentDisposition fileMetaData) throws Exception {
|
@FormDataParam("file") final FormDataContentDisposition fileMetaData) throws Exception {
|
||||||
try (DBAccess db = DBAccess.createInterface()) {
|
try (DBAccess db = DBAccess.createInterface()) {
|
||||||
@ -129,14 +129,14 @@ public class TrackResource {
|
|||||||
@Path("upload/")
|
@Path("upload/")
|
||||||
@RolesAllowed("ADMIN")
|
@RolesAllowed("ADMIN")
|
||||||
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
||||||
@AsyncType(Track.class)
|
@ApiAsyncType(Track.class)
|
||||||
@TypeScriptProgress
|
@ApiTypeScriptProgress
|
||||||
public Response uploadTrack( //
|
public Response uploadTrack( //
|
||||||
@FormDataParam("title") String title, //
|
@FormDataParam("title") String title, //
|
||||||
@FormDataOptional @AsyncType(Long.class) @FormDataParam("genderId") String genderId, //
|
@ApiInputOptional @ApiAsyncType(Long.class) @FormDataParam("genderId") String genderId, //
|
||||||
@FormDataOptional @AsyncType(Long.class) @FormDataParam("artistId") String artistId, //
|
@ApiInputOptional @ApiAsyncType(Long.class) @FormDataParam("artistId") String artistId, //
|
||||||
@FormDataOptional @AsyncType(Long.class) @FormDataParam("albumId") String albumId, //
|
@ApiInputOptional @ApiAsyncType(Long.class) @FormDataParam("albumId") String albumId, //
|
||||||
@FormDataOptional @AsyncType(Long.class) @FormDataParam("trackId") String trackId, //
|
@ApiInputOptional @ApiAsyncType(Long.class) @FormDataParam("trackId") String trackId, //
|
||||||
@FormDataParam("file") final InputStream fileInputStream, //
|
@FormDataParam("file") final InputStream fileInputStream, //
|
||||||
@FormDataParam("file") final FormDataContentDisposition fileMetaData //
|
@FormDataParam("file") final FormDataContentDisposition fileMetaData //
|
||||||
) {
|
) {
|
||||||
|
@ -2,9 +2,6 @@ package org.kar.karusic.api.UserResourceModel;
|
|||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
import org.kar.archidata.annotation.NoWriteSpecificMode;
|
|
||||||
|
|
||||||
@NoWriteSpecificMode
|
|
||||||
public class ModuleAuthorizations extends HashMap<String, PartRight> {
|
public class ModuleAuthorizations extends HashMap<String, PartRight> {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@ -2,11 +2,8 @@ package org.kar.karusic.api.UserResourceModel;
|
|||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.kar.archidata.annotation.NoWriteSpecificMode;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
@NoWriteSpecificMode
|
|
||||||
public class UserMe {
|
public class UserMe {
|
||||||
public long id;
|
public long id;
|
||||||
public String login;
|
public String login;
|
||||||
|
@ -10,6 +10,7 @@ import org.kar.archidata.externalRestApi.TsGenerateApi;
|
|||||||
import org.kar.archidata.migration.MigrationSqlStep;
|
import org.kar.archidata.migration.MigrationSqlStep;
|
||||||
import org.kar.archidata.model.Data;
|
import org.kar.archidata.model.Data;
|
||||||
import org.kar.archidata.model.User;
|
import org.kar.archidata.model.User;
|
||||||
|
import org.kar.archidata.model.token.JwtToken;
|
||||||
import org.kar.karusic.api.AlbumResource;
|
import org.kar.karusic.api.AlbumResource;
|
||||||
import org.kar.karusic.api.ArtistResource;
|
import org.kar.karusic.api.ArtistResource;
|
||||||
import org.kar.karusic.api.Front;
|
import org.kar.karusic.api.Front;
|
||||||
@ -43,6 +44,7 @@ public class Initialization extends MigrationSqlStep {
|
|||||||
TrackResource.class, DataResource.class, ProxyResource.class);
|
TrackResource.class, DataResource.class, ProxyResource.class);
|
||||||
final AnalyzeApi api = new AnalyzeApi();
|
final AnalyzeApi api = new AnalyzeApi();
|
||||||
api.addAllApi(listOfResources);
|
api.addAllApi(listOfResources);
|
||||||
|
api.addModel(JwtToken.class);
|
||||||
TsGenerateApi.generateApi(api, "../front/src/back-api/");
|
TsGenerateApi.generateApi(api, "../front/src/back-api/");
|
||||||
LOGGER.info("Generate APIs (DONE)");
|
LOGGER.info("Generate APIs (DONE)");
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import java.util.List;
|
|||||||
import org.bson.types.ObjectId;
|
import org.bson.types.ObjectId;
|
||||||
import org.kar.archidata.annotation.DataIfNotExists;
|
import org.kar.archidata.annotation.DataIfNotExists;
|
||||||
import org.kar.archidata.annotation.DataJson;
|
import org.kar.archidata.annotation.DataJson;
|
||||||
|
import org.kar.archidata.annotation.apiGenerator.ApiGenerationMode;
|
||||||
import org.kar.archidata.checker.CheckJPA;
|
import org.kar.archidata.checker.CheckJPA;
|
||||||
import org.kar.archidata.model.Data;
|
import org.kar.archidata.model.Data;
|
||||||
import org.kar.archidata.model.GenericDataSoftDelete;
|
import org.kar.archidata.model.GenericDataSoftDelete;
|
||||||
@ -22,6 +23,7 @@ import jakarta.persistence.Table;
|
|||||||
@Table(name = "album")
|
@Table(name = "album")
|
||||||
@DataIfNotExists
|
@DataIfNotExists
|
||||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
@ApiGenerationMode(create = true, update = true)
|
||||||
public class Album extends GenericDataSoftDelete {
|
public class Album extends GenericDataSoftDelete {
|
||||||
public static class AlbumChecker extends CheckJPA<Album> {
|
public static class AlbumChecker extends CheckJPA<Album> {
|
||||||
public AlbumChecker() {
|
public AlbumChecker() {
|
||||||
|
@ -6,6 +6,7 @@ import java.util.List;
|
|||||||
import org.bson.types.ObjectId;
|
import org.bson.types.ObjectId;
|
||||||
import org.kar.archidata.annotation.DataIfNotExists;
|
import org.kar.archidata.annotation.DataIfNotExists;
|
||||||
import org.kar.archidata.annotation.DataJson;
|
import org.kar.archidata.annotation.DataJson;
|
||||||
|
import org.kar.archidata.annotation.apiGenerator.ApiGenerationMode;
|
||||||
import org.kar.archidata.checker.CheckJPA;
|
import org.kar.archidata.checker.CheckJPA;
|
||||||
import org.kar.archidata.model.Data;
|
import org.kar.archidata.model.Data;
|
||||||
import org.kar.archidata.model.GenericDataSoftDelete;
|
import org.kar.archidata.model.GenericDataSoftDelete;
|
||||||
@ -22,6 +23,7 @@ import jakarta.persistence.Table;
|
|||||||
@Table(name = "artist")
|
@Table(name = "artist")
|
||||||
@DataIfNotExists
|
@DataIfNotExists
|
||||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
@ApiGenerationMode(create = true, update = true)
|
||||||
public class Artist extends GenericDataSoftDelete {
|
public class Artist extends GenericDataSoftDelete {
|
||||||
public static class ArtistChecker extends CheckJPA<Artist> {
|
public static class ArtistChecker extends CheckJPA<Artist> {
|
||||||
public ArtistChecker() {
|
public ArtistChecker() {
|
||||||
|
@ -17,6 +17,7 @@ import java.util.List;
|
|||||||
import org.bson.types.ObjectId;
|
import org.bson.types.ObjectId;
|
||||||
import org.kar.archidata.annotation.DataIfNotExists;
|
import org.kar.archidata.annotation.DataIfNotExists;
|
||||||
import org.kar.archidata.annotation.DataJson;
|
import org.kar.archidata.annotation.DataJson;
|
||||||
|
import org.kar.archidata.annotation.apiGenerator.ApiGenerationMode;
|
||||||
import org.kar.archidata.checker.CheckJPA;
|
import org.kar.archidata.checker.CheckJPA;
|
||||||
import org.kar.archidata.model.Data;
|
import org.kar.archidata.model.Data;
|
||||||
import org.kar.archidata.model.GenericDataSoftDelete;
|
import org.kar.archidata.model.GenericDataSoftDelete;
|
||||||
@ -33,6 +34,7 @@ import jakarta.persistence.Table;
|
|||||||
@Table(name = "gender")
|
@Table(name = "gender")
|
||||||
@DataIfNotExists
|
@DataIfNotExists
|
||||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
@ApiGenerationMode(create = true, update = true)
|
||||||
public class Gender extends GenericDataSoftDelete {
|
public class Gender extends GenericDataSoftDelete {
|
||||||
public static class GenderChecker extends CheckJPA<Gender> {
|
public static class GenderChecker extends CheckJPA<Gender> {
|
||||||
public GenderChecker() {
|
public GenderChecker() {
|
||||||
|
@ -17,6 +17,7 @@ import java.util.List;
|
|||||||
import org.bson.types.ObjectId;
|
import org.bson.types.ObjectId;
|
||||||
import org.kar.archidata.annotation.DataIfNotExists;
|
import org.kar.archidata.annotation.DataIfNotExists;
|
||||||
import org.kar.archidata.annotation.DataJson;
|
import org.kar.archidata.annotation.DataJson;
|
||||||
|
import org.kar.archidata.annotation.apiGenerator.ApiGenerationMode;
|
||||||
import org.kar.archidata.checker.CheckJPA;
|
import org.kar.archidata.checker.CheckJPA;
|
||||||
import org.kar.archidata.model.Data;
|
import org.kar.archidata.model.Data;
|
||||||
import org.kar.archidata.model.GenericDataSoftDelete;
|
import org.kar.archidata.model.GenericDataSoftDelete;
|
||||||
@ -35,6 +36,7 @@ import jakarta.persistence.Table;
|
|||||||
@Table(name = "playlist")
|
@Table(name = "playlist")
|
||||||
@DataIfNotExists
|
@DataIfNotExists
|
||||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
@ApiGenerationMode(create = true, update = true)
|
||||||
public class Playlist extends GenericDataSoftDelete {
|
public class Playlist extends GenericDataSoftDelete {
|
||||||
public static class PlaylistChecker extends CheckJPA<Playlist> {
|
public static class PlaylistChecker extends CheckJPA<Playlist> {
|
||||||
public PlaylistChecker() {
|
public PlaylistChecker() {
|
||||||
|
@ -17,6 +17,7 @@ import java.util.List;
|
|||||||
import org.bson.types.ObjectId;
|
import org.bson.types.ObjectId;
|
||||||
import org.kar.archidata.annotation.DataIfNotExists;
|
import org.kar.archidata.annotation.DataIfNotExists;
|
||||||
import org.kar.archidata.annotation.DataJson;
|
import org.kar.archidata.annotation.DataJson;
|
||||||
|
import org.kar.archidata.annotation.apiGenerator.ApiGenerationMode;
|
||||||
import org.kar.archidata.checker.CheckJPA;
|
import org.kar.archidata.checker.CheckJPA;
|
||||||
import org.kar.archidata.model.Data;
|
import org.kar.archidata.model.Data;
|
||||||
import org.kar.archidata.model.GenericDataSoftDelete;
|
import org.kar.archidata.model.GenericDataSoftDelete;
|
||||||
@ -33,6 +34,7 @@ import jakarta.persistence.Table;
|
|||||||
@Table(name = "track")
|
@Table(name = "track")
|
||||||
@DataIfNotExists
|
@DataIfNotExists
|
||||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
@ApiGenerationMode(create = true, update = true)
|
||||||
public class Track extends GenericDataSoftDelete {
|
public class Track extends GenericDataSoftDelete {
|
||||||
|
|
||||||
public static class TrackChecker extends CheckJPA<Track> {
|
public static class TrackChecker extends CheckJPA<Track> {
|
||||||
|
@ -29,63 +29,65 @@
|
|||||||
"*.{ts,tsx,js,jsx,json}": "prettier --write"
|
"*.{ts,tsx,js,jsx,json}": "prettier --write"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"react-speech-recognition": "4.0.0",
|
||||||
|
"regenerator-runtime": "0.14.1",
|
||||||
"@trivago/prettier-plugin-sort-imports": "5.2.2",
|
"@trivago/prettier-plugin-sort-imports": "5.2.2",
|
||||||
"@chakra-ui/cli": "3.7.0",
|
"@chakra-ui/cli": "3.13.0",
|
||||||
"@chakra-ui/react": "3.7.0",
|
"@chakra-ui/react": "3.13.0",
|
||||||
"@emotion/react": "11.14.0",
|
"@emotion/react": "11.14.0",
|
||||||
"allotment": "1.20.2",
|
"allotment": "1.20.3",
|
||||||
"css-mediaquery": "0.1.2",
|
"css-mediaquery": "0.1.2",
|
||||||
"dayjs": "1.11.13",
|
"dayjs": "1.11.13",
|
||||||
"history": "5.3.0",
|
"history": "5.3.0",
|
||||||
"next-themes": "^0.4.4",
|
"next-themes": "^0.4.6",
|
||||||
"react": "19.0.0-rc.1",
|
"react": "19.0.0",
|
||||||
"react-dom": "19.0.0-rc.1",
|
"react-dom": "19.0.0",
|
||||||
"react-error-boundary": "5.0.0",
|
"react-error-boundary": "5.0.0",
|
||||||
"react-icons": "5.4.0",
|
"react-icons": "5.5.0",
|
||||||
"react-router-dom": "7.1.5",
|
"react-router-dom": "7.4.0",
|
||||||
"react-select": "5.10.0",
|
"react-select": "5.10.1",
|
||||||
"react-use": "17.6.0",
|
"react-use": "17.6.0",
|
||||||
"zod": "3.24.1",
|
"zod": "3.24.2",
|
||||||
"zustand": "5.0.3"
|
"zustand": "5.0.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@chakra-ui/styled-system": "^2.12.0",
|
"@chakra-ui/styled-system": "^2.12.0",
|
||||||
"@playwright/test": "1.50.1",
|
"@playwright/test": "1.51.1",
|
||||||
"@storybook/addon-actions": "8.5.4",
|
"@storybook/addon-actions": "8.6.8",
|
||||||
"@storybook/addon-essentials": "8.5.4",
|
"@storybook/addon-essentials": "8.6.8",
|
||||||
"@storybook/addon-links": "8.5.4",
|
"@storybook/addon-links": "8.6.8",
|
||||||
"@storybook/addon-mdx-gfm": "8.5.4",
|
"@storybook/addon-mdx-gfm": "8.6.8",
|
||||||
"@storybook/react": "8.5.4",
|
"@storybook/react": "8.6.8",
|
||||||
"@storybook/react-vite": "8.5.4",
|
"@storybook/react-vite": "8.6.8",
|
||||||
"@storybook/theming": "8.5.4",
|
"@storybook/theming": "8.6.8",
|
||||||
"@testing-library/jest-dom": "6.6.3",
|
"@testing-library/jest-dom": "6.6.3",
|
||||||
"@testing-library/react": "16.2.0",
|
"@testing-library/react": "16.2.0",
|
||||||
"@testing-library/user-event": "14.6.1",
|
"@testing-library/user-event": "14.6.1",
|
||||||
"@trivago/prettier-plugin-sort-imports": "5.2.2",
|
"@trivago/prettier-plugin-sort-imports": "5.2.2",
|
||||||
"@types/jest": "29.5.14",
|
"@types/jest": "29.5.14",
|
||||||
"@types/node": "22.13.1",
|
"@types/node": "22.13.11",
|
||||||
"@types/react": "19.0.8",
|
"@types/react": "19.0.12",
|
||||||
"@types/react-dom": "19.0.3",
|
"@types/react-dom": "19.0.4",
|
||||||
"@typescript-eslint/eslint-plugin": "8.24.0",
|
"@typescript-eslint/eslint-plugin": "8.27.0",
|
||||||
"@typescript-eslint/parser": "8.24.0",
|
"@typescript-eslint/parser": "8.27.0",
|
||||||
"@vitejs/plugin-react": "4.3.4",
|
"@vitejs/plugin-react": "4.3.4",
|
||||||
"eslint": "9.20.1",
|
"eslint": "9.23.0",
|
||||||
"eslint-plugin-import": "2.31.0",
|
"eslint-plugin-import": "2.31.0",
|
||||||
"eslint-plugin-react": "7.37.4",
|
"eslint-plugin-react": "7.37.4",
|
||||||
"eslint-plugin-react-hooks": "5.1.0",
|
"eslint-plugin-react-hooks": "5.2.0",
|
||||||
"eslint-plugin-storybook": "0.11.2",
|
"eslint-plugin-storybook": "0.11.6",
|
||||||
"jest": "29.7.0",
|
"jest": "29.7.0",
|
||||||
"jest-environment-jsdom": "29.7.0",
|
"jest-environment-jsdom": "29.7.0",
|
||||||
"knip": "5.44.0",
|
"knip": "5.46.0",
|
||||||
"lint-staged": "15.4.3",
|
"lint-staged": "15.5.0",
|
||||||
"npm-check-updates": "^17.1.14",
|
"npm-check-updates": "^17.1.16",
|
||||||
"prettier": "3.5.0",
|
"prettier": "3.5.3",
|
||||||
"puppeteer": "24.2.0",
|
"puppeteer": "24.4.0",
|
||||||
"react-is": "19.0.0",
|
"react-is": "19.0.0",
|
||||||
"storybook": "8.5.4",
|
"storybook": "8.6.8",
|
||||||
"ts-node": "10.9.2",
|
"ts-node": "10.9.2",
|
||||||
"typescript": "5.7.3",
|
"typescript": "5.8.2",
|
||||||
"vite": "6.1.0",
|
"vite": "6.2.2",
|
||||||
"vitest": "3.0.5"
|
"vitest": "3.0.9"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
15
front/pnpm-lock.yaml
generated
15
front/pnpm-lock.yaml
generated
@ -53,9 +53,15 @@ importers:
|
|||||||
react-select:
|
react-select:
|
||||||
specifier: 5.10.0
|
specifier: 5.10.0
|
||||||
version: 5.10.0(@types/react@19.0.8)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1)
|
version: 5.10.0(@types/react@19.0.8)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1)
|
||||||
|
react-speech-recognition:
|
||||||
|
specifier: 3.10.0
|
||||||
|
version: 3.10.0(react@19.0.0-rc.1)
|
||||||
react-use:
|
react-use:
|
||||||
specifier: 17.6.0
|
specifier: 17.6.0
|
||||||
version: 17.6.0(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1)
|
version: 17.6.0(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1)
|
||||||
|
regenerator-runtime:
|
||||||
|
specifier: 0.14.1
|
||||||
|
version: 0.14.1
|
||||||
zod:
|
zod:
|
||||||
specifier: 3.24.1
|
specifier: 3.24.1
|
||||||
version: 3.24.1
|
version: 3.24.1
|
||||||
@ -3992,6 +3998,11 @@ packages:
|
|||||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||||
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||||
|
|
||||||
|
react-speech-recognition@3.10.0:
|
||||||
|
resolution: {integrity: sha512-EVSr4Ik8l9urwdPiK2r0+ADrLyDDrjB0qBRdUWO+w2MfwEBrj6NuRmy1GD3x7BU/V6/hab0pl8Lupen0zwlJyw==}
|
||||||
|
peerDependencies:
|
||||||
|
react: '>=16.8.0'
|
||||||
|
|
||||||
react-transition-group@4.4.5:
|
react-transition-group@4.4.5:
|
||||||
resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==}
|
resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -9741,6 +9752,10 @@ snapshots:
|
|||||||
- '@types/react'
|
- '@types/react'
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
|
react-speech-recognition@3.10.0(react@19.0.0-rc.1):
|
||||||
|
dependencies:
|
||||||
|
react: 19.0.0-rc.1
|
||||||
|
|
||||||
react-transition-group@4.4.5(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1):
|
react-transition-group@4.4.5(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/runtime': 7.26.7
|
'@babel/runtime': 7.26.7
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
import { ErrorBoundary } from '@/errors/ErrorBoundary';
|
import { ErrorBoundary } from '@/errors/ErrorBoundary';
|
||||||
|
|
||||||
import { AudioPlayer } from './components';
|
import { AudioPlayer } from './components';
|
||||||
@ -6,6 +8,19 @@ import { AppRoutes } from './scene/AppRoutes';
|
|||||||
import { ServiceContextProvider } from './service/ServiceContext';
|
import { ServiceContextProvider } from './service/ServiceContext';
|
||||||
|
|
||||||
export const App = () => {
|
export const App = () => {
|
||||||
|
// Prevent reload the page when scroll on mobile
|
||||||
|
useEffect(() => {
|
||||||
|
const preventRefresh = (event: { preventDefault: () => void }) => {
|
||||||
|
if (window.scrollY === 0) {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
document.addEventListener('touchmove', preventRefresh, { passive: false });
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener('touchmove', preventRefresh);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ServiceContextProvider>
|
<ServiceContextProvider>
|
||||||
<EnvDevelopment />
|
<EnvDevelopment />
|
||||||
|
@ -13,7 +13,8 @@ import {
|
|||||||
import { z as zod } from "zod"
|
import { z as zod } from "zod"
|
||||||
import {
|
import {
|
||||||
Album,
|
Album,
|
||||||
AlbumWrite,
|
AlbumCreate,
|
||||||
|
AlbumUpdate,
|
||||||
Long,
|
Long,
|
||||||
UUID,
|
UUID,
|
||||||
ZodAlbum,
|
ZodAlbum,
|
||||||
@ -87,7 +88,7 @@ export namespace AlbumResource {
|
|||||||
params: {
|
params: {
|
||||||
id: Long,
|
id: Long,
|
||||||
},
|
},
|
||||||
data: AlbumWrite,
|
data: Partial<AlbumUpdate>,
|
||||||
}): Promise<Album> {
|
}): Promise<Album> {
|
||||||
return RESTRequestJson({
|
return RESTRequestJson({
|
||||||
restModel: {
|
restModel: {
|
||||||
@ -109,7 +110,7 @@ export namespace AlbumResource {
|
|||||||
data,
|
data,
|
||||||
}: {
|
}: {
|
||||||
restConfig: RESTConfig,
|
restConfig: RESTConfig,
|
||||||
data: AlbumWrite,
|
data: AlbumCreate,
|
||||||
}): Promise<Album> {
|
}): Promise<Album> {
|
||||||
return RESTRequestJson({
|
return RESTRequestJson({
|
||||||
restModel: {
|
restModel: {
|
||||||
|
@ -13,7 +13,8 @@ import {
|
|||||||
import { z as zod } from "zod"
|
import { z as zod } from "zod"
|
||||||
import {
|
import {
|
||||||
Artist,
|
Artist,
|
||||||
ArtistWrite,
|
ArtistCreate,
|
||||||
|
ArtistUpdate,
|
||||||
Long,
|
Long,
|
||||||
ObjectId,
|
ObjectId,
|
||||||
ZodArtist,
|
ZodArtist,
|
||||||
@ -78,12 +79,12 @@ export namespace ArtistResource {
|
|||||||
params: {
|
params: {
|
||||||
id: Long,
|
id: Long,
|
||||||
},
|
},
|
||||||
data: ArtistWrite,
|
data: ArtistUpdate,
|
||||||
}): Promise<Artist> {
|
}): Promise<Artist> {
|
||||||
return RESTRequestJson({
|
return RESTRequestJson({
|
||||||
restModel: {
|
restModel: {
|
||||||
endPoint: "/artist/{id}",
|
endPoint: "/artist/{id}",
|
||||||
requestType: HTTPRequestModel.PATCH,
|
requestType: HTTPRequestModel.PUT,
|
||||||
contentType: HTTPMimeType.JSON,
|
contentType: HTTPMimeType.JSON,
|
||||||
accept: HTTPMimeType.JSON,
|
accept: HTTPMimeType.JSON,
|
||||||
},
|
},
|
||||||
@ -97,7 +98,7 @@ export namespace ArtistResource {
|
|||||||
data,
|
data,
|
||||||
}: {
|
}: {
|
||||||
restConfig: RESTConfig,
|
restConfig: RESTConfig,
|
||||||
data: ArtistWrite,
|
data: ArtistCreate,
|
||||||
}): Promise<Artist> {
|
}): Promise<Artist> {
|
||||||
return RESTRequestJson({
|
return RESTRequestJson({
|
||||||
restModel: {
|
restModel: {
|
||||||
|
@ -22,7 +22,7 @@ export namespace DataResource {
|
|||||||
restConfig,
|
restConfig,
|
||||||
queries,
|
queries,
|
||||||
params,
|
params,
|
||||||
data,
|
headers,
|
||||||
}: {
|
}: {
|
||||||
restConfig: RESTConfig,
|
restConfig: RESTConfig,
|
||||||
queries: {
|
queries: {
|
||||||
@ -32,7 +32,9 @@ export namespace DataResource {
|
|||||||
name: string,
|
name: string,
|
||||||
oid: ObjectId,
|
oid: ObjectId,
|
||||||
},
|
},
|
||||||
data: string,
|
headers?: {
|
||||||
|
Range?: string,
|
||||||
|
},
|
||||||
}): Promise<object> {
|
}): Promise<object> {
|
||||||
return RESTRequestJson({
|
return RESTRequestJson({
|
||||||
restModel: {
|
restModel: {
|
||||||
@ -42,7 +44,7 @@ export namespace DataResource {
|
|||||||
restConfig,
|
restConfig,
|
||||||
params,
|
params,
|
||||||
queries,
|
queries,
|
||||||
data,
|
headers,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
@ -52,7 +54,7 @@ export namespace DataResource {
|
|||||||
restConfig,
|
restConfig,
|
||||||
queries,
|
queries,
|
||||||
params,
|
params,
|
||||||
data,
|
headers,
|
||||||
}: {
|
}: {
|
||||||
restConfig: RESTConfig,
|
restConfig: RESTConfig,
|
||||||
queries: {
|
queries: {
|
||||||
@ -61,7 +63,9 @@ export namespace DataResource {
|
|||||||
params: {
|
params: {
|
||||||
oid: ObjectId,
|
oid: ObjectId,
|
||||||
},
|
},
|
||||||
data: string,
|
headers?: {
|
||||||
|
Range: string,
|
||||||
|
},
|
||||||
}): Promise<object> {
|
}): Promise<object> {
|
||||||
return RESTRequestJson({
|
return RESTRequestJson({
|
||||||
restModel: {
|
restModel: {
|
||||||
@ -71,7 +75,7 @@ export namespace DataResource {
|
|||||||
restConfig,
|
restConfig,
|
||||||
params,
|
params,
|
||||||
queries,
|
queries,
|
||||||
data,
|
headers,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
@ -81,7 +85,7 @@ export namespace DataResource {
|
|||||||
restConfig,
|
restConfig,
|
||||||
queries,
|
queries,
|
||||||
params,
|
params,
|
||||||
data,
|
headers,
|
||||||
}: {
|
}: {
|
||||||
restConfig: RESTConfig,
|
restConfig: RESTConfig,
|
||||||
queries: {
|
queries: {
|
||||||
@ -90,7 +94,9 @@ export namespace DataResource {
|
|||||||
params: {
|
params: {
|
||||||
oid: ObjectId,
|
oid: ObjectId,
|
||||||
},
|
},
|
||||||
data: string,
|
headers?: {
|
||||||
|
Range: string,
|
||||||
|
},
|
||||||
}): Promise<object> {
|
}): Promise<object> {
|
||||||
return RESTRequestJson({
|
return RESTRequestJson({
|
||||||
restModel: {
|
restModel: {
|
||||||
@ -100,7 +106,7 @@ export namespace DataResource {
|
|||||||
restConfig,
|
restConfig,
|
||||||
params,
|
params,
|
||||||
queries,
|
queries,
|
||||||
data,
|
headers,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
|
@ -13,7 +13,8 @@ import {
|
|||||||
import { z as zod } from "zod"
|
import { z as zod } from "zod"
|
||||||
import {
|
import {
|
||||||
Gender,
|
Gender,
|
||||||
GenderWrite,
|
GenderCreate,
|
||||||
|
GenderUpdate,
|
||||||
Long,
|
Long,
|
||||||
ObjectId,
|
ObjectId,
|
||||||
ZodGender,
|
ZodGender,
|
||||||
@ -78,7 +79,7 @@ export namespace GenderResource {
|
|||||||
params: {
|
params: {
|
||||||
id: Long,
|
id: Long,
|
||||||
},
|
},
|
||||||
data: GenderWrite,
|
data: Partial<GenderUpdate>,
|
||||||
}): Promise<Gender> {
|
}): Promise<Gender> {
|
||||||
return RESTRequestJson({
|
return RESTRequestJson({
|
||||||
restModel: {
|
restModel: {
|
||||||
@ -97,7 +98,7 @@ export namespace GenderResource {
|
|||||||
data,
|
data,
|
||||||
}: {
|
}: {
|
||||||
restConfig: RESTConfig,
|
restConfig: RESTConfig,
|
||||||
data: GenderWrite,
|
data: GenderCreate,
|
||||||
}): Promise<Gender> {
|
}): Promise<Gender> {
|
||||||
return RESTRequestJson({
|
return RESTRequestJson({
|
||||||
restModel: {
|
restModel: {
|
||||||
|
@ -14,7 +14,8 @@ import {
|
|||||||
Long,
|
Long,
|
||||||
ObjectId,
|
ObjectId,
|
||||||
Playlist,
|
Playlist,
|
||||||
PlaylistWrite,
|
PlaylistCreate,
|
||||||
|
PlaylistUpdate,
|
||||||
ZodPlaylist,
|
ZodPlaylist,
|
||||||
isPlaylist,
|
isPlaylist,
|
||||||
} from "../model";
|
} from "../model";
|
||||||
@ -98,7 +99,7 @@ export namespace PlaylistResource {
|
|||||||
params: {
|
params: {
|
||||||
id: Long,
|
id: Long,
|
||||||
},
|
},
|
||||||
data: PlaylistWrite,
|
data: Partial<PlaylistUpdate>,
|
||||||
}): Promise<Playlist> {
|
}): Promise<Playlist> {
|
||||||
return RESTRequestJson({
|
return RESTRequestJson({
|
||||||
restModel: {
|
restModel: {
|
||||||
@ -117,7 +118,7 @@ export namespace PlaylistResource {
|
|||||||
data,
|
data,
|
||||||
}: {
|
}: {
|
||||||
restConfig: RESTConfig,
|
restConfig: RESTConfig,
|
||||||
data: PlaylistWrite,
|
data: PlaylistCreate,
|
||||||
}): Promise<Playlist> {
|
}): Promise<Playlist> {
|
||||||
return RESTRequestJson({
|
return RESTRequestJson({
|
||||||
restModel: {
|
restModel: {
|
||||||
|
@ -15,7 +15,8 @@ import {
|
|||||||
Long,
|
Long,
|
||||||
ObjectId,
|
ObjectId,
|
||||||
Track,
|
Track,
|
||||||
TrackWrite,
|
TrackCreate,
|
||||||
|
TrackUpdate,
|
||||||
ZodTrack,
|
ZodTrack,
|
||||||
isTrack,
|
isTrack,
|
||||||
} from "../model";
|
} from "../model";
|
||||||
@ -99,7 +100,7 @@ export namespace TrackResource {
|
|||||||
params: {
|
params: {
|
||||||
id: Long,
|
id: Long,
|
||||||
},
|
},
|
||||||
data: TrackWrite,
|
data: Partial<TrackUpdate>,
|
||||||
}): Promise<Track> {
|
}): Promise<Track> {
|
||||||
return RESTRequestJson({
|
return RESTRequestJson({
|
||||||
restModel: {
|
restModel: {
|
||||||
@ -118,7 +119,7 @@ export namespace TrackResource {
|
|||||||
data,
|
data,
|
||||||
}: {
|
}: {
|
||||||
restConfig: RESTConfig,
|
restConfig: RESTConfig,
|
||||||
data: TrackWrite,
|
data: TrackCreate,
|
||||||
}): Promise<Track> {
|
}): Promise<Track> {
|
||||||
return RESTRequestJson({
|
return RESTRequestJson({
|
||||||
restModel: {
|
restModel: {
|
||||||
|
@ -5,7 +5,7 @@ import { z as zod } from "zod";
|
|||||||
|
|
||||||
import {ZodObjectId} from "./object-id";
|
import {ZodObjectId} from "./object-id";
|
||||||
import {ZodLocalDate} from "./local-date";
|
import {ZodLocalDate} from "./local-date";
|
||||||
import {ZodGenericDataSoftDelete, ZodGenericDataSoftDeleteWrite } from "./generic-data-soft-delete";
|
import {ZodGenericDataSoftDelete, ZodGenericDataSoftDeleteUpdate , ZodGenericDataSoftDeleteCreate } from "./generic-data-soft-delete";
|
||||||
|
|
||||||
export const ZodAlbum = ZodGenericDataSoftDelete.extend({
|
export const ZodAlbum = ZodGenericDataSoftDelete.extend({
|
||||||
name: zod.string().optional(),
|
name: zod.string().optional(),
|
||||||
@ -29,7 +29,7 @@ export function isAlbum(data: any): data is Album {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export const ZodAlbumWrite = ZodGenericDataSoftDeleteWrite.extend({
|
export const ZodAlbumUpdate = ZodGenericDataSoftDeleteUpdate.extend({
|
||||||
name: zod.string().nullable().optional(),
|
name: zod.string().nullable().optional(),
|
||||||
description: zod.string().nullable().optional(),
|
description: zod.string().nullable().optional(),
|
||||||
/**
|
/**
|
||||||
@ -40,14 +40,36 @@ export const ZodAlbumWrite = ZodGenericDataSoftDeleteWrite.extend({
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export type AlbumWrite = zod.infer<typeof ZodAlbumWrite>;
|
export type AlbumUpdate = zod.infer<typeof ZodAlbumUpdate>;
|
||||||
|
|
||||||
export function isAlbumWrite(data: any): data is AlbumWrite {
|
export function isAlbumUpdate(data: any): data is AlbumUpdate {
|
||||||
try {
|
try {
|
||||||
ZodAlbumWrite.parse(data);
|
ZodAlbumUpdate.parse(data);
|
||||||
return true;
|
return true;
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
console.log(`Fail to parse data type='ZodAlbumWrite' error=${e}`);
|
console.log(`Fail to parse data type='ZodAlbumUpdate' error=${e}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export const ZodAlbumCreate = ZodGenericDataSoftDeleteCreate.extend({
|
||||||
|
name: zod.string().nullable().optional(),
|
||||||
|
description: zod.string().nullable().optional(),
|
||||||
|
/**
|
||||||
|
* List of Id of the specific covers
|
||||||
|
*/
|
||||||
|
covers: zod.array(ZodObjectId).nullable().optional(),
|
||||||
|
publication: ZodLocalDate.nullable().optional(),
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
export type AlbumCreate = zod.infer<typeof ZodAlbumCreate>;
|
||||||
|
|
||||||
|
export function isAlbumCreate(data: any): data is AlbumCreate {
|
||||||
|
try {
|
||||||
|
ZodAlbumCreate.parse(data);
|
||||||
|
return true;
|
||||||
|
} catch (e: any) {
|
||||||
|
console.log(`Fail to parse data type='ZodAlbumCreate' error=${e}`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import { z as zod } from "zod";
|
|||||||
|
|
||||||
import {ZodObjectId} from "./object-id";
|
import {ZodObjectId} from "./object-id";
|
||||||
import {ZodLocalDate} from "./local-date";
|
import {ZodLocalDate} from "./local-date";
|
||||||
import {ZodGenericDataSoftDelete, ZodGenericDataSoftDeleteWrite } from "./generic-data-soft-delete";
|
import {ZodGenericDataSoftDelete, ZodGenericDataSoftDeleteUpdate , ZodGenericDataSoftDeleteCreate } from "./generic-data-soft-delete";
|
||||||
|
|
||||||
export const ZodArtist = ZodGenericDataSoftDelete.extend({
|
export const ZodArtist = ZodGenericDataSoftDelete.extend({
|
||||||
name: zod.string().optional(),
|
name: zod.string().optional(),
|
||||||
@ -32,7 +32,7 @@ export function isArtist(data: any): data is Artist {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export const ZodArtistWrite = ZodGenericDataSoftDeleteWrite.extend({
|
export const ZodArtistUpdate = ZodGenericDataSoftDeleteUpdate.extend({
|
||||||
name: zod.string().nullable().optional(),
|
name: zod.string().nullable().optional(),
|
||||||
description: zod.string().nullable().optional(),
|
description: zod.string().nullable().optional(),
|
||||||
/**
|
/**
|
||||||
@ -46,14 +46,39 @@ export const ZodArtistWrite = ZodGenericDataSoftDeleteWrite.extend({
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export type ArtistWrite = zod.infer<typeof ZodArtistWrite>;
|
export type ArtistUpdate = zod.infer<typeof ZodArtistUpdate>;
|
||||||
|
|
||||||
export function isArtistWrite(data: any): data is ArtistWrite {
|
export function isArtistUpdate(data: any): data is ArtistUpdate {
|
||||||
try {
|
try {
|
||||||
ZodArtistWrite.parse(data);
|
ZodArtistUpdate.parse(data);
|
||||||
return true;
|
return true;
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
console.log(`Fail to parse data type='ZodArtistWrite' error=${e}`);
|
console.log(`Fail to parse data type='ZodArtistUpdate' error=${e}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export const ZodArtistCreate = ZodGenericDataSoftDeleteCreate.extend({
|
||||||
|
name: zod.string().nullable().optional(),
|
||||||
|
description: zod.string().nullable().optional(),
|
||||||
|
/**
|
||||||
|
* List of Id of the specific covers
|
||||||
|
*/
|
||||||
|
covers: zod.array(ZodObjectId).nullable().optional(),
|
||||||
|
firstName: zod.string().nullable().optional(),
|
||||||
|
surname: zod.string().nullable().optional(),
|
||||||
|
birth: ZodLocalDate.nullable().optional(),
|
||||||
|
death: ZodLocalDate.nullable().optional(),
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
export type ArtistCreate = zod.infer<typeof ZodArtistCreate>;
|
||||||
|
|
||||||
|
export function isArtistCreate(data: any): data is ArtistCreate {
|
||||||
|
try {
|
||||||
|
ZodArtistCreate.parse(data);
|
||||||
|
return true;
|
||||||
|
} catch (e: any) {
|
||||||
|
console.log(`Fail to parse data type='ZodArtistCreate' error=${e}`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
import { z as zod } from "zod";
|
import { z as zod } from "zod";
|
||||||
|
|
||||||
import {ZodObjectId} from "./object-id";
|
import {ZodObjectId} from "./object-id";
|
||||||
import {ZodGenericDataSoftDelete, ZodGenericDataSoftDeleteWrite } from "./generic-data-soft-delete";
|
import {ZodGenericDataSoftDelete, ZodGenericDataSoftDeleteUpdate , ZodGenericDataSoftDeleteCreate } from "./generic-data-soft-delete";
|
||||||
|
|
||||||
export const ZodGender = ZodGenericDataSoftDelete.extend({
|
export const ZodGender = ZodGenericDataSoftDelete.extend({
|
||||||
name: zod.string().optional(),
|
name: zod.string().optional(),
|
||||||
@ -27,7 +27,7 @@ export function isGender(data: any): data is Gender {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export const ZodGenderWrite = ZodGenericDataSoftDeleteWrite.extend({
|
export const ZodGenderUpdate = ZodGenericDataSoftDeleteUpdate.extend({
|
||||||
name: zod.string().nullable().optional(),
|
name: zod.string().nullable().optional(),
|
||||||
description: zod.string().nullable().optional(),
|
description: zod.string().nullable().optional(),
|
||||||
/**
|
/**
|
||||||
@ -37,14 +37,35 @@ export const ZodGenderWrite = ZodGenericDataSoftDeleteWrite.extend({
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export type GenderWrite = zod.infer<typeof ZodGenderWrite>;
|
export type GenderUpdate = zod.infer<typeof ZodGenderUpdate>;
|
||||||
|
|
||||||
export function isGenderWrite(data: any): data is GenderWrite {
|
export function isGenderUpdate(data: any): data is GenderUpdate {
|
||||||
try {
|
try {
|
||||||
ZodGenderWrite.parse(data);
|
ZodGenderUpdate.parse(data);
|
||||||
return true;
|
return true;
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
console.log(`Fail to parse data type='ZodGenderWrite' error=${e}`);
|
console.log(`Fail to parse data type='ZodGenderUpdate' error=${e}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export const ZodGenderCreate = ZodGenericDataSoftDeleteCreate.extend({
|
||||||
|
name: zod.string().nullable().optional(),
|
||||||
|
description: zod.string().nullable().optional(),
|
||||||
|
/**
|
||||||
|
* List of Id of the specific covers
|
||||||
|
*/
|
||||||
|
covers: zod.array(ZodObjectId).nullable().optional(),
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
export type GenderCreate = zod.infer<typeof ZodGenderCreate>;
|
||||||
|
|
||||||
|
export function isGenderCreate(data: any): data is GenderCreate {
|
||||||
|
try {
|
||||||
|
ZodGenderCreate.parse(data);
|
||||||
|
return true;
|
||||||
|
} catch (e: any) {
|
||||||
|
console.log(`Fail to parse data type='ZodGenderCreate' error=${e}`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
import { z as zod } from "zod";
|
import { z as zod } from "zod";
|
||||||
|
|
||||||
import {ZodGenericData, ZodGenericDataWrite } from "./generic-data";
|
import {ZodGenericData, ZodGenericDataUpdate , ZodGenericDataCreate } from "./generic-data";
|
||||||
|
|
||||||
export const ZodGenericDataSoftDelete = ZodGenericData.extend({
|
export const ZodGenericDataSoftDelete = ZodGenericData.extend({
|
||||||
/**
|
/**
|
||||||
@ -24,16 +24,29 @@ export function isGenericDataSoftDelete(data: any): data is GenericDataSoftDelet
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export const ZodGenericDataSoftDeleteWrite = ZodGenericDataWrite;
|
export const ZodGenericDataSoftDeleteUpdate = ZodGenericDataUpdate;
|
||||||
|
|
||||||
export type GenericDataSoftDeleteWrite = zod.infer<typeof ZodGenericDataSoftDeleteWrite>;
|
export type GenericDataSoftDeleteUpdate = zod.infer<typeof ZodGenericDataSoftDeleteUpdate>;
|
||||||
|
|
||||||
export function isGenericDataSoftDeleteWrite(data: any): data is GenericDataSoftDeleteWrite {
|
export function isGenericDataSoftDeleteUpdate(data: any): data is GenericDataSoftDeleteUpdate {
|
||||||
try {
|
try {
|
||||||
ZodGenericDataSoftDeleteWrite.parse(data);
|
ZodGenericDataSoftDeleteUpdate.parse(data);
|
||||||
return true;
|
return true;
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
console.log(`Fail to parse data type='ZodGenericDataSoftDeleteWrite' error=${e}`);
|
console.log(`Fail to parse data type='ZodGenericDataSoftDeleteUpdate' error=${e}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export const ZodGenericDataSoftDeleteCreate = ZodGenericDataCreate;
|
||||||
|
|
||||||
|
export type GenericDataSoftDeleteCreate = zod.infer<typeof ZodGenericDataSoftDeleteCreate>;
|
||||||
|
|
||||||
|
export function isGenericDataSoftDeleteCreate(data: any): data is GenericDataSoftDeleteCreate {
|
||||||
|
try {
|
||||||
|
ZodGenericDataSoftDeleteCreate.parse(data);
|
||||||
|
return true;
|
||||||
|
} catch (e: any) {
|
||||||
|
console.log(`Fail to parse data type='ZodGenericDataSoftDeleteCreate' error=${e}`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
import { z as zod } from "zod";
|
import { z as zod } from "zod";
|
||||||
|
|
||||||
import {ZodLong} from "./long";
|
import {ZodLong} from "./long";
|
||||||
import {ZodGenericTiming, ZodGenericTimingWrite } from "./generic-timing";
|
import {ZodGenericTiming, ZodGenericTimingUpdate , ZodGenericTimingCreate } from "./generic-timing";
|
||||||
|
|
||||||
export const ZodGenericData = ZodGenericTiming.extend({
|
export const ZodGenericData = ZodGenericTiming.extend({
|
||||||
/**
|
/**
|
||||||
@ -25,16 +25,29 @@ export function isGenericData(data: any): data is GenericData {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export const ZodGenericDataWrite = ZodGenericTimingWrite;
|
export const ZodGenericDataUpdate = ZodGenericTimingUpdate;
|
||||||
|
|
||||||
export type GenericDataWrite = zod.infer<typeof ZodGenericDataWrite>;
|
export type GenericDataUpdate = zod.infer<typeof ZodGenericDataUpdate>;
|
||||||
|
|
||||||
export function isGenericDataWrite(data: any): data is GenericDataWrite {
|
export function isGenericDataUpdate(data: any): data is GenericDataUpdate {
|
||||||
try {
|
try {
|
||||||
ZodGenericDataWrite.parse(data);
|
ZodGenericDataUpdate.parse(data);
|
||||||
return true;
|
return true;
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
console.log(`Fail to parse data type='ZodGenericDataWrite' error=${e}`);
|
console.log(`Fail to parse data type='ZodGenericDataUpdate' error=${e}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export const ZodGenericDataCreate = ZodGenericTimingCreate;
|
||||||
|
|
||||||
|
export type GenericDataCreate = zod.infer<typeof ZodGenericDataCreate>;
|
||||||
|
|
||||||
|
export function isGenericDataCreate(data: any): data is GenericDataCreate {
|
||||||
|
try {
|
||||||
|
ZodGenericDataCreate.parse(data);
|
||||||
|
return true;
|
||||||
|
} catch (e: any) {
|
||||||
|
console.log(`Fail to parse data type='ZodGenericDataCreate' error=${e}`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,18 +28,33 @@ export function isGenericTiming(data: any): data is GenericTiming {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export const ZodGenericTimingWrite = zod.object({
|
export const ZodGenericTimingUpdate = zod.object({
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export type GenericTimingWrite = zod.infer<typeof ZodGenericTimingWrite>;
|
export type GenericTimingUpdate = zod.infer<typeof ZodGenericTimingUpdate>;
|
||||||
|
|
||||||
export function isGenericTimingWrite(data: any): data is GenericTimingWrite {
|
export function isGenericTimingUpdate(data: any): data is GenericTimingUpdate {
|
||||||
try {
|
try {
|
||||||
ZodGenericTimingWrite.parse(data);
|
ZodGenericTimingUpdate.parse(data);
|
||||||
return true;
|
return true;
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
console.log(`Fail to parse data type='ZodGenericTimingWrite' error=${e}`);
|
console.log(`Fail to parse data type='ZodGenericTimingUpdate' error=${e}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export const ZodGenericTimingCreate = zod.object({
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
export type GenericTimingCreate = zod.infer<typeof ZodGenericTimingCreate>;
|
||||||
|
|
||||||
|
export function isGenericTimingCreate(data: any): data is GenericTimingCreate {
|
||||||
|
try {
|
||||||
|
ZodGenericTimingCreate.parse(data);
|
||||||
|
return true;
|
||||||
|
} catch (e: any) {
|
||||||
|
console.log(`Fail to parse data type='ZodGenericTimingCreate' error=${e}`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,18 +19,3 @@ export function isHealthResult(data: any): data is HealthResult {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export const ZodHealthResultWrite = zod.object({
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
export type HealthResultWrite = zod.infer<typeof ZodHealthResultWrite>;
|
|
||||||
|
|
||||||
export function isHealthResultWrite(data: any): data is HealthResultWrite {
|
|
||||||
try {
|
|
||||||
ZodHealthResultWrite.parse(data);
|
|
||||||
return true;
|
|
||||||
} catch (e: any) {
|
|
||||||
console.log(`Fail to parse data type='ZodHealthResultWrite' error=${e}`);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -10,12 +10,16 @@ export * from "./generic-timing"
|
|||||||
export * from "./health-result"
|
export * from "./health-result"
|
||||||
export * from "./integer"
|
export * from "./integer"
|
||||||
export * from "./iso-date"
|
export * from "./iso-date"
|
||||||
|
export * from "./jwt-header"
|
||||||
|
export * from "./jwt-payload"
|
||||||
|
export * from "./jwt-token"
|
||||||
export * from "./local-date"
|
export * from "./local-date"
|
||||||
export * from "./long"
|
export * from "./long"
|
||||||
export * from "./object-id"
|
export * from "./object-id"
|
||||||
export * from "./part-right"
|
export * from "./part-right"
|
||||||
export * from "./playlist"
|
export * from "./playlist"
|
||||||
export * from "./rest-error-response"
|
export * from "./rest-error-response"
|
||||||
|
export * from "./rest-input-error"
|
||||||
export * from "./timestamp"
|
export * from "./timestamp"
|
||||||
export * from "./track"
|
export * from "./track"
|
||||||
export * from "./user"
|
export * from "./user"
|
||||||
|
23
front/src/back-api/model/jwt-header.ts
Normal file
23
front/src/back-api/model/jwt-header.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* Interface of the server (auto-generated code)
|
||||||
|
*/
|
||||||
|
import { z as zod } from "zod";
|
||||||
|
|
||||||
|
|
||||||
|
export const ZodJwtHeader = zod.object({
|
||||||
|
typ: zod.string().max(128),
|
||||||
|
alg: zod.string().max(128),
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
export type JwtHeader = zod.infer<typeof ZodJwtHeader>;
|
||||||
|
|
||||||
|
export function isJwtHeader(data: any): data is JwtHeader {
|
||||||
|
try {
|
||||||
|
ZodJwtHeader.parse(data);
|
||||||
|
return true;
|
||||||
|
} catch (e: any) {
|
||||||
|
console.log(`Fail to parse data type='ZodJwtHeader' error=${e}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
29
front/src/back-api/model/jwt-payload.ts
Normal file
29
front/src/back-api/model/jwt-payload.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
* Interface of the server (auto-generated code)
|
||||||
|
*/
|
||||||
|
import { z as zod } from "zod";
|
||||||
|
|
||||||
|
import {ZodLong} from "./long";
|
||||||
|
|
||||||
|
export const ZodJwtPayload = zod.object({
|
||||||
|
sub: zod.string(),
|
||||||
|
application: zod.string(),
|
||||||
|
iss: zod.string(),
|
||||||
|
right: zod.record(zod.string(), zod.record(zod.string(), ZodLong)),
|
||||||
|
login: zod.string(),
|
||||||
|
exp: ZodLong,
|
||||||
|
iat: ZodLong,
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
export type JwtPayload = zod.infer<typeof ZodJwtPayload>;
|
||||||
|
|
||||||
|
export function isJwtPayload(data: any): data is JwtPayload {
|
||||||
|
try {
|
||||||
|
ZodJwtPayload.parse(data);
|
||||||
|
return true;
|
||||||
|
} catch (e: any) {
|
||||||
|
console.log(`Fail to parse data type='ZodJwtPayload' error=${e}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
26
front/src/back-api/model/jwt-token.ts
Normal file
26
front/src/back-api/model/jwt-token.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/**
|
||||||
|
* Interface of the server (auto-generated code)
|
||||||
|
*/
|
||||||
|
import { z as zod } from "zod";
|
||||||
|
|
||||||
|
import {ZodJwtHeader} from "./jwt-header";
|
||||||
|
import {ZodJwtPayload} from "./jwt-payload";
|
||||||
|
|
||||||
|
export const ZodJwtToken = zod.object({
|
||||||
|
header: ZodJwtHeader,
|
||||||
|
payload: ZodJwtPayload,
|
||||||
|
signature: zod.string(),
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
export type JwtToken = zod.infer<typeof ZodJwtToken>;
|
||||||
|
|
||||||
|
export function isJwtToken(data: any): data is JwtToken {
|
||||||
|
try {
|
||||||
|
ZodJwtToken.parse(data);
|
||||||
|
return true;
|
||||||
|
} catch (e: any) {
|
||||||
|
console.log(`Fail to parse data type='ZodJwtToken' error=${e}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,7 @@
|
|||||||
import { z as zod } from "zod";
|
import { z as zod } from "zod";
|
||||||
|
|
||||||
import {ZodObjectId} from "./object-id";
|
import {ZodObjectId} from "./object-id";
|
||||||
import {ZodGenericDataSoftDelete, ZodGenericDataSoftDeleteWrite } from "./generic-data-soft-delete";
|
import {ZodGenericDataSoftDelete, ZodGenericDataSoftDeleteUpdate , ZodGenericDataSoftDeleteCreate } from "./generic-data-soft-delete";
|
||||||
|
|
||||||
export const ZodPlaylist = ZodGenericDataSoftDelete.extend({
|
export const ZodPlaylist = ZodGenericDataSoftDelete.extend({
|
||||||
name: zod.string().optional(),
|
name: zod.string().optional(),
|
||||||
@ -28,25 +28,47 @@ export function isPlaylist(data: any): data is Playlist {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export const ZodPlaylistWrite = ZodGenericDataSoftDeleteWrite.extend({
|
export const ZodPlaylistUpdate = ZodGenericDataSoftDeleteUpdate.extend({
|
||||||
name: zod.string().nullable().optional(),
|
name: zod.string().nullable().optional(),
|
||||||
description: zod.string().nullable().optional(),
|
description: zod.string().nullable().optional(),
|
||||||
/**
|
/**
|
||||||
* List of Id of the specific covers
|
* List of Id of the specific covers
|
||||||
*/
|
*/
|
||||||
covers: zod.array(ZodObjectId).nullable().optional(),
|
covers: zod.array(ZodObjectId).nullable().optional(),
|
||||||
tracks: zod.array(ZodObjectId).optional(),
|
tracks: zod.array(ZodObjectId),
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export type PlaylistWrite = zod.infer<typeof ZodPlaylistWrite>;
|
export type PlaylistUpdate = zod.infer<typeof ZodPlaylistUpdate>;
|
||||||
|
|
||||||
export function isPlaylistWrite(data: any): data is PlaylistWrite {
|
export function isPlaylistUpdate(data: any): data is PlaylistUpdate {
|
||||||
try {
|
try {
|
||||||
ZodPlaylistWrite.parse(data);
|
ZodPlaylistUpdate.parse(data);
|
||||||
return true;
|
return true;
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
console.log(`Fail to parse data type='ZodPlaylistWrite' error=${e}`);
|
console.log(`Fail to parse data type='ZodPlaylistUpdate' error=${e}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export const ZodPlaylistCreate = ZodGenericDataSoftDeleteCreate.extend({
|
||||||
|
name: zod.string().nullable().optional(),
|
||||||
|
description: zod.string().nullable().optional(),
|
||||||
|
/**
|
||||||
|
* List of Id of the specific covers
|
||||||
|
*/
|
||||||
|
covers: zod.array(ZodObjectId).nullable().optional(),
|
||||||
|
tracks: zod.array(ZodObjectId),
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
export type PlaylistCreate = zod.infer<typeof ZodPlaylistCreate>;
|
||||||
|
|
||||||
|
export function isPlaylistCreate(data: any): data is PlaylistCreate {
|
||||||
|
try {
|
||||||
|
ZodPlaylistCreate.parse(data);
|
||||||
|
return true;
|
||||||
|
} catch (e: any) {
|
||||||
|
console.log(`Fail to parse data type='ZodPlaylistCreate' error=${e}`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import { z as zod } from "zod";
|
|||||||
|
|
||||||
import {ZodObjectId} from "./object-id";
|
import {ZodObjectId} from "./object-id";
|
||||||
import {ZodInteger} from "./integer";
|
import {ZodInteger} from "./integer";
|
||||||
|
import {ZodRestInputError} from "./rest-input-error";
|
||||||
|
|
||||||
export const ZodRestErrorResponse = zod.object({
|
export const ZodRestErrorResponse = zod.object({
|
||||||
oid: ZodObjectId.optional(),
|
oid: ZodObjectId.optional(),
|
||||||
@ -13,6 +14,7 @@ export const ZodRestErrorResponse = zod.object({
|
|||||||
time: zod.string(),
|
time: zod.string(),
|
||||||
status: ZodInteger,
|
status: ZodInteger,
|
||||||
statusMessage: zod.string(),
|
statusMessage: zod.string(),
|
||||||
|
inputError: zod.array(ZodRestInputError).optional(),
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
24
front/src/back-api/model/rest-input-error.ts
Normal file
24
front/src/back-api/model/rest-input-error.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/**
|
||||||
|
* Interface of the server (auto-generated code)
|
||||||
|
*/
|
||||||
|
import { z as zod } from "zod";
|
||||||
|
|
||||||
|
|
||||||
|
export const ZodRestInputError = zod.object({
|
||||||
|
argument: zod.string().optional(),
|
||||||
|
path: zod.string().optional(),
|
||||||
|
message: zod.string(),
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
export type RestInputError = zod.infer<typeof ZodRestInputError>;
|
||||||
|
|
||||||
|
export function isRestInputError(data: any): data is RestInputError {
|
||||||
|
try {
|
||||||
|
ZodRestInputError.parse(data);
|
||||||
|
return true;
|
||||||
|
} catch (e: any) {
|
||||||
|
console.log(`Fail to parse data type='ZodRestInputError' error=${e}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -5,7 +5,7 @@ import { z as zod } from "zod";
|
|||||||
|
|
||||||
import {ZodObjectId} from "./object-id";
|
import {ZodObjectId} from "./object-id";
|
||||||
import {ZodLong} from "./long";
|
import {ZodLong} from "./long";
|
||||||
import {ZodGenericDataSoftDelete, ZodGenericDataSoftDeleteWrite } from "./generic-data-soft-delete";
|
import {ZodGenericDataSoftDelete, ZodGenericDataSoftDeleteUpdate , ZodGenericDataSoftDeleteCreate } from "./generic-data-soft-delete";
|
||||||
|
|
||||||
export const ZodTrack = ZodGenericDataSoftDelete.extend({
|
export const ZodTrack = ZodGenericDataSoftDelete.extend({
|
||||||
name: zod.string().optional(),
|
name: zod.string().optional(),
|
||||||
@ -33,7 +33,7 @@ export function isTrack(data: any): data is Track {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export const ZodTrackWrite = ZodGenericDataSoftDeleteWrite.extend({
|
export const ZodTrackUpdate = ZodGenericDataSoftDeleteUpdate.extend({
|
||||||
name: zod.string().nullable().optional(),
|
name: zod.string().nullable().optional(),
|
||||||
description: zod.string().nullable().optional(),
|
description: zod.string().nullable().optional(),
|
||||||
/**
|
/**
|
||||||
@ -44,18 +44,44 @@ export const ZodTrackWrite = ZodGenericDataSoftDeleteWrite.extend({
|
|||||||
albumId: ZodLong.nullable().optional(),
|
albumId: ZodLong.nullable().optional(),
|
||||||
track: ZodLong.nullable().optional(),
|
track: ZodLong.nullable().optional(),
|
||||||
dataId: ZodObjectId.nullable().optional(),
|
dataId: ZodObjectId.nullable().optional(),
|
||||||
artists: zod.array(ZodLong).optional(),
|
artists: zod.array(ZodLong),
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export type TrackWrite = zod.infer<typeof ZodTrackWrite>;
|
export type TrackUpdate = zod.infer<typeof ZodTrackUpdate>;
|
||||||
|
|
||||||
export function isTrackWrite(data: any): data is TrackWrite {
|
export function isTrackUpdate(data: any): data is TrackUpdate {
|
||||||
try {
|
try {
|
||||||
ZodTrackWrite.parse(data);
|
ZodTrackUpdate.parse(data);
|
||||||
return true;
|
return true;
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
console.log(`Fail to parse data type='ZodTrackWrite' error=${e}`);
|
console.log(`Fail to parse data type='ZodTrackUpdate' error=${e}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export const ZodTrackCreate = ZodGenericDataSoftDeleteCreate.extend({
|
||||||
|
name: zod.string().nullable().optional(),
|
||||||
|
description: zod.string().nullable().optional(),
|
||||||
|
/**
|
||||||
|
* List of Id of the specific covers
|
||||||
|
*/
|
||||||
|
covers: zod.array(ZodObjectId).nullable().optional(),
|
||||||
|
genderId: ZodLong.nullable().optional(),
|
||||||
|
albumId: ZodLong.nullable().optional(),
|
||||||
|
track: ZodLong.nullable().optional(),
|
||||||
|
dataId: ZodObjectId.nullable().optional(),
|
||||||
|
artists: zod.array(ZodLong),
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
export type TrackCreate = zod.infer<typeof ZodTrackCreate>;
|
||||||
|
|
||||||
|
export function isTrackCreate(data: any): data is TrackCreate {
|
||||||
|
try {
|
||||||
|
ZodTrackCreate.parse(data);
|
||||||
|
return true;
|
||||||
|
} catch (e: any) {
|
||||||
|
console.log(`Fail to parse data type='ZodTrackCreate' error=${e}`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
import { z as zod } from "zod";
|
import { z as zod } from "zod";
|
||||||
|
|
||||||
import {ZodUser, ZodUserWrite } from "./user";
|
import {ZodUser, ZodUserUpdate , ZodUserCreate } from "./user";
|
||||||
|
|
||||||
export const ZodUserKarusic = ZodUser;
|
export const ZodUserKarusic = ZodUser;
|
||||||
|
|
||||||
@ -18,16 +18,3 @@ export function isUserKarusic(data: any): data is UserKarusic {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export const ZodUserKarusicWrite = ZodUserWrite;
|
|
||||||
|
|
||||||
export type UserKarusicWrite = zod.infer<typeof ZodUserKarusicWrite>;
|
|
||||||
|
|
||||||
export function isUserKarusicWrite(data: any): data is UserKarusicWrite {
|
|
||||||
try {
|
|
||||||
ZodUserKarusicWrite.parse(data);
|
|
||||||
return true;
|
|
||||||
} catch (e: any) {
|
|
||||||
console.log(`Fail to parse data type='ZodUserKarusicWrite' error=${e}`);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -5,7 +5,7 @@ import { z as zod } from "zod";
|
|||||||
|
|
||||||
import {ZodTimestamp} from "./timestamp";
|
import {ZodTimestamp} from "./timestamp";
|
||||||
import {ZodUUID} from "./uuid";
|
import {ZodUUID} from "./uuid";
|
||||||
import {ZodGenericDataSoftDelete, ZodGenericDataSoftDeleteWrite } from "./generic-data-soft-delete";
|
import {ZodGenericDataSoftDelete, ZodGenericDataSoftDeleteUpdate , ZodGenericDataSoftDeleteCreate } from "./generic-data-soft-delete";
|
||||||
|
|
||||||
export const ZodUser = ZodGenericDataSoftDelete.extend({
|
export const ZodUser = ZodGenericDataSoftDelete.extend({
|
||||||
login: zod.string().min(3).max(128),
|
login: zod.string().min(3).max(128),
|
||||||
@ -30,8 +30,8 @@ export function isUser(data: any): data is User {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export const ZodUserWrite = ZodGenericDataSoftDeleteWrite.extend({
|
export const ZodUserUpdate = ZodGenericDataSoftDeleteUpdate.extend({
|
||||||
login: zod.string().min(3).max(128).optional(),
|
login: zod.string().min(3).max(128),
|
||||||
lastConnection: ZodTimestamp.nullable().optional(),
|
lastConnection: ZodTimestamp.nullable().optional(),
|
||||||
blocked: zod.boolean().nullable().optional(),
|
blocked: zod.boolean().nullable().optional(),
|
||||||
blockedReason: zod.string().max(512).nullable().optional(),
|
blockedReason: zod.string().max(512).nullable().optional(),
|
||||||
@ -42,14 +42,37 @@ export const ZodUserWrite = ZodGenericDataSoftDeleteWrite.extend({
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export type UserWrite = zod.infer<typeof ZodUserWrite>;
|
export type UserUpdate = zod.infer<typeof ZodUserUpdate>;
|
||||||
|
|
||||||
export function isUserWrite(data: any): data is UserWrite {
|
export function isUserUpdate(data: any): data is UserUpdate {
|
||||||
try {
|
try {
|
||||||
ZodUserWrite.parse(data);
|
ZodUserUpdate.parse(data);
|
||||||
return true;
|
return true;
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
console.log(`Fail to parse data type='ZodUserWrite' error=${e}`);
|
console.log(`Fail to parse data type='ZodUserUpdate' error=${e}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export const ZodUserCreate = ZodGenericDataSoftDeleteCreate.extend({
|
||||||
|
login: zod.string().min(3).max(128),
|
||||||
|
lastConnection: ZodTimestamp.nullable().optional(),
|
||||||
|
blocked: zod.boolean().nullable().optional(),
|
||||||
|
blockedReason: zod.string().max(512).nullable().optional(),
|
||||||
|
/**
|
||||||
|
* List of Id of the specific covers
|
||||||
|
*/
|
||||||
|
covers: zod.array(ZodUUID).nullable().optional(),
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
export type UserCreate = zod.infer<typeof ZodUserCreate>;
|
||||||
|
|
||||||
|
export function isUserCreate(data: any): data is UserCreate {
|
||||||
|
try {
|
||||||
|
ZodUserCreate.parse(data);
|
||||||
|
return true;
|
||||||
|
} catch (e: any) {
|
||||||
|
console.log(`Fail to parse data type='ZodUserCreate' error=${e}`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,30 +3,29 @@
|
|||||||
* @copyright 2024, Edouard DUPIN, all right reserved
|
* @copyright 2024, Edouard DUPIN, all right reserved
|
||||||
* @license MPL-2
|
* @license MPL-2
|
||||||
*/
|
*/
|
||||||
|
import { RestErrorResponse, isRestErrorResponse } from './model';
|
||||||
import { RestErrorResponse, isRestErrorResponse } from "./model";
|
|
||||||
|
|
||||||
export enum HTTPRequestModel {
|
export enum HTTPRequestModel {
|
||||||
ARCHIVE = "ARCHIVE",
|
ARCHIVE = 'ARCHIVE',
|
||||||
DELETE = "DELETE",
|
DELETE = 'DELETE',
|
||||||
HEAD = "HEAD",
|
HEAD = 'HEAD',
|
||||||
GET = "GET",
|
GET = 'GET',
|
||||||
OPTION = "OPTION",
|
OPTION = 'OPTION',
|
||||||
PATCH = "PATCH",
|
PATCH = 'PATCH',
|
||||||
POST = "POST",
|
POST = 'POST',
|
||||||
PUT = "PUT",
|
PUT = 'PUT',
|
||||||
RESTORE = "RESTORE",
|
RESTORE = 'RESTORE',
|
||||||
}
|
}
|
||||||
export enum HTTPMimeType {
|
export enum HTTPMimeType {
|
||||||
ALL = "*/*",
|
ALL = '*/*',
|
||||||
CSV = "text/csv",
|
CSV = 'text/csv',
|
||||||
IMAGE = "image/*",
|
IMAGE = 'image/*',
|
||||||
IMAGE_JPEG = "image/jpeg",
|
IMAGE_JPEG = 'image/jpeg',
|
||||||
IMAGE_PNG = "image/png",
|
IMAGE_PNG = 'image/png',
|
||||||
JSON = "application/json",
|
JSON = 'application/json',
|
||||||
MULTIPART = "multipart/form-data",
|
MULTIPART = 'multipart/form-data',
|
||||||
OCTET_STREAM = "application/octet-stream",
|
OCTET_STREAM = 'application/octet-stream',
|
||||||
TEXT_PLAIN = "text/plain",
|
TEXT_PLAIN = 'text/plain',
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RESTConfig {
|
export interface RESTConfig {
|
||||||
@ -54,6 +53,14 @@ export interface ModelResponseHttp {
|
|||||||
data: any;
|
data: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ErrorRestApiCallback = (response: Response) => void;
|
||||||
|
|
||||||
|
let errorApiGlobalCallback: ErrorRestApiCallback | undefined = undefined;
|
||||||
|
|
||||||
|
export const setErrorApiGlobalCallback = (callback: ErrorRestApiCallback) => {
|
||||||
|
errorApiGlobalCallback = callback;
|
||||||
|
};
|
||||||
|
|
||||||
function isNullOrUndefined(data: any): data is undefined | null {
|
function isNullOrUndefined(data: any): data is undefined | null {
|
||||||
return data === undefined || data === null;
|
return data === undefined || data === null;
|
||||||
}
|
}
|
||||||
@ -78,6 +85,7 @@ export interface RESTRequestType {
|
|||||||
data?: any;
|
data?: any;
|
||||||
params?: object;
|
params?: object;
|
||||||
queries?: object;
|
queries?: object;
|
||||||
|
headers?: any;
|
||||||
callbacks?: RESTCallbacks;
|
callbacks?: RESTCallbacks;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,15 +95,15 @@ function replaceAll(input, searchValue, replaceValue) {
|
|||||||
|
|
||||||
function removeTrailingSlashes(input: string): string {
|
function removeTrailingSlashes(input: string): string {
|
||||||
if (isNullOrUndefined(input)) {
|
if (isNullOrUndefined(input)) {
|
||||||
return "undefined";
|
return 'undefined';
|
||||||
}
|
}
|
||||||
return input.replace(/\/+$/, "");
|
return input.replace(/\/+$/, '');
|
||||||
}
|
}
|
||||||
function removeLeadingSlashes(input: string): string {
|
function removeLeadingSlashes(input: string): string {
|
||||||
if (isNullOrUndefined(input)) {
|
if (isNullOrUndefined(input)) {
|
||||||
return "";
|
return '';
|
||||||
}
|
}
|
||||||
return input.replace(/^\/+/, "");
|
return input.replace(/^\/+/, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function RESTUrl({
|
export function RESTUrl({
|
||||||
@ -133,9 +141,9 @@ export function RESTUrl({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (restConfig.token !== undefined && restModel.tokenInUrl === true) {
|
if (restConfig.token !== undefined && restModel.tokenInUrl === true) {
|
||||||
searchParams.append("Authorization", `Bearer ${restConfig.token}`);
|
searchParams.append('Authorization', `Bearer ${restConfig.token}`);
|
||||||
}
|
}
|
||||||
return generateUrl + "?" + searchParams.toString();
|
return generateUrl + '?' + searchParams.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fetchProgress(
|
export function fetchProgress(
|
||||||
@ -159,7 +167,7 @@ export function fetchProgress(
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
// Stream the upload progress
|
// Stream the upload progress
|
||||||
if (progressUpload) {
|
if (progressUpload) {
|
||||||
xhr.io?.upload.addEventListener("progress", (dataEvent) => {
|
xhr.io?.upload.addEventListener('progress', (dataEvent) => {
|
||||||
if (dataEvent.lengthComputable) {
|
if (dataEvent.lengthComputable) {
|
||||||
progressUpload(dataEvent.loaded, dataEvent.total);
|
progressUpload(dataEvent.loaded, dataEvent.total);
|
||||||
}
|
}
|
||||||
@ -167,7 +175,7 @@ export function fetchProgress(
|
|||||||
}
|
}
|
||||||
// Stream the download progress
|
// Stream the download progress
|
||||||
if (progressDownload) {
|
if (progressDownload) {
|
||||||
xhr.io?.addEventListener("progress", (dataEvent) => {
|
xhr.io?.addEventListener('progress', (dataEvent) => {
|
||||||
if (dataEvent.lengthComputable) {
|
if (dataEvent.lengthComputable) {
|
||||||
progressDownload(dataEvent.loaded, dataEvent.total);
|
progressDownload(dataEvent.loaded, dataEvent.total);
|
||||||
}
|
}
|
||||||
@ -187,19 +195,19 @@ export function fetchProgress(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
// Check if we have an internal Fail:
|
// Check if we have an internal Fail:
|
||||||
xhr.io?.addEventListener("error", () => {
|
xhr.io?.addEventListener('error', () => {
|
||||||
xhr.io = undefined;
|
xhr.io = undefined;
|
||||||
reject(new TypeError("Failed to fetch"));
|
reject(new TypeError('Failed to fetch'));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Capture the end of the stream
|
// Capture the end of the stream
|
||||||
xhr.io?.addEventListener("loadend", () => {
|
xhr.io?.addEventListener('loadend', () => {
|
||||||
if (xhr.io?.readyState !== XMLHttpRequest.DONE) {
|
if (xhr.io?.readyState !== XMLHttpRequest.DONE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (xhr.io?.status === 0) {
|
if (xhr.io?.status === 0) {
|
||||||
//the stream has been aborted
|
//the stream has been aborted
|
||||||
reject(new TypeError("Fetch has been aborted"));
|
reject(new TypeError('Fetch has been aborted'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Stream is ended, transform in a generic response:
|
// Stream is ended, transform in a generic response:
|
||||||
@ -209,17 +217,17 @@ export function fetchProgress(
|
|||||||
});
|
});
|
||||||
const headersArray = replaceAll(
|
const headersArray = replaceAll(
|
||||||
xhr.io.getAllResponseHeaders().trim(),
|
xhr.io.getAllResponseHeaders().trim(),
|
||||||
"\r\n",
|
'\r\n',
|
||||||
"\n"
|
'\n'
|
||||||
).split("\n");
|
).split('\n');
|
||||||
headersArray.forEach(function (header) {
|
headersArray.forEach(function (header) {
|
||||||
const firstColonIndex = header.indexOf(":");
|
const firstColonIndex = header.indexOf(':');
|
||||||
if (firstColonIndex !== -1) {
|
if (firstColonIndex !== -1) {
|
||||||
const key = header.substring(0, firstColonIndex).trim();
|
const key = header.substring(0, firstColonIndex).trim();
|
||||||
const value = header.substring(firstColonIndex + 1).trim();
|
const value = header.substring(firstColonIndex + 1).trim();
|
||||||
response.headers.set(key, value);
|
response.headers.set(key, value);
|
||||||
} else {
|
} else {
|
||||||
response.headers.set(header, "");
|
response.headers.set(header, '');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
xhr.io = undefined;
|
xhr.io = undefined;
|
||||||
@ -241,27 +249,29 @@ export function RESTRequest({
|
|||||||
data,
|
data,
|
||||||
params,
|
params,
|
||||||
queries,
|
queries,
|
||||||
|
headers = {},
|
||||||
callbacks,
|
callbacks,
|
||||||
}: RESTRequestType): Promise<ModelResponseHttp> {
|
}: 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 = {};
|
|
||||||
if (restConfig.token !== undefined && restModel.tokenInUrl !== true) {
|
if (restConfig.token !== undefined && restModel.tokenInUrl !== true) {
|
||||||
headers["Authorization"] = `Bearer ${restConfig.token}`;
|
headers['Authorization'] = `Bearer ${restConfig.token}`;
|
||||||
}
|
}
|
||||||
if (restModel.accept !== undefined) {
|
if (restModel.accept !== undefined) {
|
||||||
headers["Accept"] = restModel.accept;
|
headers['Accept'] = restModel.accept;
|
||||||
}
|
}
|
||||||
if (restModel.requestType !== HTTPRequestModel.GET &&
|
if (
|
||||||
restModel.requestType !== HTTPRequestModel.ARCHIVE &&
|
restModel.requestType !== HTTPRequestModel.GET &&
|
||||||
restModel.requestType !== HTTPRequestModel.RESTORE
|
restModel.requestType !== HTTPRequestModel.ARCHIVE &&
|
||||||
|
restModel.requestType !== HTTPRequestModel.RESTORE
|
||||||
) {
|
) {
|
||||||
// if Get we have not a content type, the body is empty
|
// if Get we have not a content type, the body is empty
|
||||||
if (restModel.contentType !== HTTPMimeType.MULTIPART &&
|
if (
|
||||||
restModel.contentType !== undefined
|
restModel.contentType !== HTTPMimeType.MULTIPART &&
|
||||||
) {
|
restModel.contentType !== undefined
|
||||||
|
) {
|
||||||
// special case of multi-part ==> no content type otherwise the browser does not set the ";bundary=--****"
|
// special case of multi-part ==> no content type otherwise the browser does not set the ";bundary=--****"
|
||||||
headers["Content-Type"] = restModel.contentType;
|
headers['Content-Type'] = restModel.contentType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let body = data;
|
let body = data;
|
||||||
@ -302,19 +312,27 @@ export function RESTRequest({
|
|||||||
}
|
}
|
||||||
action
|
action
|
||||||
.then((response: Response) => {
|
.then((response: Response) => {
|
||||||
|
if (
|
||||||
|
errorApiGlobalCallback &&
|
||||||
|
400 <= response.status &&
|
||||||
|
response.status <= 499
|
||||||
|
) {
|
||||||
|
// Detect an error and trigger the generic error callback:
|
||||||
|
errorApiGlobalCallback(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 (
|
if (
|
||||||
!isNullOrUndefined(restModel.accept) &&
|
!isNullOrUndefined(restModel.accept) &&
|
||||||
restModel.accept !== contentType
|
restModel.accept !== contentType
|
||||||
) {
|
) {
|
||||||
reject({
|
reject({
|
||||||
name: "Model accept type incompatible",
|
name: 'Model accept type incompatible',
|
||||||
time: Date().toString(),
|
time: Date().toString(),
|
||||||
status: 901,
|
status: 901,
|
||||||
message: `REST Content type are not compatible: ${restModel.accept} != ${contentType}`,
|
message: `REST Content type are not compatible: ${restModel.accept} != ${contentType}`,
|
||||||
statusMessage: "Fetch error",
|
statusMessage: 'Fetch error',
|
||||||
error: "rest-tools.ts Wrong type in the message return type",
|
error: 'rest-tools.ts Wrong type in the message return type',
|
||||||
} as RestErrorResponse);
|
} as RestErrorResponse);
|
||||||
} else if (contentType === HTTPMimeType.JSON) {
|
} else if (contentType === HTTPMimeType.JSON) {
|
||||||
response
|
response
|
||||||
@ -324,12 +342,12 @@ export function RESTRequest({
|
|||||||
})
|
})
|
||||||
.catch((reason: Error) => {
|
.catch((reason: Error) => {
|
||||||
reject({
|
reject({
|
||||||
name: "API serialization error",
|
name: 'API serialization error',
|
||||||
time: Date().toString(),
|
time: Date().toString(),
|
||||||
status: 902,
|
status: 902,
|
||||||
message: `REST parse json fail: ${reason}`,
|
message: `REST parse json fail: ${reason}`,
|
||||||
statusMessage: "Fetch parse error",
|
statusMessage: 'Fetch parse error',
|
||||||
error: "rest-tools.ts Wrong message model to parse",
|
error: 'rest-tools.ts Wrong message model to parse',
|
||||||
} as RestErrorResponse);
|
} as RestErrorResponse);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -349,22 +367,22 @@ export function RESTRequest({
|
|||||||
.text()
|
.text()
|
||||||
.then((dataError: string) => {
|
.then((dataError: string) => {
|
||||||
reject({
|
reject({
|
||||||
name: "API serialization error",
|
name: 'API serialization error',
|
||||||
time: Date().toString(),
|
time: Date().toString(),
|
||||||
status: 903,
|
status: 903,
|
||||||
message: `REST parse error json with wrong type fail. ${dataError}`,
|
message: `REST parse error json with wrong type fail. ${dataError}`,
|
||||||
statusMessage: "Fetch parse error",
|
statusMessage: 'Fetch parse error',
|
||||||
error: "rest-tools.ts Wrong message model to parse",
|
error: 'rest-tools.ts Wrong message model to parse',
|
||||||
} as RestErrorResponse);
|
} as RestErrorResponse);
|
||||||
})
|
})
|
||||||
.catch((reason: any) => {
|
.catch((reason: any) => {
|
||||||
reject({
|
reject({
|
||||||
name: "API serialization error",
|
name: 'API serialization error',
|
||||||
time: Date().toString(),
|
time: Date().toString(),
|
||||||
status: response.status,
|
status: response.status,
|
||||||
message: `unmanaged error model: ??? with error: ${reason}`,
|
message: `unmanaged error model: ??? with error: ${reason}`,
|
||||||
statusMessage: "Fetch ERROR parse error",
|
statusMessage: 'Fetch ERROR parse error',
|
||||||
error: "rest-tools.ts Wrong message model to parse",
|
error: 'rest-tools.ts Wrong message model to parse',
|
||||||
} as RestErrorResponse);
|
} as RestErrorResponse);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -374,22 +392,22 @@ export function RESTRequest({
|
|||||||
.text()
|
.text()
|
||||||
.then((dataError: string) => {
|
.then((dataError: string) => {
|
||||||
reject({
|
reject({
|
||||||
name: "API serialization error",
|
name: 'API serialization error',
|
||||||
time: Date().toString(),
|
time: Date().toString(),
|
||||||
status: response.status,
|
status: response.status,
|
||||||
message: `unmanaged error model: ${dataError} with error: ${reason}`,
|
message: `unmanaged error model: ${dataError} with error: ${reason}`,
|
||||||
statusMessage: "Fetch ERROR TEXT parse error",
|
statusMessage: 'Fetch ERROR TEXT parse error',
|
||||||
error: "rest-tools.ts Wrong message model to parse",
|
error: 'rest-tools.ts Wrong message model to parse',
|
||||||
} as RestErrorResponse);
|
} as RestErrorResponse);
|
||||||
})
|
})
|
||||||
.catch((reason: any) => {
|
.catch((reason: any) => {
|
||||||
reject({
|
reject({
|
||||||
name: "API serialization error",
|
name: 'API serialization error',
|
||||||
time: Date().toString(),
|
time: Date().toString(),
|
||||||
status: response.status,
|
status: response.status,
|
||||||
message: `unmanaged error model: ??? with error: ${reason}`,
|
message: `unmanaged error model: ??? with error: ${reason}`,
|
||||||
statusMessage: "Fetch ERROR TEXT FAIL",
|
statusMessage: 'Fetch ERROR TEXT FAIL',
|
||||||
error: "rest-tools.ts Wrong message model to parse",
|
error: 'rest-tools.ts Wrong message model to parse',
|
||||||
} as RestErrorResponse);
|
} as RestErrorResponse);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -400,12 +418,12 @@ export function RESTRequest({
|
|||||||
reject(error);
|
reject(error);
|
||||||
} else {
|
} else {
|
||||||
reject({
|
reject({
|
||||||
name: "Request fail",
|
name: 'Request fail',
|
||||||
time: Date(),
|
time: Date(),
|
||||||
status: 999,
|
status: 999,
|
||||||
message: error,
|
message: error,
|
||||||
statusMessage: "Fetch catch error",
|
statusMessage: 'Fetch catch error',
|
||||||
error: "rest-tools.ts detect an error in the fetch request",
|
error: 'rest-tools.ts detect an error in the fetch request',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -426,12 +444,12 @@ export function RESTRequestJson<TYPE>(
|
|||||||
resolve(value.data);
|
resolve(value.data);
|
||||||
} else {
|
} else {
|
||||||
reject({
|
reject({
|
||||||
name: "Model check fail",
|
name: 'Model check fail',
|
||||||
time: Date().toString(),
|
time: Date().toString(),
|
||||||
status: 950,
|
status: 950,
|
||||||
error: "REST Fail to verify the data",
|
error: 'REST Fail to verify the data',
|
||||||
statusMessage: "API cast ERROR",
|
statusMessage: 'API cast ERROR',
|
||||||
message: "api.ts Check type as fail",
|
message: 'api.ts Check type as fail',
|
||||||
} as RestErrorResponse);
|
} as RestErrorResponse);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -1,26 +1,61 @@
|
|||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
import { Box, Button, ConditionalValue, Flex, HStack, IconButton, Span, Text, useDisclosure } from '@chakra-ui/react';
|
Button,
|
||||||
import { LuAlignJustify, LuArrowBigLeft, LuCircleUserRound, LuKeySquare, LuLogIn, LuLogOut, LuMoon, LuSettings, LuSun } from 'react-icons/lu';
|
ConditionalValue,
|
||||||
import { MdHelp, MdHome, MdMore, MdOutlinePlaylistPlay, MdOutlineUploadFile, MdSupervisedUserCircle } from 'react-icons/md';
|
Flex,
|
||||||
|
HStack,
|
||||||
|
IconButton,
|
||||||
|
Span,
|
||||||
|
Text,
|
||||||
|
useBreakpointValue,
|
||||||
|
useDisclosure,
|
||||||
|
} from '@chakra-ui/react';
|
||||||
|
import {
|
||||||
|
LuAlignJustify,
|
||||||
|
LuArrowBigLeft,
|
||||||
|
LuCircleUserRound,
|
||||||
|
LuKeySquare,
|
||||||
|
LuLogIn,
|
||||||
|
LuLogOut,
|
||||||
|
LuMoon,
|
||||||
|
LuSettings,
|
||||||
|
LuSun,
|
||||||
|
} from 'react-icons/lu';
|
||||||
|
import {
|
||||||
|
MdHelp,
|
||||||
|
MdHome,
|
||||||
|
MdMore,
|
||||||
|
MdOutlinePlaylistPlay,
|
||||||
|
MdOutlineUploadFile,
|
||||||
|
MdSupervisedUserCircle,
|
||||||
|
} from 'react-icons/md';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import { useColorMode, useColorModeValue } from '@/components/ui/color-mode';
|
import { useColorMode, useColorModeValue } from '@/components/ui/color-mode';
|
||||||
import { DrawerBody, DrawerContent, DrawerHeader, DrawerRoot } from '@/components/ui/drawer';
|
import {
|
||||||
import { MenuContent, MenuItem, MenuRoot, MenuTrigger } from '@/components/ui/menu';
|
DrawerBody,
|
||||||
|
DrawerContent,
|
||||||
|
DrawerHeader,
|
||||||
|
DrawerRoot,
|
||||||
|
} from '@/components/ui/drawer';
|
||||||
|
import {
|
||||||
|
MenuContent,
|
||||||
|
MenuItem,
|
||||||
|
MenuRoot,
|
||||||
|
MenuTrigger,
|
||||||
|
} from '@/components/ui/menu';
|
||||||
import { useServiceContext } from '@/service/ServiceContext';
|
import { useServiceContext } from '@/service/ServiceContext';
|
||||||
import { SessionState } from '@/service/SessionState';
|
import { SessionState } from '@/service/SessionState';
|
||||||
import { useSessionService } from '@/service/session';
|
import { useSessionService } from '@/service/session';
|
||||||
import { colors } from '@/theme/colors';
|
import { colors } from '@/theme/colors';
|
||||||
import { requestOpenSite, requestSignIn, requestSignOut, requestSignUp } from '@/utils/sso';
|
import {
|
||||||
|
requestOpenSite,
|
||||||
|
requestSignIn,
|
||||||
|
requestSignOut,
|
||||||
|
requestSignUp,
|
||||||
|
} from '@/utils/sso';
|
||||||
|
|
||||||
export const TOP_BAR_HEIGHT = '50px';
|
export const TOP_BAR_HEIGHT = '50px';
|
||||||
|
|
||||||
@ -37,6 +72,8 @@ export const BUTTON_TOP_BAR_PROPERTY = {
|
|||||||
export type TopBarProps = {
|
export type TopBarProps = {
|
||||||
children?: ReactNode;
|
children?: ReactNode;
|
||||||
title?: string;
|
title?: string;
|
||||||
|
titleLink?: string;
|
||||||
|
titleIcon?: ReactNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
const ButtonMenuLeft = ({
|
const ButtonMenuLeft = ({
|
||||||
@ -74,7 +111,12 @@ const ButtonMenuLeft = ({
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
export const TopBar = ({ title, children }: TopBarProps) => {
|
export const TopBar = ({
|
||||||
|
title,
|
||||||
|
titleLink,
|
||||||
|
titleIcon,
|
||||||
|
children,
|
||||||
|
}: TopBarProps) => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { colorMode, toggleColorMode } = useColorMode();
|
const { colorMode, toggleColorMode } = useColorMode();
|
||||||
const { session } = useServiceContext();
|
const { session } = useServiceContext();
|
||||||
@ -99,8 +141,10 @@ export const TopBar = ({ title, children }: TopBarProps) => {
|
|||||||
const onKarso = (): void => {
|
const onKarso = (): void => {
|
||||||
requestOpenSite();
|
requestOpenSite();
|
||||||
};
|
};
|
||||||
|
const isVisible = useBreakpointValue({ base: false, md: true });
|
||||||
return (
|
return (
|
||||||
<Flex
|
<Flex
|
||||||
|
minWidth="320px"
|
||||||
position="absolute"
|
position="absolute"
|
||||||
top={0}
|
top={0}
|
||||||
left={0}
|
left={0}
|
||||||
@ -117,21 +161,28 @@ export const TopBar = ({ title, children }: TopBarProps) => {
|
|||||||
<Button {...BUTTON_TOP_BAR_PROPERTY} onClick={onChangeTheme}>
|
<Button {...BUTTON_TOP_BAR_PROPERTY} onClick={onChangeTheme}>
|
||||||
<HStack>
|
<HStack>
|
||||||
<LuAlignJustify />
|
<LuAlignJustify />
|
||||||
<Text paddingLeft="3px" fontWeight="bold">
|
{isVisible && (
|
||||||
Karusic
|
<Text paddingLeft="3px" fontWeight="bold">
|
||||||
</Text>
|
Karusic
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
</HStack>
|
</HStack>
|
||||||
</Button>
|
</Button>
|
||||||
{title && (
|
{title && (
|
||||||
<Text
|
<Text
|
||||||
|
truncate
|
||||||
fontSize="20px"
|
fontSize="20px"
|
||||||
fontWeight="bold"
|
fontWeight="bold"
|
||||||
textTransform="uppercase"
|
textTransform="uppercase"
|
||||||
marginRight="auto"
|
marginRight="auto"
|
||||||
userSelect="none"
|
userSelect="none"
|
||||||
color="brand.500"
|
color="brand.500"
|
||||||
|
onClick={titleLink ? () => navigate(titleLink) : undefined}
|
||||||
>
|
>
|
||||||
{title}
|
<Flex gap="4px">
|
||||||
|
{titleIcon}
|
||||||
|
{title}
|
||||||
|
</Flex>
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
{children}
|
{children}
|
||||||
|
@ -9,7 +9,7 @@ import {
|
|||||||
} from 'react-icons/md';
|
} from 'react-icons/md';
|
||||||
import { useNavigate, useParams } from 'react-router-dom';
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
|
|
||||||
import { AlbumResource, AlbumWrite } from '@/back-api';
|
import { AlbumResource, AlbumUpdate } from '@/back-api';
|
||||||
import { FormCovers } from '@/components/form/FormCovers';
|
import { FormCovers } from '@/components/form/FormCovers';
|
||||||
import { FormGroupShow } from '@/components/form/FormGroup';
|
import { FormGroupShow } from '@/components/form/FormGroup';
|
||||||
import { FormInput } from '@/components/form/FormInput';
|
import { FormInput } from '@/components/form/FormInput';
|
||||||
@ -64,11 +64,11 @@ export const AlbumEditPopUp = ({}: AlbumEditPopUpProps) => {
|
|||||||
};
|
};
|
||||||
const initialRef = useRef<HTMLButtonElement>(null);
|
const initialRef = useRef<HTMLButtonElement>(null);
|
||||||
const finalRef = useRef<HTMLButtonElement>(null);
|
const finalRef = useRef<HTMLButtonElement>(null);
|
||||||
const form = useFormidable<AlbumWrite>({
|
const form = useFormidable<Partial<AlbumUpdate>>({
|
||||||
initialValues: dataAlbum,
|
initialValues: dataAlbum,
|
||||||
deltaConfig: { omit: ['covers'] },
|
deltaConfig: { omit: ['covers'] },
|
||||||
});
|
});
|
||||||
const onSave = async (deltaData: AlbumWrite) => {
|
const onSave = async (deltaData: Partial<AlbumUpdate>) => {
|
||||||
if (isNullOrUndefined(albumIdInt)) {
|
if (isNullOrUndefined(albumIdInt)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ import {
|
|||||||
} from 'react-icons/md';
|
} from 'react-icons/md';
|
||||||
import { useNavigate, useParams } from 'react-router-dom';
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
|
|
||||||
import { ArtistResource, ArtistWrite } from '@/back-api';
|
import { ArtistResource, ArtistUpdate } from '@/back-api';
|
||||||
import { FormCovers } from '@/components/form/FormCovers';
|
import { FormCovers } from '@/components/form/FormCovers';
|
||||||
import { FormInput } from '@/components/form/FormInput';
|
import { FormInput } from '@/components/form/FormInput';
|
||||||
import { FormTextarea } from '@/components/form/FormTextarea';
|
import { FormTextarea } from '@/components/form/FormTextarea';
|
||||||
@ -63,11 +63,11 @@ export const ArtistEditPopUp = ({}: ArtistEditPopUpProps) => {
|
|||||||
};
|
};
|
||||||
const initialRef = useRef<HTMLButtonElement>(null);
|
const initialRef = useRef<HTMLButtonElement>(null);
|
||||||
const finalRef = useRef<HTMLButtonElement>(null);
|
const finalRef = useRef<HTMLButtonElement>(null);
|
||||||
const form = useFormidable<ArtistWrite>({
|
const form = useFormidable<Partial<ArtistUpdate>>({
|
||||||
initialValues: dataArtist,
|
initialValues: dataArtist,
|
||||||
deltaConfig: { omit: ['covers'] },
|
deltaConfig: { omit: ['covers'] },
|
||||||
});
|
});
|
||||||
const onSave = async (dataDelta: ArtistWrite) => {
|
const onSave = async (dataDelta: Partial<ArtistUpdate>) => {
|
||||||
if (isNullOrUndefined(artistIdInt)) {
|
if (isNullOrUndefined(artistIdInt)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ import {
|
|||||||
} from 'react-icons/md';
|
} from 'react-icons/md';
|
||||||
import { useNavigate, useParams } from 'react-router-dom';
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
|
|
||||||
import { GenderResource, GenderWrite } from '@/back-api';
|
import { GenderResource, GenderUpdate } from '@/back-api';
|
||||||
import { FormCovers } from '@/components/form/FormCovers';
|
import { FormCovers } from '@/components/form/FormCovers';
|
||||||
import { FormInput } from '@/components/form/FormInput';
|
import { FormInput } from '@/components/form/FormInput';
|
||||||
import { FormTextarea } from '@/components/form/FormTextarea';
|
import { FormTextarea } from '@/components/form/FormTextarea';
|
||||||
@ -63,11 +63,11 @@ export const GenderEditPopUp = ({}: GenderEditPopUpProps) => {
|
|||||||
};
|
};
|
||||||
const initialRef = useRef<HTMLButtonElement>(null);
|
const initialRef = useRef<HTMLButtonElement>(null);
|
||||||
const finalRef = useRef<HTMLButtonElement>(null);
|
const finalRef = useRef<HTMLButtonElement>(null);
|
||||||
const form = useFormidable<GenderWrite>({
|
const form = useFormidable<Partial<GenderUpdate>>({
|
||||||
initialValues: dataGender,
|
initialValues: dataGender,
|
||||||
deltaConfig: { omit: ['covers'] },
|
deltaConfig: { omit: ['covers'] },
|
||||||
});
|
});
|
||||||
const onSave = async (dataDelta: GenderWrite) => {
|
const onSave = async (dataDelta: Partial<GenderUpdate>) => {
|
||||||
if (isNullOrUndefined(genderIdInt)) {
|
if (isNullOrUndefined(genderIdInt)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import { Button, Text, useDisclosure } from '@chakra-ui/react';
|
|||||||
import { MdAdminPanelSettings, MdDeleteForever, MdEdit } from 'react-icons/md';
|
import { MdAdminPanelSettings, MdDeleteForever, MdEdit } from 'react-icons/md';
|
||||||
import { useNavigate, useParams } from 'react-router-dom';
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
|
|
||||||
import { TrackResource, TrackWrite } from '@/back-api';
|
import { TrackResource, TrackUpdate } from '@/back-api';
|
||||||
import { FormGroupShow } from '@/components/form/FormGroup';
|
import { FormGroupShow } from '@/components/form/FormGroup';
|
||||||
import { FormInput } from '@/components/form/FormInput';
|
import { FormInput } from '@/components/form/FormInput';
|
||||||
import { FormNumber } from '@/components/form/FormNumber';
|
import { FormNumber } from '@/components/form/FormNumber';
|
||||||
@ -64,11 +64,11 @@ export const TrackEditPopUp = ({}: TrackEditPopUpProps) => {
|
|||||||
};
|
};
|
||||||
const initialRef = useRef<HTMLButtonElement>(null);
|
const initialRef = useRef<HTMLButtonElement>(null);
|
||||||
const finalRef = useRef<HTMLButtonElement>(null);
|
const finalRef = useRef<HTMLButtonElement>(null);
|
||||||
const form = useFormidable<TrackWrite>({
|
const form = useFormidable<Partial<TrackUpdate>>({
|
||||||
initialValues: dataTrack,
|
initialValues: dataTrack,
|
||||||
deltaConfig: { omit: ['covers'] },
|
deltaConfig: { omit: ['covers'] },
|
||||||
});
|
});
|
||||||
const onSave = async (dataDelta: TrackWrite) => {
|
const onSave = async (dataDelta: Partial<TrackUpdate>) => {
|
||||||
if (isNullOrUndefined(trackIdInt)) {
|
if (isNullOrUndefined(trackIdInt)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ export const AlbumDetailPage = () => {
|
|||||||
if (!dataAlbum) {
|
if (!dataAlbum) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<TopBar title="Album detail" />
|
<TopBar title="Album detail" titleLink="/album" />
|
||||||
<PageLayoutInfoCenter>
|
<PageLayoutInfoCenter>
|
||||||
Fail to load artist id: {albumId}
|
Fail to load artist id: {albumId}
|
||||||
</PageLayoutInfoCenter>
|
</PageLayoutInfoCenter>
|
||||||
@ -54,7 +54,7 @@ export const AlbumDetailPage = () => {
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<TopBar title="Album detail">
|
<TopBar title="Album detail" titleLink="/album">
|
||||||
<Button
|
<Button
|
||||||
{...BUTTON_TOP_BAR_PROPERTY}
|
{...BUTTON_TOP_BAR_PROPERTY}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
|
@ -28,7 +28,7 @@ export const AlbumsPage = () => {
|
|||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<TopBar title="All Albums" />
|
<TopBar title="All Albums" titleLink="/home" />
|
||||||
<PageLayoutInfoCenter>No Album available</PageLayoutInfoCenter>
|
<PageLayoutInfoCenter>No Album available</PageLayoutInfoCenter>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
@ -36,7 +36,7 @@ export const AlbumsPage = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<TopBar title="All Albums">
|
<TopBar title="All Albums" titleLink="/home">
|
||||||
<SearchInput onChange={setFilterTitle} />
|
<SearchInput onChange={setFilterTitle} />
|
||||||
</TopBar>
|
</TopBar>
|
||||||
<PageLayout>
|
<PageLayout>
|
||||||
|
@ -55,33 +55,27 @@ export const ArtistAlbumDetailPage = () => {
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<TopBar title={dataArtist ? undefined : 'Album detail'}>
|
<TopBar
|
||||||
|
title={dataArtist ? dataArtist?.name : 'Album detail'}
|
||||||
|
titleLink={dataArtist ? `/artist/${dataArtist.id}` : undefined}
|
||||||
|
titleIcon={
|
||||||
|
<Covers
|
||||||
|
data={dataArtist?.covers}
|
||||||
|
size="35px"
|
||||||
|
borderRadius="full"
|
||||||
|
iconEmpty={<MdPerson />}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
>
|
||||||
{dataArtist && (
|
{dataArtist && (
|
||||||
<>
|
<Button
|
||||||
<Button
|
{...BUTTON_TOP_BAR_PROPERTY}
|
||||||
{...BUTTON_TOP_BAR_PROPERTY}
|
onClick={() =>
|
||||||
marginRight="auto"
|
navigate(`/album/${albumId}/edit-album/${dataAlbum.id}`)
|
||||||
onClick={() => navigate(`/artist/${dataArtist.id}`)}
|
}
|
||||||
>
|
>
|
||||||
<Covers
|
<MdEdit />
|
||||||
data={dataArtist?.covers}
|
</Button>
|
||||||
size="35px"
|
|
||||||
borderRadius="full"
|
|
||||||
iconEmpty={<MdPerson />}
|
|
||||||
/>
|
|
||||||
<Text fontSize="24px" fontWeight="bold">
|
|
||||||
{dataArtist?.name}
|
|
||||||
</Text>
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
{...BUTTON_TOP_BAR_PROPERTY}
|
|
||||||
onClick={() =>
|
|
||||||
navigate(`/album/${albumId}/edit-album/${dataAlbum.id}`)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<MdEdit />
|
|
||||||
</Button>
|
|
||||||
</>
|
|
||||||
)}
|
)}
|
||||||
</TopBar>
|
</TopBar>
|
||||||
<PageLayout>
|
<PageLayout>
|
||||||
|
@ -32,7 +32,7 @@ export const ArtistDetailPage = () => {
|
|||||||
if (!dataArtist) {
|
if (!dataArtist) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<TopBar title="Artist detail" />
|
<TopBar title="Artists" titleLink="/artist" />
|
||||||
<PageLayoutInfoCenter>
|
<PageLayoutInfoCenter>
|
||||||
Fail to load artist id: {artistId}
|
Fail to load artist id: {artistId}
|
||||||
</PageLayoutInfoCenter>
|
</PageLayoutInfoCenter>
|
||||||
@ -41,19 +41,12 @@ export const ArtistDetailPage = () => {
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<TopBar>
|
<TopBar
|
||||||
|
title="Artists"
|
||||||
|
titleLink="/artist/all"
|
||||||
|
titleIcon={<MdGroup height="full" />}
|
||||||
|
>
|
||||||
<>
|
<>
|
||||||
<Button
|
|
||||||
{...BUTTON_TOP_BAR_PROPERTY}
|
|
||||||
marginRight="auto"
|
|
||||||
onClick={() => navigate(`/artist/all`)}
|
|
||||||
>
|
|
||||||
<MdGroup height="full" />
|
|
||||||
<Text fontSize="24px" fontWeight="bold">
|
|
||||||
Artists
|
|
||||||
</Text>
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
{...BUTTON_TOP_BAR_PROPERTY}
|
{...BUTTON_TOP_BAR_PROPERTY}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
|
@ -63,7 +63,7 @@ export const ArtistsPage = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<TopBar title="All artists">
|
<TopBar title="All artists" titleLink="/home">
|
||||||
<SearchInput onChange={setFilterName} />
|
<SearchInput onChange={setFilterName} />
|
||||||
<Tooltip.Root aria-label="Random play">
|
<Tooltip.Root aria-label="Random play">
|
||||||
<Button {...BUTTON_TOP_BAR_PROPERTY} onClick={onRandomPlay}>
|
<Button {...BUTTON_TOP_BAR_PROPERTY} onClick={onRandomPlay}>
|
||||||
|
@ -45,7 +45,7 @@ export const GenderDetailPage = () => {
|
|||||||
if (!dataGender) {
|
if (!dataGender) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<TopBar title="Gender detail" />
|
<TopBar title="Gender detail" titleLink="/gender" />
|
||||||
<PageLayoutInfoCenter>
|
<PageLayoutInfoCenter>
|
||||||
Fail to load artist id: {genderId}
|
Fail to load artist id: {genderId}
|
||||||
</PageLayoutInfoCenter>
|
</PageLayoutInfoCenter>
|
||||||
@ -54,7 +54,7 @@ export const GenderDetailPage = () => {
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<TopBar title="Gender detail">
|
<TopBar title="Gender detail" titleLink="/gender">
|
||||||
<Button
|
<Button
|
||||||
{...BUTTON_TOP_BAR_PROPERTY}
|
{...BUTTON_TOP_BAR_PROPERTY}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
|
@ -23,7 +23,7 @@ export const GendersPage = () => {
|
|||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<TopBar title="All Genders" />
|
<TopBar title="All Genders" titleLink="/home" />
|
||||||
<PageLayoutInfoCenter>No Gender available</PageLayoutInfoCenter>
|
<PageLayoutInfoCenter>No Gender available</PageLayoutInfoCenter>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
@ -31,7 +31,7 @@ export const GendersPage = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<TopBar title="All Genders">
|
<TopBar title="All Genders" titleLink="/home">
|
||||||
<SearchInput onChange={setFilterTitle} />
|
<SearchInput onChange={setFilterTitle} />
|
||||||
</TopBar>
|
</TopBar>
|
||||||
<PageLayout>
|
<PageLayout>
|
||||||
|
@ -97,7 +97,7 @@ export const OnAirPage = () => {
|
|||||||
if (!playTrackList || playTrackList.length == 0) {
|
if (!playTrackList || playTrackList.length == 0) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<TopBar title="Album detail" />
|
<TopBar title="On Air ..." titleLink="/home" />
|
||||||
<PageLayoutInfoCenter>
|
<PageLayoutInfoCenter>
|
||||||
No data is currently playing...
|
No data is currently playing...
|
||||||
</PageLayoutInfoCenter>
|
</PageLayoutInfoCenter>
|
||||||
@ -106,7 +106,7 @@ export const OnAirPage = () => {
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<TopBar title="On Air ...">
|
<TopBar title="On Air ..." titleLink="/home">
|
||||||
<Button {...BUTTON_TOP_BAR_PROPERTY} onClick={clean}>
|
<Button {...BUTTON_TOP_BAR_PROPERTY} onClick={clean}>
|
||||||
<LuTrash2 />
|
<LuTrash2 />
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -42,7 +42,7 @@ export const TrackSelectionPage = () => {
|
|||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<TopBar title="All Tracks" />
|
<TopBar title="All Tracks" titleLink="/home" />
|
||||||
<PageLayout>
|
<PageLayout>
|
||||||
<HStack
|
<HStack
|
||||||
wrap="wrap"
|
wrap="wrap"
|
||||||
|
@ -1,21 +1,33 @@
|
|||||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
|
|
||||||
import { PartRight, RESTConfig, UserMe, UserResource } from '@/back-api';
|
import { createListCollection } from '@chakra-ui/react';
|
||||||
|
import { useEffectOnce } from 'react-use';
|
||||||
|
|
||||||
|
import {
|
||||||
|
PartRight,
|
||||||
|
RESTConfig,
|
||||||
|
UserMe,
|
||||||
|
UserResource,
|
||||||
|
setErrorApiGlobalCallback,
|
||||||
|
} from '@/back-api';
|
||||||
import { environment, getApiUrl } from '@/environment';
|
import { environment, getApiUrl } from '@/environment';
|
||||||
import { useServiceContext } from '@/service/ServiceContext';
|
import { useServiceContext } from '@/service/ServiceContext';
|
||||||
import { SessionState } from '@/service/SessionState';
|
import { SessionState } from '@/service/SessionState';
|
||||||
import { isBrowser } from '@/utils/layout';
|
import { isBrowser } from '@/utils/layout';
|
||||||
import { parseToken } from '@/utils/sso';
|
import { parseToken } from '@/utils/sso';
|
||||||
import { createListCollection } from '@chakra-ui/react';
|
|
||||||
|
|
||||||
const TOKEN_KEY = 'karusic-token-key-storage';
|
const TOKEN_KEY = 'karusic-token-key-storage';
|
||||||
|
|
||||||
export const USERS_COLLECTION = createListCollection({
|
export const USERS_COLLECTION = createListCollection({
|
||||||
items: [
|
items: [
|
||||||
{ label: "admin", value: "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiIxIiwiYXBwbGljYXRpb24iOiJrYXJ1c2ljIiwiaXNzIjoiS2FyQXV0aCIsInJpZ2h0Ijp7ImthcnVzaWMiOnsiQURNSU4iOnRydWUsIlVTRVIiOnRydWV9fSwibG9naW4iOiJIZWVyb1l1aSIsImV4cCI6MTcyNDIwNjc5NCwiaWF0IjoxNzI0MTY2ODM0fQ.TEST_SIGNATURE_FOR_LOCAL_TEST_AND_TEST_E2E" },
|
{
|
||||||
{ label: "NO_USER", value: "svelte" },
|
label: 'admin',
|
||||||
|
value:
|
||||||
|
'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiIxIiwiYXBwbGljYXRpb24iOiJrYXJ1c2ljIiwiaXNzIjoiS2FyQXV0aCIsInJpZ2h0Ijp7ImthcnVzaWMiOnsiQURNSU4iOnRydWUsIlVTRVIiOnRydWV9fSwibG9naW4iOiJIZWVyb1l1aSIsImV4cCI6MTcyNDIwNjc5NCwiaWF0IjoxNzI0MTY2ODM0fQ.TEST_SIGNATURE_FOR_LOCAL_TEST_AND_TEST_E2E',
|
||||||
|
},
|
||||||
|
{ label: 'NO_USER', value: 'svelte' },
|
||||||
],
|
],
|
||||||
})
|
});
|
||||||
export const USERS = {
|
export const USERS = {
|
||||||
admin:
|
admin:
|
||||||
'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiIxIiwiYXBwbGljYXRpb24iOiJrYXJ1c2ljIiwiaXNzIjoiS2FyQXV0aCIsInJpZ2h0Ijp7ImthcnVzaWMiOnsiQURNSU4iOnRydWUsIlVTRVIiOnRydWV9fSwibG9naW4iOiJIZWVyb1l1aSIsImV4cCI6MTcyNDIwNjc5NCwiaWF0IjoxNzI0MTY2ODM0fQ.TEST_SIGNATURE_FOR_LOCAL_TEST_AND_TEST_E2E',
|
'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiIxIiwiYXBwbGljYXRpb24iOiJrYXJ1c2ljIiwiaXNzIjoiS2FyQXV0aCIsInJpZ2h0Ijp7ImthcnVzaWMiOnsiQURNSU4iOnRydWUsIlVTRVIiOnRydWV9fSwibG9naW4iOiJIZWVyb1l1aSIsImV4cCI6MTcyNDIwNjc5NCwiaWF0IjoxNzI0MTY2ODM0fQ.TEST_SIGNATURE_FOR_LOCAL_TEST_AND_TEST_E2E',
|
||||||
@ -57,20 +69,26 @@ export const useSessionServiceWrapped = (): SessionServiceProps => {
|
|||||||
const [state, setState] = useState<SessionState>(SessionState.NO_USER);
|
const [state, setState] = useState<SessionState>(SessionState.NO_USER);
|
||||||
const [config, setConfig] = useState<UserMe | undefined>(undefined);
|
const [config, setConfig] = useState<UserMe | undefined>(undefined);
|
||||||
|
|
||||||
|
useEffectOnce(() => {
|
||||||
|
setErrorApiGlobalCallback((response: Response) => {
|
||||||
|
if (response.status == 401) {
|
||||||
|
console.error('Detect 401 error ==> remove token');
|
||||||
|
clearToken();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
const updateRight = useCallback(() => {
|
const updateRight = useCallback(() => {
|
||||||
|
console.log('update right...');
|
||||||
if (isBrowser) {
|
if (isBrowser) {
|
||||||
console.log('Detect a new token...');
|
console.log('Detect a new token...');
|
||||||
setState(SessionState.NO_USER);
|
|
||||||
setConfig(undefined);
|
|
||||||
if (token === undefined) {
|
if (token === undefined) {
|
||||||
console.log(` ==> No User`);
|
console.log(` ==> No User`);
|
||||||
setState(SessionState.NO_USER);
|
setState(SessionState.NO_USER);
|
||||||
|
setConfig(undefined);
|
||||||
localStorage.removeItem(TOKEN_KEY);
|
localStorage.removeItem(TOKEN_KEY);
|
||||||
} else if (token === '__LOGOUT__') {
|
} else {
|
||||||
console.log(` ==> disconnection: ${token}`);
|
|
||||||
setState(SessionState.DISCONNECT);
|
|
||||||
localStorage.removeItem(TOKEN_KEY);
|
|
||||||
} else if (!['__LOGOUT__', '__FAIL__', '__CANCEL__'].includes(token)) {
|
|
||||||
console.log(' ==> Login ... (try to keep right)');
|
console.log(' ==> Login ... (try to keep right)');
|
||||||
setState(SessionState.CONNECTING);
|
setState(SessionState.CONNECTING);
|
||||||
localStorage.setItem(TOKEN_KEY, token);
|
localStorage.setItem(TOKEN_KEY, token);
|
||||||
@ -84,6 +102,7 @@ export const useSessionServiceWrapped = (): SessionServiceProps => {
|
|||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
setState(SessionState.CONNECTION_FAIL);
|
setState(SessionState.CONNECTION_FAIL);
|
||||||
|
setConfig(undefined);
|
||||||
//console.log(` ==> Fail to get right: '${error}'`);
|
//console.log(` ==> Fail to get right: '${error}'`);
|
||||||
localStorage.removeItem(TOKEN_KEY);
|
localStorage.removeItem(TOKEN_KEY);
|
||||||
});
|
});
|
||||||
@ -91,7 +110,10 @@ export const useSessionServiceWrapped = (): SessionServiceProps => {
|
|||||||
}
|
}
|
||||||
}, [localStorage, parseToken, token]);
|
}, [localStorage, parseToken, token]);
|
||||||
const setTokenLocal = useCallback(
|
const setTokenLocal = useCallback(
|
||||||
(token: string) => {
|
(token?: string) => {
|
||||||
|
if (token ? token.startsWith('__') : false) {
|
||||||
|
token = undefined;
|
||||||
|
}
|
||||||
setToken(token);
|
setToken(token);
|
||||||
updateRight();
|
updateRight();
|
||||||
},
|
},
|
||||||
|
File diff suppressed because one or more lines are too long
@ -5,9 +5,6 @@ import { defineConfig } from 'vite';
|
|||||||
// https://vitejs.dev/config/
|
// https://vitejs.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [react()],
|
plugins: [react()],
|
||||||
define: {
|
|
||||||
'process.env.NODE_ENV': '"development"', // Forcer le mode dev pour éviter l'erreur
|
|
||||||
},
|
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
'@': path.resolve(__dirname, './src'),
|
'@': path.resolve(__dirname, './src'),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user