Quellcode durchsuchen

feat(core): Include width and height in Asset entity

Closes #79
Michael Bromley vor 6 Jahren
Ursprung
Commit
338ef9597f

+ 6 - 0
admin-ui/src/app/common/generated-types.ts

@@ -111,6 +111,8 @@ export type Asset = Node & {
   type: AssetType,
   fileSize: Scalars['Int'],
   mimeType: Scalars['String'],
+  width: Scalars['Int'],
+  height: Scalars['Int'],
   source: Scalars['String'],
   preview: Scalars['String'],
 };
@@ -122,6 +124,8 @@ export type AssetFilterParameter = {
   type?: Maybe<StringOperators>,
   fileSize?: Maybe<NumberOperators>,
   mimeType?: Maybe<StringOperators>,
+  width?: Maybe<NumberOperators>,
+  height?: Maybe<NumberOperators>,
   source?: Maybe<StringOperators>,
   preview?: Maybe<StringOperators>,
 };
@@ -146,6 +150,8 @@ export type AssetSortParameter = {
   name?: Maybe<SortOrder>,
   fileSize?: Maybe<SortOrder>,
   mimeType?: Maybe<SortOrder>,
+  width?: Maybe<SortOrder>,
+  height?: Maybe<SortOrder>,
   source?: Maybe<SortOrder>,
   preview?: Maybe<SortOrder>,
 };

+ 2 - 0
packages/common/src/generated-shop-types.ts

@@ -81,6 +81,8 @@ export type Asset = Node & {
     type: AssetType;
     fileSize: Scalars['Int'];
     mimeType: Scalars['String'];
+    width: Scalars['Int'];
+    height: Scalars['Int'];
     source: Scalars['String'];
     preview: Scalars['String'];
 };

+ 6 - 0
packages/common/src/generated-types.ts

@@ -110,6 +110,8 @@ export type Asset = Node & {
   type: AssetType,
   fileSize: Scalars['Int'],
   mimeType: Scalars['String'],
+  width: Scalars['Int'],
+  height: Scalars['Int'],
   source: Scalars['String'],
   preview: Scalars['String'],
 };
@@ -121,6 +123,8 @@ export type AssetFilterParameter = {
   type?: Maybe<StringOperators>,
   fileSize?: Maybe<NumberOperators>,
   mimeType?: Maybe<StringOperators>,
+  width?: Maybe<NumberOperators>,
+  height?: Maybe<NumberOperators>,
   source?: Maybe<StringOperators>,
   preview?: Maybe<StringOperators>,
 };
@@ -145,6 +149,8 @@ export type AssetSortParameter = {
   name?: Maybe<SortOrder>,
   fileSize?: Maybe<SortOrder>,
   mimeType?: Maybe<SortOrder>,
+  width?: Maybe<SortOrder>,
+  height?: Maybe<SortOrder>,
   source?: Maybe<SortOrder>,
   preview?: Maybe<SortOrder>,
 };

+ 5 - 5
packages/core/e2e/__snapshots__/collection.e2e-spec.ts.snap

@@ -4,7 +4,7 @@ exports[`Collection resolver createCollection creates a root collection 1`] = `
 Object {
   "assets": Array [
     Object {
-      "fileSize": 4,
+      "fileSize": 1680,
       "id": "T_1",
       "mimeType": "image/jpeg",
       "name": "derick-david-409858-unsplash.jpg",
@@ -13,7 +13,7 @@ Object {
       "type": "IMAGE",
     },
     Object {
-      "fileSize": 4,
+      "fileSize": 1680,
       "id": "T_2",
       "mimeType": "image/jpeg",
       "name": "alexandru-acea-686569-unsplash.jpg",
@@ -25,7 +25,7 @@ Object {
   "children": Array [],
   "description": "",
   "featuredAsset": Object {
-    "fileSize": 4,
+    "fileSize": 1680,
     "id": "T_1",
     "mimeType": "image/jpeg",
     "name": "derick-david-409858-unsplash.jpg",
@@ -73,7 +73,7 @@ exports[`Collection resolver updateCollection 1`] = `
 Object {
   "assets": Array [
     Object {
-      "fileSize": 4,
+      "fileSize": 1680,
       "id": "T_1",
       "mimeType": "image/jpeg",
       "name": "derick-david-409858-unsplash.jpg",
@@ -85,7 +85,7 @@ Object {
   "children": Array [],
   "description": "Apple stuff ",
   "featuredAsset": Object {
-    "fileSize": 4,
+    "fileSize": 1680,
     "id": "T_1",
     "mimeType": "image/jpeg",
     "name": "derick-david-409858-unsplash.jpg",

+ 2 - 2
packages/core/e2e/__snapshots__/product.e2e-spec.ts.snap

@@ -64,7 +64,7 @@ exports[`Product resolver product query returns expected properties 1`] = `
 Object {
   "assets": Array [
     Object {
-      "fileSize": 4,
+      "fileSize": 1680,
       "id": "T_2",
       "mimeType": "image/jpeg",
       "name": "alexandru-acea-686569-unsplash.jpg",
@@ -96,7 +96,7 @@ Object {
     },
   ],
   "featuredAsset": Object {
-    "fileSize": 4,
+    "fileSize": 1680,
     "id": "T_2",
     "mimeType": "image/jpeg",
     "name": "alexandru-acea-686569-unsplash.jpg",

Datei-Diff unterdrückt, da er zu groß ist
+ 2 - 0
packages/core/e2e/config/testing-asset-preview-strategy.ts


+ 3 - 1
packages/core/e2e/config/testing-asset-storage-strategy.ts

@@ -3,12 +3,14 @@ import { Readable, Stream, Writable } from 'stream';
 
 import { AssetStorageStrategy } from '../../src/config/asset-storage-strategy/asset-storage-strategy';
 
+import { getTestImageBuffer } from './testing-asset-preview-strategy';
+
 /**
  * A mock storage strategy which does not actually persist the assets anywhere.
  */
 export class TestingAssetStorageStrategy implements AssetStorageStrategy {
     readFileToBuffer(identifier: string): Promise<Buffer> {
-        return Promise.resolve(Buffer.from('test'));
+        return Promise.resolve(getTestImageBuffer());
     }
 
     readFileToStream(identifier: string): Promise<Stream> {

+ 6 - 0
packages/core/e2e/graphql/generated-e2e-admin-types.ts

@@ -110,6 +110,8 @@ export type Asset = Node & {
     type: AssetType;
     fileSize: Scalars['Int'];
     mimeType: Scalars['String'];
+    width: Scalars['Int'];
+    height: Scalars['Int'];
     source: Scalars['String'];
     preview: Scalars['String'];
 };
@@ -121,6 +123,8 @@ export type AssetFilterParameter = {
     type?: Maybe<StringOperators>;
     fileSize?: Maybe<NumberOperators>;
     mimeType?: Maybe<StringOperators>;
+    width?: Maybe<NumberOperators>;
+    height?: Maybe<NumberOperators>;
     source?: Maybe<StringOperators>;
     preview?: Maybe<StringOperators>;
 };
@@ -145,6 +149,8 @@ export type AssetSortParameter = {
     name?: Maybe<SortOrder>;
     fileSize?: Maybe<SortOrder>;
     mimeType?: Maybe<SortOrder>;
+    width?: Maybe<SortOrder>;
+    height?: Maybe<SortOrder>;
     source?: Maybe<SortOrder>;
     preview?: Maybe<SortOrder>;
 };

+ 2 - 0
packages/core/e2e/graphql/generated-e2e-shop-types.ts

@@ -81,6 +81,8 @@ export type Asset = Node & {
     type: AssetType;
     fileSize: Scalars['Int'];
     mimeType: Scalars['String'];
+    width: Scalars['Int'];
+    height: Scalars['Int'];
     source: Scalars['String'];
     preview: Scalars['String'];
 };

+ 2 - 0
packages/core/package.json

@@ -60,6 +60,7 @@
     "i18next-express-middleware": "^1.7.1",
     "i18next-icu": "^1.0.1",
     "i18next-node-fs-backend": "^2.1.1",
+    "image-size": "^0.7.4",
     "mime-types": "^2.1.21",
     "ms": "^2.1.1",
     "nanoid": "^2.0.0",
@@ -78,6 +79,7 @@
     "@types/graphql-type-json": "^0.1.3",
     "@types/gulp": "^4.0.5",
     "@types/http-proxy-middleware": "^0.19.2",
+    "@types/image-size": "^0.7.0",
     "@types/jest": "^23.3.12",
     "@types/mime-types": "^2.1.0",
     "@types/ms": "^0.7.30",

+ 2 - 0
packages/core/src/api/schema/type/asset.type.graphql

@@ -6,6 +6,8 @@ type Asset implements Node {
     type: AssetType!
     fileSize: Int!
     mimeType: String!
+    width: Int!
+    height: Int!
     source: String!
     preview: String!
 }

+ 4 - 0
packages/core/src/entity/asset/asset.entity.ts

@@ -26,6 +26,10 @@ export class Asset extends VendureEntity {
 
     @Column() mimeType: string;
 
+    @Column({ default: 0 }) width: number;
+
+    @Column({ default: 0 }) height: number;
+
     @Column() fileSize: number;
 
     @Column() source: string;

+ 23 - 5
packages/core/src/service/services/asset.service.ts

@@ -1,8 +1,9 @@
 import { Injectable } from '@nestjs/common';
 import { InjectConnection } from '@nestjs/typeorm';
-import { CreateAssetInput } from '@vendure/common/lib/generated-types';
+import { AssetType, CreateAssetInput } from '@vendure/common/lib/generated-types';
 import { ID, PaginatedList } from '@vendure/common/lib/shared-types';
 import { ReadStream } from 'fs-extra';
+import sizeOf from 'image-size';
 import mime from 'mime-types';
 import path from 'path';
 import { Stream } from 'stream';
@@ -12,6 +13,7 @@ import { InternalServerError } from '../../common/error/errors';
 import { ListQueryOptions } from '../../common/types/common-types';
 import { getAssetType } from '../../common/utils';
 import { ConfigService } from '../../config/config.service';
+import { Logger } from '../../config/logger/vendure-logger';
 import { Asset } from '../../entity/asset/asset.entity';
 import { EntityWithAssets } from '../helpers/asset-updater/asset-updater';
 import { ListQueryBuilder } from '../helpers/list-query-builder/list-query-builder';
@@ -58,9 +60,11 @@ export class AssetService {
 
     async getFeaturedAsset<T extends EntityWithAssets>(entity: T): Promise<Asset | undefined> {
         const entityType = Object.getPrototypeOf(entity).constructor;
-        const entityWithFeaturedAsset = await this.connection.getRepository<EntityWithAssets>(entityType).findOne(entity.id, {
-            relations: ['featuredAsset'],
-        });
+        const entityWithFeaturedAsset = await this.connection
+            .getRepository<EntityWithAssets>(entityType)
+            .findOne(entity.id, {
+                relations: ['featuredAsset'],
+            });
         return entityWithFeaturedAsset && entityWithFeaturedAsset.featuredAsset;
     }
 
@@ -100,9 +104,13 @@ export class AssetService {
             previewFileName,
             preview,
         );
+        const type = getAssetType(mimetype);
+        const { width, height } = this.getDimensions(type === AssetType.IMAGE ? sourceFile : preview);
 
         const asset = new Asset({
-            type: getAssetType(mimetype),
+            type,
+            width,
+            height,
             name: sourceFileName,
             fileSize: sourceFile.byteLength,
             mimeType: mimetype,
@@ -137,4 +145,14 @@ export class AssetService {
         } while (await assetOptions.assetStorageStrategy.fileExists(outputFileName));
         return outputFileName;
     }
+
+    private getDimensions(imageFile: Buffer): { width: number; height: number } {
+        try {
+            const { width, height } = sizeOf(imageFile);
+            return { width, height };
+        } catch (e) {
+            Logger.error(`Could not determine Asset dimensions: ` + e);
+            return { width: 0, height: 0 };
+        }
+    }
 }

Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
schema-admin.json


Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
schema-shop.json


+ 8 - 1
yarn.lock

@@ -1720,6 +1720,13 @@
   dependencies:
     "@types/node" "*"
 
+"@types/image-size@^0.7.0":
+  version "0.7.0"
+  resolved "https://registry.npmjs.org/@types/image-size/-/image-size-0.7.0.tgz#a785302cdaedad7dfd985c5f2f6f721467b95de9"
+  integrity sha512-WkmNFWsC7NggeNC+2LxFJc6we3PiPf72NJUpezGNPbSe5zZ9sBcscQnSqQjYAyax3QNCyT42kNdAeT2tTvQMcQ==
+  dependencies:
+    "@types/node" "*"
+
 "@types/is-glob@4.0.1":
   version "4.0.1"
   resolved "https://registry.npmjs.org/@types/is-glob/-/is-glob-4.0.1.tgz#a93eec1714172c8eb3225a1cc5eb88c2477b7d00"
@@ -5841,7 +5848,7 @@ ignore@^5.1.1:
   resolved "https://registry.npmjs.org/ignore/-/ignore-5.1.2.tgz#e28e584d43ad7e92f96995019cc43b9e1ac49558"
   integrity sha512-vdqWBp7MyzdmHkkRWV5nY+PfGRbYbahfuvsBCh277tq+w9zyNi7h5CYJCK0kmzti9kU+O/cB7sE8HvKv6aXAKQ==
 
-image-size@^0.7.3:
+image-size@^0.7.3, image-size@^0.7.4:
   version "0.7.4"
   resolved "https://registry.npmjs.org/image-size/-/image-size-0.7.4.tgz#092c1e541a93511917bfc957a1fc7add21c72e87"
   integrity sha512-GqPgxs+VkOr12aWwjSkyRzf5atzObWpFtiRuDgxCl2I/SDpZOKZFRD3iIAeAN6/usmn8SeLWRt7a8JRYK0Whbw==

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.