payloadcms / payload-3.0-demo

The official demo for Payload 3.0
https://next-payload-3-0-test.vercel.app
440 stars 143 forks source link

Attempted import error: 'file-type' does not contain a default export (imported as 'getFileType'). #170

Closed tyteen4a03 closed 4 months ago

tyteen4a03 commented 4 months ago

Link to reproduction

No response

Describe the Bug

I am getting this error when trying to enter the Payload admin panel:

 ⨯ ./node_modules/@payloadcms/next/dist/routes/rest/files/getFile.js

Attempted import error: 'file-type' does not contain a default export (imported as 'getFileType'). 
 Import trace for requested module: ./node_modules/@payloadcms/next/dist/routes/rest/files/getFile.js 
./node_modules/@payloadcms/next/dist/routes/rest/index.js
 ./node_modules/@payloadcms/next/dist/exports/routes.js
 ./src/app/(payload)/api/[...slug]/route.ts

To Reproduce

N/A - I don't know how to reproduce this, only that others have seen the issue as well.

https://discord.com/channels/967097582721572934/1215659716538273832/1234633622309441586 https://discord.com/channels/967097582721572934/1234566493992259685/1234620798137012229

This is my dependencies list:

"dependencies": {
    "@apollo/client": "^3.10.1",
    "@apollo/experimental-nextjs-app-support": "^0.10.0",
    "@ark-ui/react": "^2.2.3",
    "@aws-sdk/client-s3": "^3.565.0",
    "@lexical/headless": "^0.13.1",
    "@lexical/react": "^0.13.1",
    "@payloadcms/db-postgres": "3.0.0-beta.20",
    "@payloadcms/next": "3.0.0-beta.20",
    "@payloadcms/richtext-lexical": "^3.0.0-beta.20",
    "@payloadcms/storage-s3": "3.0.0-beta.20",
    "@payloadcms/translations": "^3.0.0-beta.20",
    "@payloadcms/ui": "^3.0.0-beta.20",
    "date-fns": "^3.6.0",
    "graphql": "^16.8.1",
    "jotai": "^2.8.0",
    "lexical": "^0.13.1",
    "next": "^14.3.0-canary.8",
    "node-gyp": "^10.1.0",
    "nuqs": "^1.17.1",
    "payload": "3.0.0-beta.20",
    "radash": "^12.1.0",
    "react": "^18.3.1",
    "react-dom": "^18.3.1",
    "react-icons": "^5.1.0",
    "react-lazyload-youtube": "^1.0.8",
    "sharp": "^0.33.3",
    "yet-another-react-lightbox": "^3.17.5"
  },
  "devDependencies": {
    "@biomejs/biome": "1.7.2",
    "@graphql-codegen/cli": "5.0.2",
    "@graphql-codegen/client-preset": "4.2.5",
    "@graphql-typed-document-node/core": "^3.2.0",
    "@pandacss/dev": "0.38.0",
    "@pandacss/types": "^0.38.0",
    "@parcel/watcher": "^2.4.1",
    "@park-ui/panda-preset": "^0.37.0",
    "@swc-jotai/react-refresh": "^0.1.0",
    "@swc/cli": "^0.3.12",
    "@swc/core": "^1.4.17",
    "@types/node": "^20.12.7",
    "@types/react": "^18.3.1",
    "@types/react-dom": "^18.3.0",
    "@types/react-lazyload-youtube": "^1.0.0",
    "tsconfig-paths": "^4.2.0",
    "typescript": "^5.4.5"
  }

Payload Version

3.0.0 Beta 20

Adapters and Plugins

No response

As a side note, Payload's file-type is still on 16 - we should be able to bump this to 19 now that we are fully ESM right?

tyteen4a03 commented 4 months ago

Some insights into this issue from https://discord.com/channels/967097582721572934/1215659716538273832/1235016351223910420:

jmikrut commented 4 months ago

Good reconnaissance. Thank you. Gonna get to the bottom of this tomorrow.

tyteen4a03 commented 4 months ago

I found the culprit:

❯ yarn why file-type
├─ @mole-inc/bin-wrapper@npm:8.0.1
│  └─ file-type@npm:17.1.6 (via npm:^17.1.6)
│
├─ payload@npm:3.0.0-beta.20
│  └─ file-type@npm:16.5.4 (via npm:16.5.4)
│
└─ payload@npm:3.0.0-beta.20 [2316f]
   └─ file-type@npm:16.5.4 (via npm:16.5.4)
❯ yarn why @mole-inc/bin-wrapper
├─ @swc/cli@npm:0.3.12
│  └─ @mole-inc/bin-wrapper@npm:8.0.1 (via npm:^8.0.1)
│
└─ @swc/cli@npm:0.3.12 [2316f]
   └─ @mole-inc/bin-wrapper@npm:8.0.1 (via npm:^8.0.1)

file-type@^17 changed the package format to be ESM (while 16 is CJS), which is likely why things got confused by Next.

Removing @swc/cli fixed the conflict (I didn't need it), but for the people that do need it, we should still look into upgrading file-types to v19.

denolfe commented 4 months ago

Fix released in https://github.com/payloadcms/payload/releases/tag/v3.0.0-beta.21

erickreutz commented 4 months ago

I'm running into this issue here: https://github.com/payloadcms/payload/blob/v3.0.0-beta.30/packages/payload/src/uploads/getFileByPath.ts#L1

file:///vercel/path0/node_modules/payload/dist/uploads/getFileByPath.js:1
--
10:38:49.741 | import fileType from 'file-type';
10:38:49.742 | ^^^^^^^^
10:38:49.742 | SyntaxError: The requested module 'file-type' does not provide an export named 'default'
10:38:49.742 | at ModuleJob._instantiate (node:internal/modules/esm/module_job:134:21)
10:38:49.742 | at async ModuleJob.run (node:internal/modules/esm/module_job:217:5)
10:38:49.742 | at async ModuleLoader.import (node:internal/modules/esm/loader:323:24)
10:38:49.742 | at async loadESM (node:internal/process/esm_loader:28:7)
10:38:49.742 | at async handleMainPromise (node:internal/modules/run_main:113:12)

this patch fixed it

diff --git a/node_modules/payload/dist/uploads/generateFileData.js b/node_modules/payload/dist/uploads/generateFileData.js
index 5bab623..edf0521 100644
--- a/node_modules/payload/dist/uploads/generateFileData.js
+++ b/node_modules/payload/dist/uploads/generateFileData.js
@@ -1,5 +1,4 @@
-import fileType from 'file-type';
-const { fromBuffer } = fileType;
+import { fileTypeFromBuffer } from 'file-type';
 import fs from 'fs';
 import mkdirp from 'mkdirp';
 import sanitize from 'sanitize-filename';
@@ -98,7 +97,7 @@ export const generateFileData = async ({ collection: { config: collectionConfig
             fileBuffer = await sharpFile.toBuffer({
                 resolveWithObject: true
             });
-            ({ ext, mime } = await fromBuffer(fileBuffer.data) // This is getting an incorrect gif height back.
+            ({ ext, mime } = await fileTypeFromBuffer(fileBuffer.data) // This is getting an incorrect gif height back.
             );
             fileData.width = fileBuffer.info.width;
             fileData.height = fileBuffer.info.height;
diff --git a/node_modules/payload/dist/uploads/getFileByPath.js b/node_modules/payload/dist/uploads/getFileByPath.js
index 6d8ccdf..b258082 100644
--- a/node_modules/payload/dist/uploads/getFileByPath.js
+++ b/node_modules/payload/dist/uploads/getFileByPath.js
@@ -1,14 +1,13 @@
-import fileType from 'file-type';
+import { fileTypeFromFile } from 'file-type';
 import fs from 'fs';
 import path from 'path';
-const { fromFile } = fileType;
 const mimeTypeEstimate = {
     svg: 'image/svg+xml'
 };
 export const getFileByPath = async (filePath)=>{
     if (typeof filePath === 'string') {
         const data = fs.readFileSync(filePath);
-        const mimetype = fromFile(filePath);
+        const mimetype = fileTypeFromFile(filePath);
         const { size } = fs.statSync(filePath);
         const name = path.basename(filePath);
         const ext = path.extname(filePath).slice(1);
diff --git a/node_modules/payload/dist/uploads/imageResizer.js b/node_modules/payload/dist/uploads/imageResizer.js
index 97d7c56..06521aa 100644
--- a/node_modules/payload/dist/uploads/imageResizer.js
+++ b/node_modules/payload/dist/uploads/imageResizer.js
@@ -1,5 +1,4 @@
-import fileType from 'file-type';
-const { fromBuffer } = fileType;
+import { fileTypeFromBuffer } from 'file-type';
 import fs from 'fs';
 import sanitize from 'sanitize-filename';
 import { isNumber } from '../utilities/isNumber.js';
@@ -208,7 +207,7 @@ import fileExists from './fileExists.js';
         });
         const sanitizedImage = getSanitizedImageData(savedFilename);
         req.payloadUploadSizes[imageResizeConfig.name] = bufferData;
-        const mimeInfo = await fromBuffer(bufferData);
+        const mimeInfo = await fileTypeFromBuffer(bufferData);
         const imageNameWithDimensions = createImageName(sanitizedImage.name, bufferInfo, mimeInfo?.ext || sanitizedImage.ext);
         const imagePath = `${staticPath}/${imageNameWithDimensions}`;
         if (await fileExists(imagePath)) {