From d9e2b5e1ee8c3ca4623675564d75c4dc566d7593 Mon Sep 17 00:00:00 2001 From: amvanbaren Date: Tue, 27 Sep 2022 11:19:22 +0300 Subject: [PATCH] Web extension resources return incorrect MIME type Use [Content_Types].xml to set FileResource contentType Add test case for default content type: application/octet-stream --- .../eclipse/openvsx/ExtensionProcessor.java | 57 +++++- .../eclipse/openvsx/LocalRegistryService.java | 2 +- .../openvsx/adapter/LocalVSCodeService.java | 4 +- .../eclipse/openvsx/dto/FileResourceDTO.java | 18 +- .../openvsx/entities/FileResource.java | 10 + .../FileResourceDTORepository.java | 20 +- .../storage/AzureBlobStorageService.java | 14 +- .../storage/GoogleCloudStorageService.java | 14 +- .../eclipse/openvsx/storage/StorageUtil.java | 13 -- .../openvsx/storage/StorageUtilService.java | 15 +- .../org/eclipse/openvsx/jooq/Indexes.java | 3 + .../org/eclipse/openvsx/jooq/Keys.java | 4 + .../org/eclipse/openvsx/jooq/Public.java | 7 + .../org/eclipse/openvsx/jooq/Tables.java | 6 + .../AdminStatisticsExtensionsByRating.java | 7 +- ...isticsPublishersByExtensionsPublished.java | 7 +- .../eclipse/openvsx/jooq/tables/Download.java | 7 + .../openvsx/jooq/tables/Extension.java | 7 +- .../openvsx/jooq/tables/ExtensionReview.java | 13 +- .../openvsx/jooq/tables/ExtensionVersion.java | 13 +- .../tables/ExtractResourcesMigrationItem.java | 146 ++++++++++++++ .../openvsx/jooq/tables/FileResource.java | 22 ++- .../jooq/tables/NamespaceMembership.java | 13 +- .../openvsx/jooq/tables/PersistedLog.java | 7 +- .../jooq/tables/PersonalAccessToken.java | 7 +- .../jooq/tables/SpringSessionAttributes.java | 7 +- .../ExtractResourcesMigrationItemRecord.java | 180 ++++++++++++++++++ .../tables/records/FileResourceRecord.java | 57 +++++- .../V1_26__FileResource_ContentType.sql | 1 + .../org/eclipse/openvsx/RegistryAPITest.java | 3 + .../openvsx/adapter/VSCodeAPITest.java | 167 +++++++++++++--- 31 files changed, 753 insertions(+), 98 deletions(-) create mode 100644 server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/ExtractResourcesMigrationItem.java create mode 100644 server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/records/ExtractResourcesMigrationItemRecord.java create mode 100644 server/src/main/resources/db/migration/V1_26__FileResource_ContentType.sql diff --git a/server/src/main/java/org/eclipse/openvsx/ExtensionProcessor.java b/server/src/main/java/org/eclipse/openvsx/ExtensionProcessor.java index a48660afc..ac64fcee4 100644 --- a/server/src/main/java/org/eclipse/openvsx/ExtensionProcessor.java +++ b/server/src/main/java/org/eclipse/openvsx/ExtensionProcessor.java @@ -9,10 +9,7 @@ ********************************************************************************/ package org.eclipse.openvsx; -import java.io.EOFException; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; +import java.io.*; import java.util.*; import java.util.function.Consumer; import java.util.regex.Pattern; @@ -40,6 +37,11 @@ import org.slf4j.LoggerFactory; import org.springframework.data.util.Pair; import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; /** * Processes uploaded extension files and extracts their metadata. @@ -301,6 +303,7 @@ public List getResources(ExtensionVersion extVersion) { public List getResources(ExtensionVersion extVersion, List excludes) { var resources = new ArrayList(); + var contentTypes = loadContentTypes(resources); if(!excludes.contains(FileResource.RESOURCE)) { resources.addAll(getAllResources(extVersion).collect(Collectors.toList())); } @@ -335,7 +338,9 @@ public List getResources(ExtensionVersion extVersion, List resources.add(icon); } - return resources; + return resources.stream() + .map(resource -> setContentType(resource, contentTypes)) + .collect(Collectors.toList()); } public void processEachResource(ExtensionVersion extVersion, Consumer processor) { @@ -461,6 +466,48 @@ public FileResource getLicense(ExtensionVersion extVersion) { return license; } + private Map loadContentTypes(List resources) { + var contentTypes = resources.stream() + .filter(r -> r.getName().equals("[Content_Types].xml")) + .findFirst() + .map(FileResource::getContent) + .map(this::parseContentTypesXml) + .orElse(new HashMap<>()); + + contentTypes.putIfAbsent(".vsix", "application/zip"); + return contentTypes; + } + + private Map parseContentTypesXml(byte[] content) { + try (var input = new ByteArrayInputStream(content)) { + var contentTypes = new HashMap(); + var document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(input); + var elements = document.getDocumentElement().getElementsByTagName("Default"); + for(var i = 0; i < elements.getLength(); i++) { + var element = elements.item(i); + var attributes = element.getAttributes(); + var extension = attributes.getNamedItem("Extension").getTextContent(); + var contentType = attributes.getNamedItem("ContentType").getTextContent(); + contentTypes.put(extension, contentType); + } + + return contentTypes; + } catch (IOException | ParserConfigurationException | SAXException e) { + logger.error("failed to read content types", e); + return null; + } + } + + private FileResource setContentType(FileResource resource, Map contentTypes) { + var resourceName = Optional.ofNullable(resource.getName()).orElse(""); + var fileExtensionIndex = resourceName.lastIndexOf('.'); + var fileExtension = fileExtensionIndex != -1 ? resourceName.substring(fileExtensionIndex) : ""; + var contentType = contentTypes.getOrDefault(fileExtension, MediaType.APPLICATION_OCTET_STREAM_VALUE); + + resource.setContentType(contentType); + return resource; + } + private void detectLicense(byte[] content, ExtensionVersion extVersion) { if (Strings.isNullOrEmpty(extVersion.getLicense())) { var detection = new LicenseDetection(); diff --git a/server/src/main/java/org/eclipse/openvsx/LocalRegistryService.java b/server/src/main/java/org/eclipse/openvsx/LocalRegistryService.java index 8e0d8ae9c..dd90bf0ef 100644 --- a/server/src/main/java/org/eclipse/openvsx/LocalRegistryService.java +++ b/server/src/main/java/org/eclipse/openvsx/LocalRegistryService.java @@ -173,7 +173,7 @@ public ResponseEntity getFile(String namespace, String extensionName, St if (resource.getType().equals(DOWNLOAD)) storageUtil.increaseDownloadCount(extVersion, resource); if (resource.getStorageType().equals(FileResource.STORAGE_DB)) { - var headers = storageUtil.getFileResponseHeaders(fileName); + var headers = storageUtil.getFileResponseHeaders(resource); return new ResponseEntity<>(resource.getContent(), headers, HttpStatus.OK); } else { return ResponseEntity.status(HttpStatus.FOUND) diff --git a/server/src/main/java/org/eclipse/openvsx/adapter/LocalVSCodeService.java b/server/src/main/java/org/eclipse/openvsx/adapter/LocalVSCodeService.java index 7e8076d8f..1df38c879 100644 --- a/server/src/main/java/org/eclipse/openvsx/adapter/LocalVSCodeService.java +++ b/server/src/main/java/org/eclipse/openvsx/adapter/LocalVSCodeService.java @@ -304,7 +304,7 @@ public ResponseEntity getAsset( storageUtil.increaseDownloadCount(extVersion, resource); } if (resource.getStorageType().equals(FileResource.STORAGE_DB)) { - var headers = storageUtil.getFileResponseHeaders(resource.getName()); + var headers = storageUtil.getFileResponseHeaders(resource); return new ResponseEntity<>(resource.getContent(), headers, HttpStatus.OK); } else { return ResponseEntity.status(HttpStatus.FOUND) @@ -416,7 +416,7 @@ private ResponseEntity browseFile( String version ) { if (resource.getStorageType().equals(FileResource.STORAGE_DB)) { - var headers = storageUtil.getFileResponseHeaders(resource.getName()); + var headers = storageUtil.getFileResponseHeaders(resource); return new ResponseEntity<>(resource.getContent(), headers, HttpStatus.OK); } else { var namespace = new Namespace(); diff --git a/server/src/main/java/org/eclipse/openvsx/dto/FileResourceDTO.java b/server/src/main/java/org/eclipse/openvsx/dto/FileResourceDTO.java index c545be3b6..ea57ad699 100644 --- a/server/src/main/java/org/eclipse/openvsx/dto/FileResourceDTO.java +++ b/server/src/main/java/org/eclipse/openvsx/dto/FileResourceDTO.java @@ -11,8 +11,6 @@ import org.eclipse.openvsx.entities.FileResource; -import java.util.Objects; - public class FileResourceDTO { private final long extensionVersionId; @@ -23,11 +21,21 @@ public class FileResourceDTO { private final String type; private String storageType; private byte[] content; - - public FileResourceDTO(long id, long extensionVersionId, String name, String type, String storageType, byte[] content) { + private String contentType; + + public FileResourceDTO( + long id, + long extensionVersionId, + String name, + String type, + String storageType, + byte[] content, + String contentType + ) { this(id, extensionVersionId, name, type); this.storageType = storageType; this.content = content; + this.contentType = contentType; } public FileResourceDTO(long id, long extensionVersionId, String name, String type) { @@ -73,6 +81,8 @@ public byte[] getContent() { return content; } + public String getContentType() { return contentType; } + public boolean isWebResource() { return type.equals(FileResource.RESOURCE) && name.startsWith("extension/"); } diff --git a/server/src/main/java/org/eclipse/openvsx/entities/FileResource.java b/server/src/main/java/org/eclipse/openvsx/entities/FileResource.java index e8b71b858..5109798e5 100644 --- a/server/src/main/java/org/eclipse/openvsx/entities/FileResource.java +++ b/server/src/main/java/org/eclipse/openvsx/entities/FileResource.java @@ -45,6 +45,8 @@ public class FileResource { @Basic(fetch = FetchType.LAZY) byte[] content; + String contentType; + @Column(length = 32) String storageType; @@ -89,6 +91,14 @@ public void setContent(byte[] content) { this.content = content; } + public String getContentType() { + return contentType; + } + + public void setContentType(String contentType) { + this.contentType = contentType; + } + public String getStorageType() { return storageType; } diff --git a/server/src/main/java/org/eclipse/openvsx/repositories/FileResourceDTORepository.java b/server/src/main/java/org/eclipse/openvsx/repositories/FileResourceDTORepository.java index 1d5974f16..7c9e3d603 100644 --- a/server/src/main/java/org/eclipse/openvsx/repositories/FileResourceDTORepository.java +++ b/server/src/main/java/org/eclipse/openvsx/repositories/FileResourceDTORepository.java @@ -13,9 +13,6 @@ import org.eclipse.openvsx.entities.FileResource; import org.jooq.DSLContext; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.Repository; -import org.springframework.data.util.Streamable; import org.springframework.stereotype.Component; import java.util.Collection; @@ -30,7 +27,12 @@ public class FileResourceDTORepository { DSLContext dsl; public List findAll(Collection extensionIds, Collection types) { - return dsl.select(FILE_RESOURCE.ID, FILE_RESOURCE.EXTENSION_ID, FILE_RESOURCE.NAME, FILE_RESOURCE.TYPE) + return dsl.select( + FILE_RESOURCE.ID, + FILE_RESOURCE.EXTENSION_ID, + FILE_RESOURCE.NAME, + FILE_RESOURCE.TYPE + ) .from(FILE_RESOURCE) .where(FILE_RESOURCE.EXTENSION_ID.in(extensionIds)) .and(FILE_RESOURCE.TYPE.in(types)) @@ -38,7 +40,15 @@ public List findAll(Collection extensionIds, Collection findAllResources(long extVersionId, String prefix) { - return dsl.select(FILE_RESOURCE.ID, FILE_RESOURCE.EXTENSION_ID, FILE_RESOURCE.NAME, FILE_RESOURCE.TYPE, FILE_RESOURCE.STORAGE_TYPE, FILE_RESOURCE.CONTENT) + return dsl.select( + FILE_RESOURCE.ID, + FILE_RESOURCE.EXTENSION_ID, + FILE_RESOURCE.NAME, + FILE_RESOURCE.TYPE, + FILE_RESOURCE.STORAGE_TYPE, + FILE_RESOURCE.CONTENT, + FILE_RESOURCE.CONTENT_TYPE + ) .from(FILE_RESOURCE) .where(FILE_RESOURCE.TYPE.eq(FileResource.RESOURCE)) .and(FILE_RESOURCE.EXTENSION_ID.eq(extVersionId)) diff --git a/server/src/main/java/org/eclipse/openvsx/storage/AzureBlobStorageService.java b/server/src/main/java/org/eclipse/openvsx/storage/AzureBlobStorageService.java index 78c169193..49bf56cc4 100644 --- a/server/src/main/java/org/eclipse/openvsx/storage/AzureBlobStorageService.java +++ b/server/src/main/java/org/eclipse/openvsx/storage/AzureBlobStorageService.java @@ -64,19 +64,21 @@ public void uploadFile(FileResource resource) { + blobName + ": missing Azure blob service endpoint"); } - uploadFile(resource.getContent(), resource.getName(), blobName); + uploadFile(resource, blobName); } - protected void uploadFile(byte[] content, String fileName, String blobName) { + protected void uploadFile(FileResource resource, String blobName) { var blobClient = getContainerClient().getBlobClient(blobName); var headers = new BlobHttpHeaders(); - headers.setContentType(StorageUtil.getFileType(fileName).toString()); - if (fileName.endsWith(".vsix")) { - headers.setContentDisposition("attachment; filename=\"" + fileName + "\""); + headers.setContentType(resource.getContentType()); + if (resource.getName().endsWith(".vsix")) { + headers.setContentDisposition("attachment; filename=\"" + resource.getName() + "\""); } else { - var cacheControl = StorageUtil.getCacheControl(fileName); + var cacheControl = StorageUtil.getCacheControl(resource.getName()); headers.setCacheControl(cacheControl.getHeaderValue()); } + + var content = resource.getContent(); try (var dataStream = new ByteArrayInputStream(content)) { blobClient.upload(dataStream, content.length, true); blobClient.setHttpHeaders(headers); diff --git a/server/src/main/java/org/eclipse/openvsx/storage/GoogleCloudStorageService.java b/server/src/main/java/org/eclipse/openvsx/storage/GoogleCloudStorageService.java index 979ea8ceb..8c74966ed 100644 --- a/server/src/main/java/org/eclipse/openvsx/storage/GoogleCloudStorageService.java +++ b/server/src/main/java/org/eclipse/openvsx/storage/GoogleCloudStorageService.java @@ -64,19 +64,19 @@ public void uploadFile(FileResource resource) { + objectId + ": missing Google bucket id"); } - uploadFile(resource.getContent(), resource.getName(), objectId); + uploadFile(resource, objectId); } - protected void uploadFile(byte[] content, String fileName, String objectId) { + protected void uploadFile(FileResource resource, String objectId) { var blobInfoBuilder = BlobInfo.newBuilder(BlobId.of(bucketId, objectId)) - .setContentType(StorageUtil.getFileType(fileName).toString()); - if (fileName.endsWith(".vsix")) { - blobInfoBuilder.setContentDisposition("attachment; filename=\"" + fileName + "\""); + .setContentType(resource.getContentType()); + if (resource.getName().endsWith(".vsix")) { + blobInfoBuilder.setContentDisposition("attachment; filename=\"" + resource.getName() + "\""); } else { - var cacheControl = StorageUtil.getCacheControl(fileName); + var cacheControl = StorageUtil.getCacheControl(resource.getName()); blobInfoBuilder.setCacheControl(cacheControl.getHeaderValue()); } - getStorage().create(blobInfoBuilder.build(), content); + getStorage().create(blobInfoBuilder.build(), resource.getContent()); } @Override diff --git a/server/src/main/java/org/eclipse/openvsx/storage/StorageUtil.java b/server/src/main/java/org/eclipse/openvsx/storage/StorageUtil.java index 63e897fc4..a5b83c804 100644 --- a/server/src/main/java/org/eclipse/openvsx/storage/StorageUtil.java +++ b/server/src/main/java/org/eclipse/openvsx/storage/StorageUtil.java @@ -11,26 +11,13 @@ package org.eclipse.openvsx.storage; import org.springframework.http.CacheControl; -import org.springframework.http.MediaType; -import java.net.URLConnection; import java.util.concurrent.TimeUnit; class StorageUtil { private StorageUtil(){} - static MediaType getFileType(String fileName) { - if (fileName.endsWith(".vsix")) - return MediaType.APPLICATION_OCTET_STREAM; - if (fileName.endsWith(".json")) - return MediaType.APPLICATION_JSON; - var contentType = URLConnection.guessContentTypeFromName(fileName); - if (contentType != null) - return MediaType.parseMediaType(contentType); - return MediaType.TEXT_PLAIN; - } - static CacheControl getCacheControl(String fileName) { // Files are requested with a version string in the URL, so their content cannot change return CacheControl.maxAge(30, TimeUnit.DAYS).cachePublic(); diff --git a/server/src/main/java/org/eclipse/openvsx/storage/StorageUtilService.java b/server/src/main/java/org/eclipse/openvsx/storage/StorageUtilService.java index a72d8c9bb..4ab87e194 100644 --- a/server/src/main/java/org/eclipse/openvsx/storage/StorageUtilService.java +++ b/server/src/main/java/org/eclipse/openvsx/storage/StorageUtilService.java @@ -10,6 +10,8 @@ package org.eclipse.openvsx.storage; import com.google.common.base.Strings; + +import org.eclipse.openvsx.dto.FileResourceDTO; import com.google.common.collect.Maps; import org.eclipse.openvsx.entities.ExtensionVersion; import org.eclipse.openvsx.entities.FileResource; @@ -19,6 +21,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; import org.springframework.stereotype.Component; import javax.transaction.Transactional; @@ -170,9 +173,17 @@ public void increaseDownloadCount(ExtensionVersion extVersion, FileResource reso downloadCountService.increaseDownloadCount(extVersion, resource, List.of(TimeUtil.getCurrentUTC())); } - public HttpHeaders getFileResponseHeaders(String fileName) { + public HttpHeaders getFileResponseHeaders(FileResource resource) { + return getFileResponseHeaders(resource.getName(), resource.getContentType()); + } + + public HttpHeaders getFileResponseHeaders(FileResourceDTO resource) { + return getFileResponseHeaders(resource.getName(), resource.getContentType()); + } + + private HttpHeaders getFileResponseHeaders(String fileName, String contentType) { var headers = new HttpHeaders(); - headers.setContentType(StorageUtil.getFileType(fileName)); + headers.setContentType(MediaType.parseMediaType(contentType)); if (fileName.endsWith(".vsix")) { headers.add("Content-Disposition", "attachment; filename=\"" + fileName + "\""); } else { diff --git a/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/Indexes.java b/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/Indexes.java index a0f80e314..6c6ed0e15 100644 --- a/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/Indexes.java +++ b/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/Indexes.java @@ -4,6 +4,7 @@ package org.eclipse.openvsx.jooq; +import org.eclipse.openvsx.jooq.tables.Download; import org.eclipse.openvsx.jooq.tables.Extension; import org.eclipse.openvsx.jooq.tables.ExtensionReview; import org.eclipse.openvsx.jooq.tables.ExtensionVersion; @@ -28,12 +29,14 @@ public class Indexes { // INDEX definitions // ------------------------------------------------------------------------- + public static final Index DOWNLOAD_TIMESTAMP_BRIN_IDX = Internal.createIndex(DSL.name("download_timestamp_brin_idx"), Download.DOWNLOAD, new OrderField[] { Download.DOWNLOAD.TIMESTAMP }, false); public static final Index EXTENSION__NAMESPACE_ID__IDX = Internal.createIndex(DSL.name("extension__namespace_id__idx"), Extension.EXTENSION, new OrderField[] { Extension.EXTENSION.NAMESPACE_ID }, false); public static final Index EXTENSION_REVIEW__EXTENSION_ID__IDX = Internal.createIndex(DSL.name("extension_review__extension_id__idx"), ExtensionReview.EXTENSION_REVIEW, new OrderField[] { ExtensionReview.EXTENSION_REVIEW.EXTENSION_ID }, false); public static final Index EXTENSION_REVIEW__USER_ID__IDX = Internal.createIndex(DSL.name("extension_review__user_id__idx"), ExtensionReview.EXTENSION_REVIEW, new OrderField[] { ExtensionReview.EXTENSION_REVIEW.USER_ID }, false); public static final Index EXTENSION_VERSION__EXTENSION_ID__IDX = Internal.createIndex(DSL.name("extension_version__extension_id__idx"), ExtensionVersion.EXTENSION_VERSION, new OrderField[] { ExtensionVersion.EXTENSION_VERSION.EXTENSION_ID }, false); public static final Index EXTENSION_VERSION__PUBLISHED_WITH_ID__IDX = Internal.createIndex(DSL.name("extension_version__published_with_id__idx"), ExtensionVersion.EXTENSION_VERSION, new OrderField[] { ExtensionVersion.EXTENSION_VERSION.PUBLISHED_WITH_ID }, false); public static final Index FILE_RESOURCE_EXTENSION_IDX = Internal.createIndex(DSL.name("file_resource_extension_idx"), FileResource.FILE_RESOURCE, new OrderField[] { FileResource.FILE_RESOURCE.EXTENSION_ID }, false); + public static final Index FILE_RESOURCE_TYPE_IDX = Internal.createIndex(DSL.name("file_resource_type_idx"), FileResource.FILE_RESOURCE, new OrderField[] { FileResource.FILE_RESOURCE.TYPE }, false); public static final Index FLYWAY_SCHEMA_HISTORY_S_IDX = Internal.createIndex(DSL.name("flyway_schema_history_s_idx"), FlywaySchemaHistory.FLYWAY_SCHEMA_HISTORY, new OrderField[] { FlywaySchemaHistory.FLYWAY_SCHEMA_HISTORY.SUCCESS }, false); public static final Index NAMESPACE_MEMBERSHIP__NAMESPACE__IDX = Internal.createIndex(DSL.name("namespace_membership__namespace__idx"), NamespaceMembership.NAMESPACE_MEMBERSHIP, new OrderField[] { NamespaceMembership.NAMESPACE_MEMBERSHIP.NAMESPACE }, false); public static final Index NAMESPACE_MEMBERSHIP__USER_DATA__IDX = Internal.createIndex(DSL.name("namespace_membership__user_data__idx"), NamespaceMembership.NAMESPACE_MEMBERSHIP, new OrderField[] { NamespaceMembership.NAMESPACE_MEMBERSHIP.USER_DATA }, false); diff --git a/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/Keys.java b/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/Keys.java index cc0544e41..183920cf4 100644 --- a/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/Keys.java +++ b/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/Keys.java @@ -13,6 +13,7 @@ import org.eclipse.openvsx.jooq.tables.Extension; import org.eclipse.openvsx.jooq.tables.ExtensionReview; import org.eclipse.openvsx.jooq.tables.ExtensionVersion; +import org.eclipse.openvsx.jooq.tables.ExtractResourcesMigrationItem; import org.eclipse.openvsx.jooq.tables.FileResource; import org.eclipse.openvsx.jooq.tables.FlywaySchemaHistory; import org.eclipse.openvsx.jooq.tables.Namespace; @@ -32,6 +33,7 @@ import org.eclipse.openvsx.jooq.tables.records.ExtensionRecord; import org.eclipse.openvsx.jooq.tables.records.ExtensionReviewRecord; import org.eclipse.openvsx.jooq.tables.records.ExtensionVersionRecord; +import org.eclipse.openvsx.jooq.tables.records.ExtractResourcesMigrationItemRecord; import org.eclipse.openvsx.jooq.tables.records.FileResourceRecord; import org.eclipse.openvsx.jooq.tables.records.FlywaySchemaHistoryRecord; import org.eclipse.openvsx.jooq.tables.records.NamespaceMembershipRecord; @@ -69,6 +71,8 @@ public class Keys { public static final UniqueKey EXTENSION_REVIEW_PKEY = Internal.createUniqueKey(ExtensionReview.EXTENSION_REVIEW, DSL.name("extension_review_pkey"), new TableField[] { ExtensionReview.EXTENSION_REVIEW.ID }, true); public static final UniqueKey EXTENSION_VERSION_PKEY = Internal.createUniqueKey(ExtensionVersion.EXTENSION_VERSION, DSL.name("extension_version_pkey"), new TableField[] { ExtensionVersion.EXTENSION_VERSION.ID }, true); public static final UniqueKey UNIQUE_EXTENSION_VERSION = Internal.createUniqueKey(ExtensionVersion.EXTENSION_VERSION, DSL.name("unique_extension_version"), new TableField[] { ExtensionVersion.EXTENSION_VERSION.EXTENSION_ID, ExtensionVersion.EXTENSION_VERSION.TARGET_PLATFORM, ExtensionVersion.EXTENSION_VERSION.VERSION }, true); + public static final UniqueKey EXTRACT_RESOURCES_MIGRATION_ITEM_PKEY = Internal.createUniqueKey(ExtractResourcesMigrationItem.EXTRACT_RESOURCES_MIGRATION_ITEM, DSL.name("extract_resources_migration_item_pkey"), new TableField[] { ExtractResourcesMigrationItem.EXTRACT_RESOURCES_MIGRATION_ITEM.ID }, true); + public static final UniqueKey UNIQUE_EXTENSION_ID = Internal.createUniqueKey(ExtractResourcesMigrationItem.EXTRACT_RESOURCES_MIGRATION_ITEM, DSL.name("unique_extension_id"), new TableField[] { ExtractResourcesMigrationItem.EXTRACT_RESOURCES_MIGRATION_ITEM.EXTENSION_ID }, true); public static final UniqueKey FILE_RESOURCE_PKEY = Internal.createUniqueKey(FileResource.FILE_RESOURCE, DSL.name("file_resource_pkey"), new TableField[] { FileResource.FILE_RESOURCE.ID }, true); public static final UniqueKey FLYWAY_SCHEMA_HISTORY_PK = Internal.createUniqueKey(FlywaySchemaHistory.FLYWAY_SCHEMA_HISTORY, DSL.name("flyway_schema_history_pk"), new TableField[] { FlywaySchemaHistory.FLYWAY_SCHEMA_HISTORY.INSTALLED_RANK }, true); public static final UniqueKey NAMESPACE_PKEY = Internal.createUniqueKey(Namespace.NAMESPACE, DSL.name("namespace_pkey"), new TableField[] { Namespace.NAMESPACE.ID }, true); diff --git a/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/Public.java b/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/Public.java index ed50f6e32..6e03fd43b 100644 --- a/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/Public.java +++ b/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/Public.java @@ -16,6 +16,7 @@ import org.eclipse.openvsx.jooq.tables.Extension; import org.eclipse.openvsx.jooq.tables.ExtensionReview; import org.eclipse.openvsx.jooq.tables.ExtensionVersion; +import org.eclipse.openvsx.jooq.tables.ExtractResourcesMigrationItem; import org.eclipse.openvsx.jooq.tables.FileResource; import org.eclipse.openvsx.jooq.tables.FlywaySchemaHistory; import org.eclipse.openvsx.jooq.tables.Namespace; @@ -90,6 +91,11 @@ public class Public extends SchemaImpl { */ public final ExtensionVersion EXTENSION_VERSION = ExtensionVersion.EXTENSION_VERSION; + /** + * The table public.extract_resources_migration_item. + */ + public final ExtractResourcesMigrationItem EXTRACT_RESOURCES_MIGRATION_ITEM = ExtractResourcesMigrationItem.EXTRACT_RESOURCES_MIGRATION_ITEM; + /** * The table public.file_resource. */ @@ -174,6 +180,7 @@ public final List> getTables() { Extension.EXTENSION, ExtensionReview.EXTENSION_REVIEW, ExtensionVersion.EXTENSION_VERSION, + ExtractResourcesMigrationItem.EXTRACT_RESOURCES_MIGRATION_ITEM, FileResource.FILE_RESOURCE, FlywaySchemaHistory.FLYWAY_SCHEMA_HISTORY, Namespace.NAMESPACE, diff --git a/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/Tables.java b/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/Tables.java index 4334e9223..d57a85c2d 100644 --- a/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/Tables.java +++ b/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/Tables.java @@ -13,6 +13,7 @@ import org.eclipse.openvsx.jooq.tables.Extension; import org.eclipse.openvsx.jooq.tables.ExtensionReview; import org.eclipse.openvsx.jooq.tables.ExtensionVersion; +import org.eclipse.openvsx.jooq.tables.ExtractResourcesMigrationItem; import org.eclipse.openvsx.jooq.tables.FileResource; import org.eclipse.openvsx.jooq.tables.FlywaySchemaHistory; import org.eclipse.openvsx.jooq.tables.Namespace; @@ -76,6 +77,11 @@ public class Tables { */ public static final ExtensionVersion EXTENSION_VERSION = ExtensionVersion.EXTENSION_VERSION; + /** + * The table public.extract_resources_migration_item. + */ + public static final ExtractResourcesMigrationItem EXTRACT_RESOURCES_MIGRATION_ITEM = ExtractResourcesMigrationItem.EXTRACT_RESOURCES_MIGRATION_ITEM; + /** * The table public.file_resource. */ diff --git a/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/AdminStatisticsExtensionsByRating.java b/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/AdminStatisticsExtensionsByRating.java index 04d3cb840..ea408cbea 100644 --- a/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/AdminStatisticsExtensionsByRating.java +++ b/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/AdminStatisticsExtensionsByRating.java @@ -103,8 +103,13 @@ public Schema getSchema() { return Arrays.>asList(Keys.ADMIN_STATISTICS_EXTENSIONS_BY_RATING__ADMIN_STATISTICS_EXTENSIONS_BY_RATING_FKEY); } + private transient AdminStatistics _adminStatistics; + public AdminStatistics adminStatistics() { - return new AdminStatistics(this, Keys.ADMIN_STATISTICS_EXTENSIONS_BY_RATING__ADMIN_STATISTICS_EXTENSIONS_BY_RATING_FKEY); + if (_adminStatistics == null) + _adminStatistics = new AdminStatistics(this, Keys.ADMIN_STATISTICS_EXTENSIONS_BY_RATING__ADMIN_STATISTICS_EXTENSIONS_BY_RATING_FKEY); + + return _adminStatistics; } @Override diff --git a/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/AdminStatisticsPublishersByExtensionsPublished.java b/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/AdminStatisticsPublishersByExtensionsPublished.java index 57592196f..46e554e11 100644 --- a/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/AdminStatisticsPublishersByExtensionsPublished.java +++ b/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/AdminStatisticsPublishersByExtensionsPublished.java @@ -103,8 +103,13 @@ public Schema getSchema() { return Arrays.>asList(Keys.ADMIN_STATISTICS_PUBLISHERS_BY_EXTENSIONS_PUBLISHED__ADMIN_STATISTICS_PUBLISHERS_BY_EXTENSIONS_PUBLISHED_FKEY); } + private transient AdminStatistics _adminStatistics; + public AdminStatistics adminStatistics() { - return new AdminStatistics(this, Keys.ADMIN_STATISTICS_PUBLISHERS_BY_EXTENSIONS_PUBLISHED__ADMIN_STATISTICS_PUBLISHERS_BY_EXTENSIONS_PUBLISHED_FKEY); + if (_adminStatistics == null) + _adminStatistics = new AdminStatistics(this, Keys.ADMIN_STATISTICS_PUBLISHERS_BY_EXTENSIONS_PUBLISHED__ADMIN_STATISTICS_PUBLISHERS_BY_EXTENSIONS_PUBLISHED_FKEY); + + return _adminStatistics; } @Override diff --git a/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/Download.java b/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/Download.java index bef8680f3..55b29733e 100644 --- a/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/Download.java +++ b/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/Download.java @@ -8,11 +8,13 @@ import java.util.Arrays; import java.util.List; +import org.eclipse.openvsx.jooq.Indexes; import org.eclipse.openvsx.jooq.Keys; import org.eclipse.openvsx.jooq.Public; import org.eclipse.openvsx.jooq.tables.records.DownloadRecord; import org.jooq.Field; import org.jooq.ForeignKey; +import org.jooq.Index; import org.jooq.Name; import org.jooq.Record; import org.jooq.Row4; @@ -105,6 +107,11 @@ public Schema getSchema() { return Public.PUBLIC; } + @Override + public List getIndexes() { + return Arrays.asList(Indexes.DOWNLOAD_TIMESTAMP_BRIN_IDX); + } + @Override public UniqueKey getPrimaryKey() { return Keys.DOWNLOAD_PKEY; diff --git a/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/Extension.java b/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/Extension.java index 8d6f25542..1b1a6b0a5 100644 --- a/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/Extension.java +++ b/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/Extension.java @@ -152,8 +152,13 @@ public List> getKeys() { return Arrays.>asList(Keys.EXTENSION__FK64IMD3NRJ67D50TPKJS94NGMN); } + private transient Namespace _namespace; + public Namespace namespace() { - return new Namespace(this, Keys.EXTENSION__FK64IMD3NRJ67D50TPKJS94NGMN); + if (_namespace == null) + _namespace = new Namespace(this, Keys.EXTENSION__FK64IMD3NRJ67D50TPKJS94NGMN); + + return _namespace; } @Override diff --git a/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/ExtensionReview.java b/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/ExtensionReview.java index 957d3806d..b2d4304a8 100644 --- a/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/ExtensionReview.java +++ b/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/ExtensionReview.java @@ -147,12 +147,21 @@ public List> getKeys() { return Arrays.>asList(Keys.EXTENSION_REVIEW__FKGD2DQDC23OGBNOBX8AFJFPNKP, Keys.EXTENSION_REVIEW__FKINJBN9GRK135Y6IK0UT4UJP0W); } + private transient Extension _extension; + private transient UserData _userData; + public Extension extension() { - return new Extension(this, Keys.EXTENSION_REVIEW__FKGD2DQDC23OGBNOBX8AFJFPNKP); + if (_extension == null) + _extension = new Extension(this, Keys.EXTENSION_REVIEW__FKGD2DQDC23OGBNOBX8AFJFPNKP); + + return _extension; } public UserData userData() { - return new UserData(this, Keys.EXTENSION_REVIEW__FKINJBN9GRK135Y6IK0UT4UJP0W); + if (_userData == null) + _userData = new UserData(this, Keys.EXTENSION_REVIEW__FKINJBN9GRK135Y6IK0UT4UJP0W); + + return _userData; } @Override diff --git a/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/ExtensionVersion.java b/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/ExtensionVersion.java index 274e23d0e..ce81ecad4 100644 --- a/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/ExtensionVersion.java +++ b/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/ExtensionVersion.java @@ -231,12 +231,21 @@ public List> getKeys() { return Arrays.>asList(Keys.EXTENSION_VERSION__FKKHS1EC9S9J08FGICQ9PMWU6BT, Keys.EXTENSION_VERSION__FK70KHJ8PM0VACASUIIAQ0W0R80); } + private transient Extension _extension; + private transient PersonalAccessToken _personalAccessToken; + public Extension extension() { - return new Extension(this, Keys.EXTENSION_VERSION__FKKHS1EC9S9J08FGICQ9PMWU6BT); + if (_extension == null) + _extension = new Extension(this, Keys.EXTENSION_VERSION__FKKHS1EC9S9J08FGICQ9PMWU6BT); + + return _extension; } public PersonalAccessToken personalAccessToken() { - return new PersonalAccessToken(this, Keys.EXTENSION_VERSION__FK70KHJ8PM0VACASUIIAQ0W0R80); + if (_personalAccessToken == null) + _personalAccessToken = new PersonalAccessToken(this, Keys.EXTENSION_VERSION__FK70KHJ8PM0VACASUIIAQ0W0R80); + + return _personalAccessToken; } @Override diff --git a/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/ExtractResourcesMigrationItem.java b/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/ExtractResourcesMigrationItem.java new file mode 100644 index 000000000..e6f33d4ce --- /dev/null +++ b/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/ExtractResourcesMigrationItem.java @@ -0,0 +1,146 @@ +/* + * This file is generated by jOOQ. + */ +package org.eclipse.openvsx.jooq.tables; + + +import java.util.Arrays; +import java.util.List; + +import org.eclipse.openvsx.jooq.Keys; +import org.eclipse.openvsx.jooq.Public; +import org.eclipse.openvsx.jooq.tables.records.ExtractResourcesMigrationItemRecord; +import org.jooq.Field; +import org.jooq.ForeignKey; +import org.jooq.Name; +import org.jooq.Record; +import org.jooq.Row3; +import org.jooq.Schema; +import org.jooq.Table; +import org.jooq.TableField; +import org.jooq.TableOptions; +import org.jooq.UniqueKey; +import org.jooq.impl.DSL; +import org.jooq.impl.SQLDataType; +import org.jooq.impl.TableImpl; + + +/** + * This class is generated by jOOQ. + */ +@SuppressWarnings({ "all", "unchecked", "rawtypes" }) +public class ExtractResourcesMigrationItem extends TableImpl { + + private static final long serialVersionUID = 1L; + + /** + * The reference instance of public.extract_resources_migration_item + */ + public static final ExtractResourcesMigrationItem EXTRACT_RESOURCES_MIGRATION_ITEM = new ExtractResourcesMigrationItem(); + + /** + * The class holding records for this type + */ + @Override + public Class getRecordType() { + return ExtractResourcesMigrationItemRecord.class; + } + + /** + * The column public.extract_resources_migration_item.id. + */ + public final TableField ID = createField(DSL.name("id"), SQLDataType.BIGINT.nullable(false), this, ""); + + /** + * The column public.extract_resources_migration_item.extension_id. + */ + public final TableField EXTENSION_ID = createField(DSL.name("extension_id"), SQLDataType.BIGINT.nullable(false), this, ""); + + /** + * The column public.extract_resources_migration_item.migration_scheduled. + */ + public final TableField MIGRATION_SCHEDULED = createField(DSL.name("migration_scheduled"), SQLDataType.BOOLEAN.nullable(false), this, ""); + + private ExtractResourcesMigrationItem(Name alias, Table aliased) { + this(alias, aliased, null); + } + + private ExtractResourcesMigrationItem(Name alias, Table aliased, Field[] parameters) { + super(alias, null, aliased, parameters, DSL.comment(""), TableOptions.table()); + } + + /** + * Create an aliased public.extract_resources_migration_item table reference + */ + public ExtractResourcesMigrationItem(String alias) { + this(DSL.name(alias), EXTRACT_RESOURCES_MIGRATION_ITEM); + } + + /** + * Create an aliased public.extract_resources_migration_item table reference + */ + public ExtractResourcesMigrationItem(Name alias) { + this(alias, EXTRACT_RESOURCES_MIGRATION_ITEM); + } + + /** + * Create a public.extract_resources_migration_item table reference + */ + public ExtractResourcesMigrationItem() { + this(DSL.name("extract_resources_migration_item"), null); + } + + public ExtractResourcesMigrationItem(Table child, ForeignKey key) { + super(child, key, EXTRACT_RESOURCES_MIGRATION_ITEM); + } + + @Override + public Schema getSchema() { + return Public.PUBLIC; + } + + @Override + public UniqueKey getPrimaryKey() { + return Keys.EXTRACT_RESOURCES_MIGRATION_ITEM_PKEY; + } + + @Override + public List> getKeys() { + return Arrays.>asList(Keys.EXTRACT_RESOURCES_MIGRATION_ITEM_PKEY, Keys.UNIQUE_EXTENSION_ID); + } + + @Override + public ExtractResourcesMigrationItem as(String alias) { + return new ExtractResourcesMigrationItem(DSL.name(alias), this); + } + + @Override + public ExtractResourcesMigrationItem as(Name alias) { + return new ExtractResourcesMigrationItem(alias, this); + } + + /** + * Rename this table + */ + @Override + public ExtractResourcesMigrationItem rename(String name) { + return new ExtractResourcesMigrationItem(DSL.name(name), null); + } + + /** + * Rename this table + */ + @Override + public ExtractResourcesMigrationItem rename(Name name) { + return new ExtractResourcesMigrationItem(name, null); + } + + // ------------------------------------------------------------------------- + // Row3 type methods + // ------------------------------------------------------------------------- + + @Override + public Row3 fieldsRow() { + return (Row3) super.fieldsRow(); + } +} diff --git a/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/FileResource.java b/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/FileResource.java index 13ac0947f..44341d510 100644 --- a/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/FileResource.java +++ b/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/FileResource.java @@ -16,7 +16,7 @@ import org.jooq.Index; import org.jooq.Name; import org.jooq.Record; -import org.jooq.Row6; +import org.jooq.Row7; import org.jooq.Schema; import org.jooq.Table; import org.jooq.TableField; @@ -78,6 +78,11 @@ public Class getRecordType() { */ public final TableField STORAGE_TYPE = createField(DSL.name("storage_type"), SQLDataType.VARCHAR(32), this, ""); + /** + * The column public.file_resource.content_type. + */ + public final TableField CONTENT_TYPE = createField(DSL.name("content_type"), SQLDataType.VARCHAR(255), this, ""); + private FileResource(Name alias, Table aliased) { this(alias, aliased, null); } @@ -118,7 +123,7 @@ public Schema getSchema() { @Override public List getIndexes() { - return Arrays.asList(Indexes.FILE_RESOURCE_EXTENSION_IDX); + return Arrays.asList(Indexes.FILE_RESOURCE_EXTENSION_IDX, Indexes.FILE_RESOURCE_TYPE_IDX); } @Override @@ -136,8 +141,13 @@ public List> getKeys() { return Arrays.>asList(Keys.FILE_RESOURCE__FILE_RESOURCE_EXTENSION_FKEY); } + private transient ExtensionVersion _extensionVersion; + public ExtensionVersion extensionVersion() { - return new ExtensionVersion(this, Keys.FILE_RESOURCE__FILE_RESOURCE_EXTENSION_FKEY); + if (_extensionVersion == null) + _extensionVersion = new ExtensionVersion(this, Keys.FILE_RESOURCE__FILE_RESOURCE_EXTENSION_FKEY); + + return _extensionVersion; } @Override @@ -167,11 +177,11 @@ public FileResource rename(Name name) { } // ------------------------------------------------------------------------- - // Row6 type methods + // Row7 type methods // ------------------------------------------------------------------------- @Override - public Row6 fieldsRow() { - return (Row6) super.fieldsRow(); + public Row7 fieldsRow() { + return (Row7) super.fieldsRow(); } } diff --git a/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/NamespaceMembership.java b/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/NamespaceMembership.java index 6e4b9e00a..af323e774 100644 --- a/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/NamespaceMembership.java +++ b/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/NamespaceMembership.java @@ -126,12 +126,21 @@ public List> getKeys() { return Arrays.>asList(Keys.NAMESPACE_MEMBERSHIP__FKGFHWHKNULA6DO2N6WYVQETM3N, Keys.NAMESPACE_MEMBERSHIP__FKNSAMEKUTXYWVSB3S1MJDCJKYP); } + private transient Namespace _namespace; + private transient UserData _userData; + public Namespace namespace() { - return new Namespace(this, Keys.NAMESPACE_MEMBERSHIP__FKGFHWHKNULA6DO2N6WYVQETM3N); + if (_namespace == null) + _namespace = new Namespace(this, Keys.NAMESPACE_MEMBERSHIP__FKGFHWHKNULA6DO2N6WYVQETM3N); + + return _namespace; } public UserData userData() { - return new UserData(this, Keys.NAMESPACE_MEMBERSHIP__FKNSAMEKUTXYWVSB3S1MJDCJKYP); + if (_userData == null) + _userData = new UserData(this, Keys.NAMESPACE_MEMBERSHIP__FKNSAMEKUTXYWVSB3S1MJDCJKYP); + + return _userData; } @Override diff --git a/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/PersistedLog.java b/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/PersistedLog.java index 40cae9057..015e4f6d5 100644 --- a/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/PersistedLog.java +++ b/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/PersistedLog.java @@ -127,8 +127,13 @@ public List> getKeys() { return Arrays.>asList(Keys.PERSISTED_LOG__PERSISTED_LOG_USER_DATA_FKEY); } + private transient UserData _userData; + public UserData userData() { - return new UserData(this, Keys.PERSISTED_LOG__PERSISTED_LOG_USER_DATA_FKEY); + if (_userData == null) + _userData = new UserData(this, Keys.PERSISTED_LOG__PERSISTED_LOG_USER_DATA_FKEY); + + return _userData; } @Override diff --git a/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/PersonalAccessToken.java b/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/PersonalAccessToken.java index de5c8a5aa..5f91c0acc 100644 --- a/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/PersonalAccessToken.java +++ b/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/PersonalAccessToken.java @@ -135,8 +135,13 @@ public List> getKeys() { return Arrays.>asList(Keys.PERSONAL_ACCESS_TOKEN__FKTQJVMHOIG3WTTJ6DL1IBCAJ3L); } + private transient UserData _userData; + public UserData userData() { - return new UserData(this, Keys.PERSONAL_ACCESS_TOKEN__FKTQJVMHOIG3WTTJ6DL1IBCAJ3L); + if (_userData == null) + _userData = new UserData(this, Keys.PERSONAL_ACCESS_TOKEN__FKTQJVMHOIG3WTTJ6DL1IBCAJ3L); + + return _userData; } @Override diff --git a/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/SpringSessionAttributes.java b/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/SpringSessionAttributes.java index cdd3a8799..fdae9bd6a 100644 --- a/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/SpringSessionAttributes.java +++ b/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/SpringSessionAttributes.java @@ -114,8 +114,13 @@ public List> getKeys() { return Arrays.>asList(Keys.SPRING_SESSION_ATTRIBUTES__SPRING_SESSION_ATTRIBUTES_FK); } + private transient SpringSession _springSession; + public SpringSession springSession() { - return new SpringSession(this, Keys.SPRING_SESSION_ATTRIBUTES__SPRING_SESSION_ATTRIBUTES_FK); + if (_springSession == null) + _springSession = new SpringSession(this, Keys.SPRING_SESSION_ATTRIBUTES__SPRING_SESSION_ATTRIBUTES_FK); + + return _springSession; } @Override diff --git a/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/records/ExtractResourcesMigrationItemRecord.java b/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/records/ExtractResourcesMigrationItemRecord.java new file mode 100644 index 000000000..12fc46973 --- /dev/null +++ b/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/records/ExtractResourcesMigrationItemRecord.java @@ -0,0 +1,180 @@ +/* + * This file is generated by jOOQ. + */ +package org.eclipse.openvsx.jooq.tables.records; + + +import org.eclipse.openvsx.jooq.tables.ExtractResourcesMigrationItem; +import org.jooq.Field; +import org.jooq.Record1; +import org.jooq.Record3; +import org.jooq.Row3; +import org.jooq.impl.UpdatableRecordImpl; + + +/** + * This class is generated by jOOQ. + */ +@SuppressWarnings({ "all", "unchecked", "rawtypes" }) +public class ExtractResourcesMigrationItemRecord extends UpdatableRecordImpl implements Record3 { + + private static final long serialVersionUID = 1L; + + /** + * Setter for public.extract_resources_migration_item.id. + */ + public void setId(Long value) { + set(0, value); + } + + /** + * Getter for public.extract_resources_migration_item.id. + */ + public Long getId() { + return (Long) get(0); + } + + /** + * Setter for public.extract_resources_migration_item.extension_id. + */ + public void setExtensionId(Long value) { + set(1, value); + } + + /** + * Getter for public.extract_resources_migration_item.extension_id. + */ + public Long getExtensionId() { + return (Long) get(1); + } + + /** + * Setter for public.extract_resources_migration_item.migration_scheduled. + */ + public void setMigrationScheduled(Boolean value) { + set(2, value); + } + + /** + * Getter for public.extract_resources_migration_item.migration_scheduled. + */ + public Boolean getMigrationScheduled() { + return (Boolean) get(2); + } + + // ------------------------------------------------------------------------- + // Primary key information + // ------------------------------------------------------------------------- + + @Override + public Record1 key() { + return (Record1) super.key(); + } + + // ------------------------------------------------------------------------- + // Record3 type implementation + // ------------------------------------------------------------------------- + + @Override + public Row3 fieldsRow() { + return (Row3) super.fieldsRow(); + } + + @Override + public Row3 valuesRow() { + return (Row3) super.valuesRow(); + } + + @Override + public Field field1() { + return ExtractResourcesMigrationItem.EXTRACT_RESOURCES_MIGRATION_ITEM.ID; + } + + @Override + public Field field2() { + return ExtractResourcesMigrationItem.EXTRACT_RESOURCES_MIGRATION_ITEM.EXTENSION_ID; + } + + @Override + public Field field3() { + return ExtractResourcesMigrationItem.EXTRACT_RESOURCES_MIGRATION_ITEM.MIGRATION_SCHEDULED; + } + + @Override + public Long component1() { + return getId(); + } + + @Override + public Long component2() { + return getExtensionId(); + } + + @Override + public Boolean component3() { + return getMigrationScheduled(); + } + + @Override + public Long value1() { + return getId(); + } + + @Override + public Long value2() { + return getExtensionId(); + } + + @Override + public Boolean value3() { + return getMigrationScheduled(); + } + + @Override + public ExtractResourcesMigrationItemRecord value1(Long value) { + setId(value); + return this; + } + + @Override + public ExtractResourcesMigrationItemRecord value2(Long value) { + setExtensionId(value); + return this; + } + + @Override + public ExtractResourcesMigrationItemRecord value3(Boolean value) { + setMigrationScheduled(value); + return this; + } + + @Override + public ExtractResourcesMigrationItemRecord values(Long value1, Long value2, Boolean value3) { + value1(value1); + value2(value2); + value3(value3); + return this; + } + + // ------------------------------------------------------------------------- + // Constructors + // ------------------------------------------------------------------------- + + /** + * Create a detached ExtractResourcesMigrationItemRecord + */ + public ExtractResourcesMigrationItemRecord() { + super(ExtractResourcesMigrationItem.EXTRACT_RESOURCES_MIGRATION_ITEM); + } + + /** + * Create a detached, initialised ExtractResourcesMigrationItemRecord + */ + public ExtractResourcesMigrationItemRecord(Long id, Long extensionId, Boolean migrationScheduled) { + super(ExtractResourcesMigrationItem.EXTRACT_RESOURCES_MIGRATION_ITEM); + + setId(id); + setExtensionId(extensionId); + setMigrationScheduled(migrationScheduled); + } +} diff --git a/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/records/FileResourceRecord.java b/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/records/FileResourceRecord.java index 8203f55f1..8fa2ce38c 100644 --- a/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/records/FileResourceRecord.java +++ b/server/src/main/jooq-gen/org/eclipse/openvsx/jooq/tables/records/FileResourceRecord.java @@ -7,8 +7,8 @@ import org.eclipse.openvsx.jooq.tables.FileResource; import org.jooq.Field; import org.jooq.Record1; -import org.jooq.Record6; -import org.jooq.Row6; +import org.jooq.Record7; +import org.jooq.Row7; import org.jooq.impl.UpdatableRecordImpl; @@ -16,7 +16,7 @@ * This class is generated by jOOQ. */ @SuppressWarnings({ "all", "unchecked", "rawtypes" }) -public class FileResourceRecord extends UpdatableRecordImpl implements Record6 { +public class FileResourceRecord extends UpdatableRecordImpl implements Record7 { private static final long serialVersionUID = 1L; @@ -104,6 +104,20 @@ public String getStorageType() { return (String) get(5); } + /** + * Setter for public.file_resource.content_type. + */ + public void setContentType(String value) { + set(6, value); + } + + /** + * Getter for public.file_resource.content_type. + */ + public String getContentType() { + return (String) get(6); + } + // ------------------------------------------------------------------------- // Primary key information // ------------------------------------------------------------------------- @@ -114,17 +128,17 @@ public Record1 key() { } // ------------------------------------------------------------------------- - // Record6 type implementation + // Record7 type implementation // ------------------------------------------------------------------------- @Override - public Row6 fieldsRow() { - return (Row6) super.fieldsRow(); + public Row7 fieldsRow() { + return (Row7) super.fieldsRow(); } @Override - public Row6 valuesRow() { - return (Row6) super.valuesRow(); + public Row7 valuesRow() { + return (Row7) super.valuesRow(); } @Override @@ -157,6 +171,11 @@ public Field field6() { return FileResource.FILE_RESOURCE.STORAGE_TYPE; } + @Override + public Field field7() { + return FileResource.FILE_RESOURCE.CONTENT_TYPE; + } + @Override public Long component1() { return getId(); @@ -187,6 +206,11 @@ public String component6() { return getStorageType(); } + @Override + public String component7() { + return getContentType(); + } + @Override public Long value1() { return getId(); @@ -217,6 +241,11 @@ public String value6() { return getStorageType(); } + @Override + public String value7() { + return getContentType(); + } + @Override public FileResourceRecord value1(Long value) { setId(value); @@ -254,13 +283,20 @@ public FileResourceRecord value6(String value) { } @Override - public FileResourceRecord values(Long value1, String value2, byte[] value3, Long value4, String value5, String value6) { + public FileResourceRecord value7(String value) { + setContentType(value); + return this; + } + + @Override + public FileResourceRecord values(Long value1, String value2, byte[] value3, Long value4, String value5, String value6, String value7) { value1(value1); value2(value2); value3(value3); value4(value4); value5(value5); value6(value6); + value7(value7); return this; } @@ -278,7 +314,7 @@ public FileResourceRecord() { /** * Create a detached, initialised FileResourceRecord */ - public FileResourceRecord(Long id, String type, byte[] content, Long extensionId, String name, String storageType) { + public FileResourceRecord(Long id, String type, byte[] content, Long extensionId, String name, String storageType, String contentType) { super(FileResource.FILE_RESOURCE); setId(id); @@ -287,5 +323,6 @@ public FileResourceRecord(Long id, String type, byte[] content, Long extensionId setExtensionId(extensionId); setName(name); setStorageType(storageType); + setContentType(contentType); } } diff --git a/server/src/main/resources/db/migration/V1_26__FileResource_ContentType.sql b/server/src/main/resources/db/migration/V1_26__FileResource_ContentType.sql new file mode 100644 index 000000000..3795dc37c --- /dev/null +++ b/server/src/main/resources/db/migration/V1_26__FileResource_ContentType.sql @@ -0,0 +1 @@ +ALTER TABLE file_resource ADD COLUMN content_type CHARACTER VARYING(255); \ No newline at end of file diff --git a/server/src/test/java/org/eclipse/openvsx/RegistryAPITest.java b/server/src/test/java/org/eclipse/openvsx/RegistryAPITest.java index 5d6bc986e..5eaff806a 100644 --- a/server/src/test/java/org/eclipse/openvsx/RegistryAPITest.java +++ b/server/src/test/java/org/eclipse/openvsx/RegistryAPITest.java @@ -1417,6 +1417,7 @@ private FileResource mockReadme(String targetPlatform) { resource.setName("README"); resource.setType(FileResource.README); resource.setContent("Please read me".getBytes()); + resource.setContentType(MediaType.TEXT_PLAIN_VALUE); resource.setStorageType(FileResource.STORAGE_DB); Mockito.when(repositories.findFileByName(extVersion, "README")) .thenReturn(resource); @@ -1430,6 +1431,7 @@ private FileResource mockChangelog() { resource.setName("CHANGELOG"); resource.setType(FileResource.CHANGELOG); resource.setContent("All notable changes is documented here".getBytes()); + resource.setContentType(MediaType.TEXT_PLAIN_VALUE); resource.setStorageType(FileResource.STORAGE_DB); Mockito.when(repositories.findFileByName(extVersion, "CHANGELOG")) .thenReturn(resource); @@ -1443,6 +1445,7 @@ private FileResource mockLicense() { resource.setName("LICENSE"); resource.setType(FileResource.LICENSE); resource.setContent("I never broke the Law! I am the law!".getBytes()); + resource.setContentType(MediaType.TEXT_PLAIN_VALUE); resource.setStorageType(FileResource.STORAGE_DB); Mockito.when(repositories.findFileByName(extVersion, "LICENSE")) .thenReturn(resource); diff --git a/server/src/test/java/org/eclipse/openvsx/adapter/VSCodeAPITest.java b/server/src/test/java/org/eclipse/openvsx/adapter/VSCodeAPITest.java index 43c2bd148..9654a4dd1 100644 --- a/server/src/test/java/org/eclipse/openvsx/adapter/VSCodeAPITest.java +++ b/server/src/test/java/org/eclipse/openvsx/adapter/VSCodeAPITest.java @@ -47,6 +47,7 @@ import org.eclipse.openvsx.security.TokenService; import org.eclipse.openvsx.storage.*; import org.eclipse.openvsx.util.TargetPlatform; +import org.elasticsearch.search.aggregations.Aggregations; import org.eclipse.openvsx.util.VersionService; import org.junit.jupiter.api.Test; import org.mockito.Mockito; @@ -60,6 +61,7 @@ import org.springframework.data.elasticsearch.core.SearchHitsImpl; import org.springframework.data.elasticsearch.core.TotalHitsRelation; import org.springframework.data.util.Streamable; +import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; import org.springframework.test.web.servlet.MockMvc; @@ -224,6 +226,7 @@ public void testAsset() throws Exception { mockMvc.perform(get("/vscode/asset/{namespace}/{extensionName}/{version}/{assetType}", "redhat", "vscode-yaml", "0.5.2", "Microsoft.VisualStudio.Code.Manifest")) .andExpect(status().isOk()) + .andExpect(header().string(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)) .andExpect(content().string("{\"foo\":\"bar\"}")); } @@ -234,6 +237,7 @@ public void testAssetMacOSX() throws Exception { mockMvc.perform(get("/vscode/asset/{namespace}/{extensionName}/{version}/{assetType}?targetPlatform={target}", "redhat", "vscode-yaml", "0.5.2", "Microsoft.VisualStudio.Code.Manifest", target)) .andExpect(status().isOk()) + .andExpect(header().string(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)) .andExpect(content().string("{\"foo\":\"bar\",\"target\":\"darwin-arm64\"}")); } @@ -247,6 +251,15 @@ public void testAssetNotFound() throws Exception { .andExpect(status().isNotFound()); } + @Test + public void testAssetVsixPackage() throws Exception { + mockExtension(); + mockMvc.perform(get("/vscode/asset/{namespace}/{extensionName}/{version}/{assetType}", + "redhat", "vscode-yaml", "0.5.2", "Microsoft.VisualStudio.Services.VSIXPackage")) + .andExpect(status().isOk()) + .andExpect(header().string(HttpHeaders.CONTENT_TYPE, "application/zip")); + } + @Test public void testGetItem() throws Exception { mockExtension(); @@ -256,14 +269,65 @@ public void testGetItem() throws Exception { } @Test - public void testWebResourceAsset() throws Exception { + public void testDefaultWebResourceAsset() throws Exception { + mockExtension(); + mockMvc.perform(get("/vscode/asset/{namespace}/{extensionName}/{version}/{assetType}", + "redhat", "vscode-yaml", "0.5.2", "Microsoft.VisualStudio.Code.WebResources/extension/resources/data.bin")) + .andExpect(status().isOk()) + .andExpect(header().string(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE)) + .andExpect(content().string("data.bin")); + } + + @Test + public void testPngWebResourceAsset() throws Exception { mockExtension(); mockMvc.perform(get("/vscode/asset/{namespace}/{extensionName}/{version}/{assetType}", "redhat", "vscode-yaml", "0.5.2", "Microsoft.VisualStudio.Code.WebResources/extension/img/logo.png")) .andExpect(status().isOk()) + .andExpect(header().string(HttpHeaders.CONTENT_TYPE, MediaType.IMAGE_PNG_VALUE)) .andExpect(content().string("logo.png")); } + @Test + public void testCssWebResourceAsset() throws Exception { + mockExtension(); + mockMvc.perform(get("/vscode/asset/{namespace}/{extensionName}/{version}/{assetType}", + "redhat", "vscode-yaml", "0.5.2", "Microsoft.VisualStudio.Code.WebResources/extension/public/static/css/main.css")) + .andExpect(status().isOk()) + .andExpect(header().string(HttpHeaders.CONTENT_TYPE, "text/css")) + .andExpect(content().string(".main { margin: 0 auto; }")); + } + + @Test + public void testChunkCssWebResourceAsset() throws Exception { + mockExtension(); + mockMvc.perform(get("/vscode/asset/{namespace}/{extensionName}/{version}/{assetType}", + "redhat", "vscode-yaml", "0.5.2", "Microsoft.VisualStudio.Code.WebResources/extension/public/static/css/main.9cab4879.chunk.css")) + .andExpect(status().isOk()) + .andExpect(header().string(HttpHeaders.CONTENT_TYPE, "text/css")) + .andExpect(content().string(".root { margin: 0 auto; }")); + } + + @Test + public void testJsWebResourceAsset() throws Exception { + mockExtension(); + mockMvc.perform(get("/vscode/asset/{namespace}/{extensionName}/{version}/{assetType}", + "redhat", "vscode-yaml", "0.5.2", "Microsoft.VisualStudio.Code.WebResources/extension/public/static/js/main.js")) + .andExpect(status().isOk()) + .andExpect(header().string(HttpHeaders.CONTENT_TYPE, "application/javascript")) + .andExpect(content().string("() => { console.log('main'); }")); + } + + @Test + public void testChunkJsWebResourceAsset() throws Exception { + mockExtension(); + mockMvc.perform(get("/vscode/asset/{namespace}/{extensionName}/{version}/{assetType}", + "redhat", "vscode-yaml", "0.5.2", "Microsoft.VisualStudio.Code.WebResources/extension/public/static/js/main.34d01954.chunk.js")) + .andExpect(status().isOk()) + .andExpect(header().string(HttpHeaders.CONTENT_TYPE, "application/javascript")) + .andExpect(content().string("() => { console.log('js'); }")); + } + @Test public void testNotWebResourceAsset() throws Exception { mockExtension(); @@ -324,12 +388,12 @@ public void testBrowseTopDir() throws Exception { Mockito.when(repositories.findActiveExtensionVersionDTOsByVersion(version, extensionName, namespaceName)) .thenReturn(List.of(new ExtensionVersionDTO(0L, 1L, TargetPlatform.NAME_UNIVERSAL, version))); - var vsixResource = new FileResourceDTO(15, 1, "extension.vsixmanifest", RESOURCE, STORAGE_DB, "".getBytes(StandardCharsets.UTF_8)); - var manifestResource = new FileResourceDTO(16, 1, "extension/package.json", RESOURCE, STORAGE_DB, "{\"package\":\"json\"}".getBytes(StandardCharsets.UTF_8)); - var readmeResource = new FileResourceDTO(17, 1, "extension/README.md", RESOURCE, STORAGE_DB, "README".getBytes(StandardCharsets.UTF_8)); - var changelogResource = new FileResourceDTO(18, 1, "extension/CHANGELOG.md", RESOURCE, STORAGE_DB, "CHANGELOG".getBytes(StandardCharsets.UTF_8)); - var licenseResource = new FileResourceDTO(19, 1, "extension/LICENSE.txt", RESOURCE, STORAGE_DB, "LICENSE".getBytes(StandardCharsets.UTF_8)); - var iconResource = new FileResourceDTO(20, 1, "extension/images/icon128.png", RESOURCE, STORAGE_DB, "ICON128".getBytes(StandardCharsets.UTF_8)); + var vsixResource = new FileResourceDTO(15, 1, "extension.vsixmanifest", RESOURCE, STORAGE_DB, "".getBytes(StandardCharsets.UTF_8), "application/xml"); + var manifestResource = new FileResourceDTO(16, 1, "extension/package.json", RESOURCE, STORAGE_DB, "{\"package\":\"json\"}".getBytes(StandardCharsets.UTF_8), "application/json"); + var readmeResource = new FileResourceDTO(17, 1, "extension/README.md", RESOURCE, STORAGE_DB, "README".getBytes(StandardCharsets.UTF_8), "text/markdown"); + var changelogResource = new FileResourceDTO(18, 1, "extension/CHANGELOG.md", RESOURCE, STORAGE_DB, "CHANGELOG".getBytes(StandardCharsets.UTF_8), "text/markdown"); + var licenseResource = new FileResourceDTO(19, 1, "extension/LICENSE.txt", RESOURCE, STORAGE_DB, "LICENSE".getBytes(StandardCharsets.UTF_8), "text/plain"); + var iconResource = new FileResourceDTO(20, 1, "extension/images/icon128.png", RESOURCE, STORAGE_DB, "ICON128".getBytes(StandardCharsets.UTF_8), "image/png"); Mockito.when(repositories.findAllResourceFileResourceDTOs(1L, "")) .thenReturn(List.of(vsixResource, manifestResource, readmeResource, changelogResource, licenseResource, iconResource)); @@ -348,7 +412,7 @@ public void testBrowseVsixManifest() throws Exception { .thenReturn(List.of(new ExtensionVersionDTO(0L, 1L, TargetPlatform.NAME_UNIVERSAL, version))); var content = "".getBytes(StandardCharsets.UTF_8); - var vsixResource = new FileResourceDTO(15, 1, "extension.vsixmanifest", RESOURCE, STORAGE_DB, content); + var vsixResource = new FileResourceDTO(15, 1, "extension.vsixmanifest", RESOURCE, STORAGE_DB, content, "application/xml"); Mockito.when(repositories.findAllResourceFileResourceDTOs(1L, "extension.vsixmanifest")) .thenReturn(List.of(vsixResource)); @@ -370,7 +434,7 @@ public void testBrowseVsixManifestUniversal() throws Exception { )); var content = "".getBytes(StandardCharsets.UTF_8); - var vsixResource = new FileResourceDTO(15, 1, "extension.vsixmanifest", RESOURCE, STORAGE_DB, content); + var vsixResource = new FileResourceDTO(15, 1, "extension.vsixmanifest", RESOURCE, STORAGE_DB, content, "application/xml"); Mockito.when(repositories.findAllResourceFileResourceDTOs(1L, "extension.vsixmanifest")) .thenReturn(List.of(vsixResource)); @@ -392,7 +456,7 @@ public void testBrowseVsixManifestWindows() throws Exception { )); var content = "".getBytes(StandardCharsets.UTF_8); - var vsixResource = new FileResourceDTO(15, 4, "extension.vsixmanifest", RESOURCE, STORAGE_DB, content); + var vsixResource = new FileResourceDTO(15, 4, "extension.vsixmanifest", RESOURCE, STORAGE_DB, content, "application/xml"); Mockito.when(repositories.findAllResourceFileResourceDTOs(4L, "extension.vsixmanifest")) .thenReturn(List.of(vsixResource)); @@ -409,11 +473,11 @@ public void testBrowseExtensionDir() throws Exception { Mockito.when(repositories.findActiveExtensionVersionDTOsByVersion(version, extensionName, namespaceName)) .thenReturn(List.of(new ExtensionVersionDTO(0L, 1L, TargetPlatform.NAME_UNIVERSAL, version))); - var manifestResource = new FileResourceDTO(16, 1, "extension/package.json", RESOURCE, STORAGE_DB, "{\"package\":\"json\"}".getBytes(StandardCharsets.UTF_8)); - var readmeResource = new FileResourceDTO(17, 1, "extension/README.md", RESOURCE, STORAGE_DB, "README".getBytes(StandardCharsets.UTF_8)); - var changelogResource = new FileResourceDTO(18, 1, "extension/CHANGELOG.md", RESOURCE, STORAGE_DB, "CHANGELOG".getBytes(StandardCharsets.UTF_8)); - var licenseResource = new FileResourceDTO(19, 1, "extension/LICENSE.txt", RESOURCE, STORAGE_DB, "LICENSE".getBytes(StandardCharsets.UTF_8)); - var iconResource = new FileResourceDTO(20, 1, "extension/images/icon128.png", RESOURCE, STORAGE_DB, "ICON128".getBytes(StandardCharsets.UTF_8)); + var manifestResource = new FileResourceDTO(16, 1, "extension/package.json", RESOURCE, STORAGE_DB, "{\"package\":\"json\"}".getBytes(StandardCharsets.UTF_8), "application/json"); + var readmeResource = new FileResourceDTO(17, 1, "extension/README.md", RESOURCE, STORAGE_DB, "README".getBytes(StandardCharsets.UTF_8), "text/markdown"); + var changelogResource = new FileResourceDTO(18, 1, "extension/CHANGELOG.md", RESOURCE, STORAGE_DB, "CHANGELOG".getBytes(StandardCharsets.UTF_8), "text/markdown"); + var licenseResource = new FileResourceDTO(19, 1, "extension/LICENSE.txt", RESOURCE, STORAGE_DB, "LICENSE".getBytes(StandardCharsets.UTF_8), "text/plain"); + var iconResource = new FileResourceDTO(20, 1, "extension/images/icon128.png", RESOURCE, STORAGE_DB, "ICON128".getBytes(StandardCharsets.UTF_8), "image/png"); Mockito.when(repositories.findAllResourceFileResourceDTOs(1L, "extension")) .thenReturn(List.of(manifestResource, readmeResource, changelogResource, licenseResource, iconResource)); @@ -439,7 +503,7 @@ public void testBrowsePackageJson() throws Exception { .thenReturn(List.of(new ExtensionVersionDTO(0L, 1L, TargetPlatform.NAME_UNIVERSAL, version))); var content = "{\"package\":\"json\"}".getBytes(StandardCharsets.UTF_8); - var manifestResource = new FileResourceDTO(16, 1, "extension/package.json", RESOURCE, STORAGE_DB, content); + var manifestResource = new FileResourceDTO(16, 1, "extension/package.json", RESOURCE, STORAGE_DB, content, "application/json"); Mockito.when(repositories.findAllResourceFileResourceDTOs(1L, "extension/package.json")) .thenReturn(List.of(manifestResource)); @@ -456,7 +520,7 @@ public void testBrowseImagesDir() throws Exception { Mockito.when(repositories.findActiveExtensionVersionDTOsByVersion(version, extensionName, namespaceName)) .thenReturn(List.of(new ExtensionVersionDTO(0L, 1L, TargetPlatform.NAME_UNIVERSAL, version))); - var iconResource = new FileResourceDTO(20, 1, "extension/images/icon128.png", RESOURCE, STORAGE_DB, "ICON128".getBytes(StandardCharsets.UTF_8)); + var iconResource = new FileResourceDTO(20, 1, "extension/images/icon128.png", RESOURCE, STORAGE_DB, "ICON128".getBytes(StandardCharsets.UTF_8), "image/png"); Mockito.when(repositories.findAllResourceFileResourceDTOs(1L, "extension/images")) .thenReturn(List.of(iconResource)); @@ -475,7 +539,7 @@ public void testBrowseIcon() throws Exception { .thenReturn(List.of(new ExtensionVersionDTO(0L, 1L, TargetPlatform.NAME_UNIVERSAL, version))); var content = "ICON128".getBytes(StandardCharsets.UTF_8); - var iconResource = new FileResourceDTO(20, 1, "extension/images/icon128.png", RESOURCE, STORAGE_DB, content); + var iconResource = new FileResourceDTO(20, 1, "extension/images/icon128.png", RESOURCE, STORAGE_DB, content, "image/png"); Mockito.when(repositories.findAllResourceFileResourceDTOs(1L, "extension/images/icon128.png")) .thenReturn(List.of(iconResource)); @@ -627,6 +691,7 @@ private ExtensionVersion mockExtension(String targetPlatform) throws JsonProcess extension.setAverageRating(3.0); extension.setNamespace(namespace); var extVersion = new ExtensionVersion(); + extVersion.setExtension(extension); extension.getVersions().add(extVersion); extVersion.setTargetPlatform(targetPlatform); extVersion.setVersion("0.5.2"); @@ -655,6 +720,7 @@ private ExtensionVersion mockExtension(String targetPlatform) throws JsonProcess extensionFile.setExtension(extVersion); extensionFile.setName("redhat.vscode-yaml-0.5.2.vsix"); extensionFile.setType(FileResource.DOWNLOAD); + extensionFile.setContentType("application/zip"); extensionFile.setStorageType(FileResource.STORAGE_DB); Mockito.when(repositories.findFileByType(extVersion, FileResource.DOWNLOAD)) .thenReturn(extensionFile); @@ -667,6 +733,7 @@ private ExtensionVersion mockExtension(String targetPlatform) throws JsonProcess if(!targetPlatform.equals(TargetPlatform.NAME_UNIVERSAL)) manifestContent.put("target", targetPlatform); manifestFile.setContent(new ObjectMapper().writeValueAsBytes(manifestContent)); + manifestFile.setContentType(MediaType.APPLICATION_JSON_VALUE); manifestFile.setStorageType(FileResource.STORAGE_DB); Mockito.when(repositories.findFileByType(extVersion, FileResource.MANIFEST)) .thenReturn(manifestFile); @@ -674,6 +741,7 @@ private ExtensionVersion mockExtension(String targetPlatform) throws JsonProcess readmeFile.setExtension(extVersion); readmeFile.setName("README.md"); readmeFile.setType(FileResource.README); + readmeFile.setContentType("text/markdown"); readmeFile.setStorageType(FileResource.STORAGE_DB); Mockito.when(repositories.findFileByType(extVersion, FileResource.README)) .thenReturn(readmeFile); @@ -681,6 +749,7 @@ private ExtensionVersion mockExtension(String targetPlatform) throws JsonProcess changelogFile.setExtension(extVersion); changelogFile.setName("CHANGELOG.md"); changelogFile.setType(FileResource.CHANGELOG); + changelogFile.setContentType("text/markdown"); changelogFile.setStorageType(FileResource.STORAGE_DB); Mockito.when(repositories.findFileByType(extVersion, FileResource.CHANGELOG)) .thenReturn(changelogFile); @@ -688,6 +757,7 @@ private ExtensionVersion mockExtension(String targetPlatform) throws JsonProcess licenseFile.setExtension(extVersion); licenseFile.setName("LICENSE.txt"); licenseFile.setType(FileResource.LICENSE); + licenseFile.setContentType(MediaType.TEXT_PLAIN_VALUE); licenseFile.setStorageType(FileResource.STORAGE_DB); Mockito.when(repositories.findFileByType(extVersion, FileResource.LICENSE)) .thenReturn(licenseFile); @@ -695,17 +765,64 @@ private ExtensionVersion mockExtension(String targetPlatform) throws JsonProcess iconFile.setExtension(extVersion); iconFile.setName("icon128.png"); iconFile.setType(FileResource.ICON); + iconFile.setContentType(MediaType.IMAGE_PNG_VALUE); iconFile.setStorageType(FileResource.STORAGE_DB); Mockito.when(repositories.findFileByType(extVersion, FileResource.ICON)) .thenReturn(iconFile); - var webResourceFile = new FileResource(); - webResourceFile.setExtension(extVersion); - webResourceFile.setName("extension/img/logo.png"); - webResourceFile.setType(FileResource.RESOURCE); - webResourceFile.setStorageType(STORAGE_DB); - webResourceFile.setContent("logo.png".getBytes()); + var binWebResourceFile = new FileResource(); + binWebResourceFile.setExtension(extVersion); + binWebResourceFile.setName("extension/resources/data.bin"); + binWebResourceFile.setType(FileResource.RESOURCE); + binWebResourceFile.setStorageType(STORAGE_DB); + binWebResourceFile.setContent("data.bin".getBytes()); + binWebResourceFile.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); + Mockito.when(repositories.findFileByTypeAndName(extVersion, FileResource.RESOURCE, "extension/resources/data.bin")) + .thenReturn(binWebResourceFile); + var pngWebResourceFile = new FileResource(); + pngWebResourceFile.setExtension(extVersion); + pngWebResourceFile.setName("extension/img/logo.png"); + pngWebResourceFile.setType(FileResource.RESOURCE); + pngWebResourceFile.setStorageType(STORAGE_DB); + pngWebResourceFile.setContent("logo.png".getBytes()); + pngWebResourceFile.setContentType(MediaType.IMAGE_PNG_VALUE); Mockito.when(repositories.findFileByTypeAndName(extVersion, FileResource.RESOURCE, "extension/img/logo.png")) - .thenReturn(webResourceFile); + .thenReturn(pngWebResourceFile); + var jsWebResourceFile = new FileResource(); + jsWebResourceFile.setExtension(extVersion); + jsWebResourceFile.setName("extension/public/static/js/main.js"); + jsWebResourceFile.setType(FileResource.RESOURCE); + jsWebResourceFile.setStorageType(STORAGE_DB); + jsWebResourceFile.setContent("() => { console.log('main'); }".getBytes()); + jsWebResourceFile.setContentType("application/javascript"); + Mockito.when(repositories.findFileByTypeAndName(extVersion, FileResource.RESOURCE, "extension/public/static/js/main.js")) + .thenReturn(jsWebResourceFile); + var jsChunkWebResourceFile = new FileResource(); + jsChunkWebResourceFile.setExtension(extVersion); + jsChunkWebResourceFile.setName("extension/public/static/js/main.34d01954.chunk.js"); + jsChunkWebResourceFile.setType(FileResource.RESOURCE); + jsChunkWebResourceFile.setStorageType(STORAGE_DB); + jsChunkWebResourceFile.setContent("() => { console.log('js'); }".getBytes()); + jsChunkWebResourceFile.setContentType("application/javascript"); + Mockito.when(repositories.findFileByTypeAndName(extVersion, FileResource.RESOURCE, "extension/public/static/js/main.34d01954.chunk.js")) + .thenReturn(jsChunkWebResourceFile); + var cssWebResourceFile = new FileResource(); + cssWebResourceFile.setExtension(extVersion); + cssWebResourceFile.setName("extension/public/static/css/main.css"); + cssWebResourceFile.setType(FileResource.RESOURCE); + cssWebResourceFile.setStorageType(STORAGE_DB); + cssWebResourceFile.setContent(".main { margin: 0 auto; }".getBytes()); + cssWebResourceFile.setContentType("text/css"); + Mockito.when(repositories.findFileByTypeAndName(extVersion, FileResource.RESOURCE, "extension/public/static/css/main.css")) + .thenReturn(cssWebResourceFile); + var cssChunkWebResourceFile = new FileResource(); + cssChunkWebResourceFile.setExtension(extVersion); + cssChunkWebResourceFile.setName("extension/public/static/css/main.9cab4879.chunk.css"); + cssChunkWebResourceFile.setType(FileResource.RESOURCE); + cssChunkWebResourceFile.setStorageType(STORAGE_DB); + cssChunkWebResourceFile.setContent(".root { margin: 0 auto; }".getBytes()); + cssChunkWebResourceFile.setContentType("text/css"); + Mockito.when(repositories.findFileByTypeAndName(extVersion, FileResource.RESOURCE, "extension/public/static/css/main.9cab4879.chunk.css")) + .thenReturn(cssChunkWebResourceFile); Mockito.when(repositories.findFilesByType(anyCollection(), anyCollection())).thenAnswer(invocation -> { Collection extVersions = invocation.getArgument(0); var types = invocation.getArgument(1);