fix (hasura-storage-js/docs): use correct way of specifying metadata[] in formData (#3418)

### **PR Type**
Bug fix


___

### **Description**
- Fix metadata[] specification in formData for file uploads

- Use Blob with JSON.stringify for metadata[] in multiple files

- Update documentation and example code for correct usage

- Ensure compatibility across different environments (browser/Node.js)


___

### Diagram Walkthrough


```mermaid
flowchart LR
  A["Old metadata[] handling"] --> B["New metadata[] handling"]
  B --> C["Use Blob"]
  C --> D["JSON.stringify"]
  D --> E["Set content type"]
  E --> F["Empty filename"]
```



<details> <summary><h3> File Walkthrough</h3></summary>

<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Bug
fix</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>hasura-storage-api.ts</strong><dd><code>Update
metadata[] handling in file upload</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></summary>
<hr>

packages/hasura-storage-js/src/hasura-storage-api.ts

<ul><li>Replace direct JSON.stringify with Blob for metadata[]<br> <li>
Set content type to 'application/json'<br> <li> Add empty string as
third argument for filename</ul>


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3418/files#diff-b57b3bb982394c4bc702c400e0798bb62a3371fdc13c91754d68ce5a5d0e7afc">+5/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr><tr><td><strong>Documentation</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>upload-file.mdx</strong><dd><code>Update documentation
for correct metadata[] usage</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

docs/reference/storage/upload-file.mdx

<ul><li>Update example code for correct metadata[] usage<br> <li> Use
Blob with JSON.stringify for metadata[]<br> <li> Set content type and
add empty filename</ul>


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3418/files#diff-d0a3eae50a19e63cf2d66ab4f644104fa20a946b24122254ec4a368f847292d1">+9/-5</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr><tr><td><strong>Enhancement</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>uploadFormData.mjs</strong><dd><code>Update example
code for correct metadata[] handling</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></summary>
<hr>

examples/node-storage/src/uploadFormData.mjs

<ul><li>Update example code for multiple file uploads<br> <li> Use Blob
with JSON.stringify for each metadata[] entry<br> <li> Set content type
and add empty filename for each entry</ul>


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3418/files#diff-409940e89eec273da12632fa6eaf09fa331c8806ef03882543616282921e12c4">+10/-2</a>&nbsp;
&nbsp; </td>

</tr>
</table></td></tr></tr></tbody></table>

</details>

___
This commit is contained in:
David Barroso
2025-08-13 14:16:56 +02:00
committed by GitHub
parent 06b47e0fb9
commit 2f5bc04e0c
26 changed files with 161 additions and 165 deletions

View File

@@ -0,0 +1,7 @@
---
'@nhost/hasura-storage-js': minor
'@nhost-examples/node-storage': minor
'@nhost/docs': minor
---
fix (hasura-storage-js/docs): use correct way of specifying metadata[] in formData

View File

@@ -45,7 +45,7 @@
"@mui/material": "^5.15.14",
"@mui/system": "^5.15.14",
"@mui/x-date-pickers": "^5.0.20",
"@nhost/nhost-js-beta": "npm:@nhost/nhost-js@5.0.0-beta.7",
"@nhost/nhost-js-beta": "npm:@nhost/nhost-js@5.0.0-beta.8",
"@radix-ui/react-accordion": "^1.2.1",
"@radix-ui/react-alert-dialog": "^1.1.2",
"@radix-ui/react-checkbox": "^1.1.2",

View File

@@ -42,7 +42,7 @@ export default function useProject(): UseProjectReturnType {
const { data, isLoading, refetch, error } = useQuery(
['project', appSubdomain as string],
async () => {
const response = await nhost.graphql.post<{
const response = await nhost.graphql.request<{
apps: ProjectFragment[];
}>(GetProjectDocument, { subdomain: (appSubdomain as string) || '' });
return response.body;

View File

@@ -44,7 +44,7 @@ export default function useProjectWithState(): UseProjectWithStateReturnType {
const { data, isLoading, refetch, error, isFetched } = useQuery({
queryKey: ['projectWithState', appSubdomain as string],
queryFn: async () => {
const response = await nhost.graphql.post<{
const response = await nhost.graphql.request<{
apps: ProjectFragment[];
}>(GetProjectStateDocument, {
subdomain: (appSubdomain as string) || '',

View File

@@ -219,14 +219,17 @@ export default function DataGridPreviewCell<TData extends object>({
dispatch({ type: 'PREVIEW_LOADING' });
}
const { body: presignedUrl } = await appClient.storage.getPresignedURL(id, {
headers: {
'x-hasura-admin-secret':
process.env.NEXT_PUBLIC_ENV === 'dev'
? getHasuraAdminSecret()
: project!.config!.hasura.adminSecret,
const { body: presignedUrl } = await appClient.storage.getFilePresignedURL(
id,
{
headers: {
'x-hasura-admin-secret':
process.env.NEXT_PUBLIC_ENV === 'dev'
? getHasuraAdminSecret()
: project!.config!.hasura.adminSecret,
},
},
});
);
if (presignedUrl?.url) {
if (!isPreviewable) {

View File

@@ -2,7 +2,7 @@ import type { Organization, Project } from '@/types/application';
import { ApplicationStatus } from '@/types/application';
import { Organization_Status_Enum } from '@/utils/__generated__/graphql';
import { faker } from '@faker-js/faker';
import type { Session } from '@nhost/nhost-js-beta/auth';
import type { Session } from '@nhost/nhost-js-beta/session';
import type { NextRouter } from 'next/router';
import { vi } from 'vitest';
@@ -84,10 +84,20 @@ export const mockApplication: Project = {
};
export const mockSession: Session = {
accessToken: faker.random.alphaNumeric(),
accessToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c',
accessTokenExpiresIn: 86400,
refreshToken: faker.datatype.uuid(),
refreshTokenId: faker.datatype.uuid(),
decodedToken: {
sub: '1234567890',
iat: 1516239022,
exp: 1516325422,
'https://hasura.io/jwt/claims': {
'x-hasura-allowed-roles': ['user', 'me'],
'x-hasura-default-role': 'user',
'x-hasura-user-id': '1234567890',
},
},
user: {
id: faker.datatype.uuid(),
email: faker.internet.email(),

View File

@@ -5,8 +5,7 @@ import {
getStorageServiceUrl,
} from '@/utils/env';
import { createClient } from '@nhost/nhost-js-beta';
import { type Session } from '@nhost/nhost-js-beta/auth';
import { type SessionStorageBackend } from '@nhost/nhost-js-beta/session';
import { type Session, type SessionStorageBackend } from '@nhost/nhost-js-beta/session';
const nhost = createClient({
authUrl: getAuthServiceUrl(),

View File

@@ -35,11 +35,15 @@ form.append("bucket-id", "<string>");
form.append("file[]", <file_object>);
form.append("metadata[]", JSON.stringify({
"id": "<string>",
"metadata": {},
"name": "<string>"
}));
form.append(
"metadata[]",
new Blob([JSON.stringify({
"id": "<string>",
"metadata": {},
"name": "<string>"
})], {type: "application/json"}),
"",
);
const options = {
method: 'POST',

View File

@@ -36,9 +36,17 @@ export async function uploadFormData() {
const formData = new FormData()
formData.append('file[]', Buffer.from(arrayBuffer), customValues[0].name)
formData.append('metadata[]', JSON.stringify({ id: customValues[0].id }))
formData.append(
'metadata[]',
new Blob([JSON.stringify({ id: customValues[0].id })], { type: 'application/json' }),
"",
)
formData.append('file[]', Buffer.from(arrayBuffer), customValues[1].name)
formData.append('metadata[]', JSON.stringify({ id: customValues[1].id }))
formData.append(
'metadata[]',
new Blob([JSON.stringify({ id: customValues[1].id })], { type: 'application/json' }),
"",
)
// Upload files to Nhost Storage
const { error: uploadError, fileMetadata } = await client.storage.upload({

View File

@@ -15,7 +15,12 @@ export default function UploadSingleFile({ onUpload }: UploadSingleFileProps) {
multiple: false,
onDropAccepted: async (files) => {
if (files.length > 0) {
await upload({ file: files[0] })
await upload(
{
file: files[0],
name: `ra-${files[0].name}`,
},
)
onUpload?.()
}
}

34
flake.lock generated
View File

@@ -33,18 +33,40 @@
"type": "github"
}
},
"nix2container": {
"inputs": {
"nixpkgs": [
"nixops",
"nixpkgs"
]
},
"locked": {
"lastModified": 1752002763,
"narHash": "sha256-JYAkdZvpdSx9GUoHPArctYMypSONob4DYKRkOubUWtY=",
"owner": "nlewo",
"repo": "nix2container",
"rev": "4f2437f6a1844b843b380d483087ae6d461240ee",
"type": "github"
},
"original": {
"owner": "nlewo",
"repo": "nix2container",
"type": "github"
}
},
"nixops": {
"inputs": {
"flake-utils": "flake-utils",
"nix-filter": "nix-filter",
"nix2container": "nix2container",
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1745925792,
"narHash": "sha256-tSN3G8dAm4cX6vG6Agm/jXGhBrsHgewHCHVF0LR52fQ=",
"lastModified": 1754635544,
"narHash": "sha256-/46fUYRUvpwxTb+diHQa8nS/OPJLblKTMOeYXpWsdC0=",
"owner": "nhost",
"repo": "nixops",
"rev": "555a2f79e2a0187c0e2f33d519c8e79041b681e1",
"rev": "ff80fd734426f1de7599c742dfa3e273c9939049",
"type": "github"
},
"original": {
@@ -55,11 +77,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1745804731,
"narHash": "sha256-v/sK3AS0QKu/Tu5sHIfddiEHCvrbNYPv8X10Fpux68g=",
"lastModified": 1753399495,
"narHash": "sha256-7XG/QBqhrYOyA2houjRTL2NMa7IKZZ/somBqr+Q/6Wo=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "29335f23bea5e34228349ea739f31ee79e267b88",
"rev": "0d00f23f023b7215b3f1035adb5247c8ec180dbc",
"type": "github"
},
"original": {

View File

@@ -1,63 +0,0 @@
{ final }:
let
version = "v1.29.6";
dist = {
aarch64-darwin = {
url = "https://github.com/nhost/cli/releases/download/${version}/cli-${version}-darwin-arm64.tar.gz";
sha256 = "0jbi1ihidpjfs0igjv6h6jg4jisnjggy9lyncpsafqbpgvr9gpy8";
};
x86_64-darwin = {
url = "https://github.com/nhost/cli/releases/download/${version}/cli-${version}-darwin-amd64.tar.gz";
sha256 = "1rirxir3y4qvbf91j0npcwiqkpagg336iani3mh2mwmbqxmzvacp";
};
aarch64-linux = {
url = "https://github.com/nhost/cli/releases/download/${version}/cli-${version}-linux-arm64.tar.gz";
sha256 = "0c0k2zcnvly91gzvqmkqnl4nvxypk6nx1k5zlnjxgc59s37vr2xn";
};
x86_64-linux = {
url = "https://github.com/nhost/cli/releases/download/${version}/cli-${version}-linux-amd64.tar.gz";
sha256 = "0kp7jwxryb6h3mb1nk125qrflsx32bz2b6jkhrwpgfdfy0w2vawr";
};
};
in
final.stdenvNoCC.mkDerivation {
pname = "nhost-cli";
inherit version;
src = final.fetchurl {
inherit (dist.${final.stdenvNoCC.hostPlatform.system} or
(throw "Unsupported system: ${final.stdenvNoCC.hostPlatform.system}")) url sha256;
};
sourceRoot = ".";
nativeBuildInputs = [
final.unzip
final.makeWrapper
final.installShellFiles
];
installPhase = ''
runHook preInstall
mkdir -p $out/bin
mv cli $out/bin/nhost
# installShellCompletion --cmd nhost \
# --bash <($out/bin/nhost completion bash) \
# --fish <($out/bin/nhost completion fish) \
# --zsh <($out/bin/nhost completion zsh)
runHook postInstall
'';
meta = with final.lib; {
description = "Nhost CLI";
homepage = "https://nhost.io";
license = licenses.mit;
maintainers = [ "@nhost" ];
};
}

View File

@@ -1,7 +1,6 @@
(final: prev: rec {
nodejs = final.nodejs_20;
nodePackages = nodejs.pkgs;
nhost-cli = final.callPackage ./nhost-cli.nix { inherit final; };
pnpm_10 = final.callPackage "${final.path}/pkgs/development/tools/pnpm/generic.nix" {
version = "10.1.0";

View File

@@ -5,5 +5,4 @@ settings:
excludeLinksFromLockfile: false
importers:
.: {}

View File

@@ -1,7 +1,7 @@
[global]
[hasura]
version = 'v2.44.0-ce'
version = 'v2.46.0-ce'
adminSecret = '{{ secrets.HASURA_GRAPHQL_ADMIN_SECRET }}'
webhookSecret = '{{ secrets.NHOST_WEBHOOK_SECRET }}'
@@ -28,7 +28,7 @@ httpPoolSize = 100
version = 22
[auth]
version = '0.38.0'
version = '0.41.1'
[auth.redirections]
clientUrl = 'http://localhost:3000'
@@ -133,7 +133,7 @@ timeout = 60000
enabled = false
[postgres]
version = '15.10-20250311-1'
version = '17.5-20250728-1'
[postgres.resources.storage]
capacity = 1

View File

@@ -62,8 +62,6 @@
"docgen": "pnpm typedoc && docgen --config ./storage.docgen.json"
},
"dependencies": {
"fetch-ponyfill": "^7.1.0",
"form-data": "^4.0.0",
"graphql": "16.8.1",
"xstate": "^4.38.3"
},
@@ -74,4 +72,4 @@
"pixelmatch": "^5.3.0",
"uuid": "^9.0.1"
}
}
}

View File

@@ -1,6 +1,3 @@
import fetchPonyfill from 'fetch-ponyfill'
import LegacyFormData from 'form-data'
import {
ApiDeleteParams,
ApiDeleteResponse,
@@ -16,12 +13,6 @@ import {
import { fetchUpload } from './utils/upload'
import { appendImageTransformationParameters } from './utils'
let fetch: any
if (typeof fetch === 'undefined') {
fetch = fetchPonyfill().fetch
}
/**
* @internal
* This is an internal class.
@@ -74,17 +65,19 @@ export class HasuraStorageApi {
name,
headers: extraHeaders
}: StorageUploadFileParams): Promise<StorageUploadFileResponse> {
const formData = typeof window === 'undefined' ? new LegacyFormData() : new FormData()
const formData = new FormData()
formData.append('file[]', file)
formData.append('metadata[]', JSON.stringify({ id, name }))
formData.append(
'metadata[]',
new Blob([JSON.stringify({ id, name })], { type: 'application/json' }),
''
)
const { error, fileMetadata } = await fetchUpload(this.url, formData, {
accessToken: this.accessToken,
adminSecret: this.adminSecret,
bucketId,
fileId: id,
name,
headers: {
...this.headers, // global nhost storage client headers to be sent with all `uploadFile` calls
...extraHeaders // extra headers to be sent with a specific call

View File

@@ -2,14 +2,6 @@ import { assign, createMachine } from 'xstate'
import { FileUploadConfig, StorageErrorPayload } from '../utils'
import { fetchUpload } from '../utils/upload'
import FallbackFormData from 'form-data'
let FormData: any
if (typeof FormData === 'undefined') {
FormData = FallbackFormData
}
export type FileUploadContext = {
progress: number | null
loaded: number

View File

@@ -1,5 +1,3 @@
import LegacyFormData from 'form-data'
// TODO shared with other packages
export type StorageErrorPayload = {
error: string
@@ -39,7 +37,7 @@ export interface StorageUploadFileParams extends StorageHeadersParam {
// works in browser and server
export interface StorageUploadFormDataParams extends StorageHeadersParam {
formData: FormData | LegacyFormData
formData: FormData
bucketId?: string
}

View File

@@ -1,9 +1,5 @@
import fetchPonyfill from 'fetch-ponyfill'
import LegacyFormData from 'form-data'
import { StorageErrorPayload, StorageUploadResponse } from './types'
let fetch = globalThis.fetch
/** Convert any string into ISO-8859-1 */
export const toIso88591 = (fileName: string) => {
try {
@@ -16,7 +12,7 @@ export const toIso88591 = (fileName: string) => {
export const fetchUpload = async (
backendUrl: string,
data: FormData | LegacyFormData,
data: FormData,
{
accessToken,
name,
@@ -48,14 +44,25 @@ export const fetchUpload = async (
headers['Authorization'] = `Bearer ${accessToken}`
}
if ((name || fileId) && !data.has('metadata[]')) {
const metadata: Record<string, string> = {}
if (name) {
metadata.name = name
}
if (fileId) {
metadata.id = fileId
}
data.append(
'metadata[]',
new Blob([JSON.stringify(metadata)], { type: 'application/json' }),
"",
)
}
const url = `${backendUrl}/files`
if (typeof XMLHttpRequest === 'undefined') {
// * Non-browser environment: XMLHttpRequest is not available
try {
if (data instanceof LegacyFormData) {
fetch = fetchPonyfill().fetch
}
const response = await fetch(url, {
method: 'POST',
headers,

View File

@@ -6,10 +6,12 @@ import { storage } from './utils/helpers'
describe('test delete file', () => {
it('should be able to get delete file', async () => {
const file = fs.createReadStream('./tests/assets/sample.pdf')
const file = new File([fs.readFileSync('./tests/assets/sample.pdf')], 'sample.pdf', {
type: 'application/pdf'
})
const { fileMetadata } = await storage.upload({
file: file as unknown as File
file: file,
})
const { error } = await storage.delete({

View File

@@ -1,4 +1,3 @@
import FormData from 'form-data'
import fs from 'fs'
import { v4 as uuidv4 } from 'uuid'
import { describe, expect, it } from 'vitest'
@@ -7,7 +6,10 @@ import { storage } from './utils/helpers'
describe('test get presigned url of file', () => {
it('should be able to get presigned url of file', async () => {
const formData = new FormData()
formData.append('file', fs.createReadStream('./tests/assets/sample.pdf'))
const file = new File([fs.readFileSync('./tests/assets/sample.pdf')], 'sample.pdf', {
type: 'application/pdf'
})
formData.append('file[]', file)
const { fileMetadata } = await storage.upload({ formData })

View File

@@ -1,4 +1,3 @@
import FormData from 'form-data'
import fs from 'fs'
import { v4 as uuidv4 } from 'uuid'
import { describe, expect, it } from 'vitest'
@@ -7,7 +6,10 @@ import { storage } from './utils/helpers'
describe('test get file', () => {
it('should be able to get uploaded file', async () => {
const fd = new FormData()
fd.append('file', fs.createReadStream('./tests/assets/sample.pdf'))
const file = new File([fs.readFileSync('./tests/assets/sample.pdf')], 'sample.pdf', {
type: 'application/pdf'
})
fd.append('file[]', file)
const { fileMetadata, error } = await storage.upload({
formData: fd

View File

@@ -1,4 +1,3 @@
import FormData from 'form-data'
import fs from 'fs'
import jpeg from 'jpeg-js'
import pixelmatch from 'pixelmatch'
@@ -11,8 +10,12 @@ const downloadJpeg = async (url: string) =>
describe('Image transformation', () => {
let fileId: string
beforeAll(async () => {
const file = new File([fs.readFileSync('./tests/assets/image.jpeg')], 'image.jpeg', {
type: 'image/jpeg'
})
const fd = new FormData()
fd.append('file', fs.createReadStream('./tests/assets/image.jpeg'))
fd.append('file[]', file)
const { fileMetadata } = await storage.upload({
formData: fd

View File

@@ -1,16 +1,15 @@
import fetchPonyfill from 'fetch-ponyfill'
import FormData from 'form-data'
import fs from 'fs'
import { v4 as uuidv4 } from 'uuid'
import { describe, expect, it } from 'vitest'
import { storage } from './utils/helpers'
const { fetch } = fetchPonyfill()
describe('test upload', () => {
it('should upload a file from the file system', async () => {
const file = new File([fs.readFileSync('./tests/assets/sample.pdf')], 'sample.pdf', {
type: 'application/pdf'
})
const fd = new FormData()
fd.append('file', fs.createReadStream('./tests/assets/sample.pdf'))
fd.append('file[]', file)
const { error } = await storage.upload({
formData: fd
@@ -26,7 +25,7 @@ describe('test upload', () => {
// create form data
const fd = new FormData()
fd.append('file', blob.stream(), 'logo.png')
fd.append('file[]', blob, 'logo.png')
const { error } = await storage.upload({
formData: fd
@@ -38,10 +37,11 @@ describe('test upload', () => {
it('should upload a file with specific id', async () => {
const RANDOM_UUID = uuidv4()
const file = fs.createReadStream('./tests/assets/sample.pdf')
const fileBuffer = fs.readFileSync('./tests/assets/sample.pdf')
const file = new File([fileBuffer], 'sample.pdf', { type: 'application/pdf' })
const { fileMetadata, error } = await storage.upload({
file: file as unknown as File,
file: file,
id: RANDOM_UUID
})
@@ -58,7 +58,9 @@ describe('test upload', () => {
it('should upload a file with specific name', async () => {
const FILE_NAME = 'special-name.pdf'
const file = fs.createReadStream('./tests/assets/sample.pdf')
const file = new File([fs.readFileSync('./tests/assets/sample.pdf')], 'sample.pdf', {
type: 'application/pdf'
})
const { fileMetadata, error } = await storage.upload({
file: file as unknown as File,
@@ -76,10 +78,12 @@ describe('test upload', () => {
})
it('should upload a file with a non-ISO 8859-1 name', async () => {
const file = fs.createReadStream('./tests/assets/sample.pdf')
const file = new File([fs.readFileSync('./tests/assets/sample.pdf')], 'sample.pdf', {
type: 'application/pdf'
})
const { fileMetadata, error } = await storage.upload({
file: file as unknown as File,
file: file,
name: '你 好'
})
@@ -97,7 +101,9 @@ describe('test upload', () => {
const RANDOM_UUID = uuidv4()
const FILE_NAME = 'special-name.pdf'
const file = fs.createReadStream('./tests/assets/sample.pdf')
const file = new File([fs.readFileSync('./tests/assets/sample.pdf')], 'sample.pdf', {
type: 'application/pdf'
})
const { fileMetadata, error } = await storage.upload({
file: file as unknown as File,
@@ -118,7 +124,10 @@ describe('test upload', () => {
it('should upload a file with specific bucket id', async () => {
const fd = new FormData()
fd.append('file', fs.createReadStream('./tests/assets/sample.pdf'))
const file = new File([fs.readFileSync('./tests/assets/sample.pdf')], 'sample.pdf', {
type: 'application/pdf'
})
fd.append('file[]', file)
const { fileMetadata, error } = await storage.upload({
formData: fd,
@@ -138,7 +147,10 @@ describe('test upload', () => {
it.skip('should upload a file with specific bucket id (test-bucket)', async () => {
const fd = new FormData()
fd.append('file', fs.createReadStream('./tests/assets/sample.pdf'))
const file = new File([fs.readFileSync('./tests/assets/sample.pdf')], 'sample.pdf', {
type: 'application/pdf'
})
fd.append('file[]', file)
const { fileMetadata, error } = await storage.upload({
formData: fd,

16
pnpm-lock.yaml generated
View File

@@ -269,8 +269,8 @@ importers:
specifier: ^5.0.20
version: 5.0.20(@emotion/react@11.11.4(@types/react@18.3.4)(react@18.2.0))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.4)(react@18.2.0))(@types/react@18.3.4)(react@18.2.0))(@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.4)(react@18.2.0))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.4)(react@18.2.0))(@types/react@18.3.4)(react@18.2.0))(@types/react@18.3.4)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@mui/system@5.15.15(@emotion/react@11.11.4(@types/react@18.3.4)(react@18.2.0))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.4)(react@18.2.0))(@types/react@18.3.4)(react@18.2.0))(@types/react@18.3.4)(react@18.2.0))(@types/react@18.3.4)(date-fns@2.30.0)(dayjs@1.11.11)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
'@nhost/nhost-js-beta':
specifier: npm:@nhost/nhost-js@5.0.0-beta.7
version: '@nhost/nhost-js@5.0.0-beta.7'
specifier: npm:@nhost/nhost-js@5.0.0-beta.8
version: '@nhost/nhost-js@5.0.0-beta.8'
'@radix-ui/react-accordion':
specifier: ^1.2.1
version: 1.2.2(@types/react-dom@18.3.0)(@types/react@18.3.4)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
@@ -1992,12 +1992,6 @@ importers:
packages/hasura-storage-js:
dependencies:
fetch-ponyfill:
specifier: ^7.1.0
version: 7.1.0(encoding@0.1.13)
form-data:
specifier: '>=4.0.4'
version: 4.0.4
graphql:
specifier: 16.8.1
version: 16.8.1
@@ -4970,8 +4964,8 @@ packages:
cpu: [x64]
os: [win32]
'@nhost/nhost-js@5.0.0-beta.7':
resolution: {integrity: sha512-usfX+azFr38zKsHXC0b5lqZCKJz32Hdi9QuLUkNO1amPENgkR95t2ZcZbxllJj7qiFXYsrmwfp/nxMz64HIsYg==}
'@nhost/nhost-js@5.0.0-beta.8':
resolution: {integrity: sha512-741YBbDXcK6oiVJtcpDYWzzUk8/dFOjGHBdpHsGoO+SICk6Jpsf3zgqpxFqVRzN8SYrnfDXIHZxtEo4uCJOVhw==}
engines: {node: '>=20'}
'@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1':
@@ -22260,7 +22254,7 @@ snapshots:
'@next/swc-win32-x64-msvc@14.2.30':
optional: true
'@nhost/nhost-js@5.0.0-beta.7': {}
'@nhost/nhost-js@5.0.0-beta.8': {}
'@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1':
dependencies: