Compare commits

..

32 Commits

Author SHA1 Message Date
Johan Eliasson
9dea25ebe1 Merge pull request #900 from nhost/changeset-release/main
chore: update versions
2022-08-25 10:58:02 +02:00
github-actions[bot]
9b063abe32 chore: update versions 2022-08-25 07:53:20 +00:00
Johan Eliasson
cea97ba333 Merge pull request #898 from nhost/changeset-iasgd9ad
adding changeset for storage upload
2022-08-25 09:52:09 +02:00
Johan Eliasson
607c457f9d adding changeset for storage upload 2022-08-25 09:14:56 +02:00
Johan Eliasson
6ea9ed69ce Merge pull request #893 from nhost/fix/storage-in-node
Make @nhost/storage-js work on non-browser environments
2022-08-25 09:03:16 +02:00
Johan Eliasson
6450dcc02e overloading 2022-08-25 08:20:31 +02:00
Johan Eliasson
0b18704d5b updates 2022-08-24 18:04:07 +02:00
Johan Eliasson
0c53f9034e adding empty functions folder for nhost-js 2022-08-24 15:07:52 +02:00
Johan Eliasson
0c90292779 adding correct health check endpoints and new vite config files where needed 2022-08-24 15:05:24 +02:00
Johan Eliasson
2333aeb0c8 no tests 2022-08-24 14:58:13 +02:00
Johan Eliasson
3b686a231b use GET request 2022-08-24 14:47:01 +02:00
Johan Eliasson
136b85c5fb add empty package.json in the functions folder 2022-08-24 13:53:30 +02:00
Johan Eliasson
3d715d5f95 wait for hasura console to be up' 2022-08-24 10:38:34 +02:00
Johan Eliasson
6d5295aeca exclude is not needed as we're using include 2022-08-24 10:29:26 +02:00
Johan Eliasson
45f6285249 vite config for storage-js 2022-08-24 10:21:02 +02:00
Pierre-Louis Mercereau
01fb999c7d ci: remove chown 2022-08-24 10:14:52 +02:00
Johan Eliasson
8b8412d5fa exclude paths for vitest 2022-08-24 10:11:51 +02:00
Pierre-Louis Mercereau
0f1311c5b0 ci: correct gh expression 2022-08-24 10:09:34 +02:00
Pierre-Louis Mercereau
6b197aa886 ci: chown package folder 2022-08-24 10:05:14 +02:00
Pierre-Louis Mercereau
0353c6648e ci: change permissions 2022-08-24 09:58:55 +02:00
Johan Eliasson
978b8f8f68 install cli as sudo 2022-08-24 09:37:06 +02:00
Johan Eliasson
3643449a9a update 2022-08-24 07:59:04 +02:00
Johan Eliasson
8e25971e7d move nhost folder 2022-08-24 07:44:24 +02:00
Johan Eliasson
5cf05c8731 correct config 2022-08-23 13:51:48 +02:00
Johan Eliasson
4da70abcfb cleanup 2022-08-23 13:50:31 +02:00
Johan Eliasson
2d5203872c delete test functions folder 2022-08-23 13:49:31 +02:00
Johan Eliasson
882f1531ab update types and docs 2022-08-23 13:47:48 +02:00
Johan Eliasson
6126d77b01 updated tests 2022-08-23 13:47:48 +02:00
Johan Eliasson
09debbd746 Merge branch 'main' into fix/storage-in-node 2022-08-23 12:12:51 +02:00
Johan Eliasson
604ed6b314 readme update 2022-08-23 12:12:11 +02:00
Johan Eliasson
2f1fec1dcf new tests 2022-08-23 12:07:19 +02:00
Johan Eliasson
70f537841f make storage work on server 2022-08-23 08:01:28 +02:00
121 changed files with 1607 additions and 292 deletions

View File

@@ -3,25 +3,25 @@
title: upload()
sidebar_label: upload()
slug: /reference/javascript/storage/upload
description: Use `nhost.storage.upload` to upload a file. The `file` must be of type [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File).
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/hasura-storage-client.ts#L52
description: Use `nhost.storage.upload` to upload a file.
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/hasura-storage-client.ts#L76
---
# `upload()`
Use `nhost.storage.upload` to upload a file. The `file` must be of type [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File).
## Overload 1 of 2
If no `bucket` is specified the `default` bucket will be used.
Use `nhost.storage.upload` to upload a file.
```ts
await nhost.storage.upload({ file })
```
It's possible to use [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) or [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) to upload a file. The `File` instance is only available in the browser while `FormData` with [`form-data`](https://www.npmjs.com/package/form-data) works both in the browser and in NodeJS (server).
## Parameters
If no `bucketId` is specified the bucket `default` is used.
### Parameters
---
**<span className="parameter-name">params</span>** <span className="optional-status">required</span> [`StorageUploadParams`](/reference/docgen/javascript/storage/types/storage-upload-params)
**<span className="parameter-name">params</span>** <span className="optional-status">required</span> [`StorageUploadFileParams`](/reference/docgen/javascript/storage/types/storage-upload-file-params)
| Property | Type | Required | Notes |
| :------------------------------------------------------------------------------------------ | :------- | :------: | :---- |
@@ -32,12 +32,44 @@ await nhost.storage.upload({ file })
---
## Examples
### Examples
Upload a file from a browser using `File`.
```ts
await nhost.storage.upload({ file })
```
Upload a file from a browser using `File` to a specific Bucket.
```ts
await nhost.storage.upload({ file, bucketId: '<Bucket-ID>' })
```
Upload a file from a server using `FormData` with [`form-data`](https://www.npmjs.com/package/form-data).
```ts
const fd = new FormData()
fd.append('file', fs.createReadStream('./tests/assets/sample.pdf'))
await storage.upload({
formData: fd
})
```
## Overload 2 of 2
### Parameters
---
**<span className="parameter-name">params</span>** <span className="optional-status">required</span> [`StorageUploadFormDataParams`](/reference/docgen/javascript/storage/types/storage-upload-form-data-params)
| Property | Type | Required | Notes |
| :------------------------------------------------------------------------------------------ | :--------- | :------: | :---- |
| <span className="parameter-name"><span className="light-grey">params.</span>formData</span> | `FormData` | ✔️ | |
| <span className="parameter-name"><span className="light-grey">params.</span>bucketId</span> | `string` | | |
| <span className="parameter-name"><span className="light-grey">params.</span>name</span> | `string` | | |
| <span className="parameter-name"><span className="light-grey">params.</span>id</span> | `string` | | |
---

View File

@@ -5,7 +5,7 @@ sidebar_label: getUrl()
slug: /reference/javascript/storage/get-url
sidebar_class_name: deprecated
description: No description provided.
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/hasura-storage-client.ts#L74
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/hasura-storage-client.ts#L106
---
# `getUrl()`

View File

@@ -4,7 +4,7 @@ title: getPublicUrl()
sidebar_label: getPublicUrl()
slug: /reference/javascript/storage/get-public-url
description: Use `nhost.storage.getPublicUrl` to get the public URL of a file. The public URL can be used for un-authenticated users to access files. To access public files the `public` role must have permissions to select the file in the `storage.files` table.
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/hasura-storage-client.ts#L88
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/hasura-storage-client.ts#L120
---
# `getPublicUrl()`

View File

@@ -4,7 +4,7 @@ title: getPresignedUrl()
sidebar_label: getPresignedUrl()
slug: /reference/javascript/storage/get-presigned-url
description: Use `nhost.storage.getPresignedUrl` to get a presigned URL of a file. To get a presigned URL the user must have permission to select the file in the `storage.files` table.
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/hasura-storage-client.ts#L110
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/hasura-storage-client.ts#L142
---
# `getPresignedUrl()`

View File

@@ -4,7 +4,7 @@ title: delete()
sidebar_label: delete()
slug: /reference/javascript/storage/delete
description: Use `nhost.storage.delete` to delete a file. To delete a file the user must have permissions to delete the file in the `storage.files` table. Deleting the file using `nhost.storage.delete()` will delete both the file and its metadata.
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/hasura-storage-client.ts#L135
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/hasura-storage-client.ts#L167
---
# `delete()`

View File

@@ -4,7 +4,7 @@ title: setAccessToken()
sidebar_label: setAccessToken()
slug: /reference/javascript/storage/set-access-token
description: Use `nhost.storage.setAccessToken` to a set an access token to be used in subsequent storage requests. Note that if you're signin in users with `nhost.auth.signIn()` the access token will be set automatically.
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/hasura-storage-client.ts#L156
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/hasura-storage-client.ts#L188
---
# `setAccessToken()`

View File

@@ -4,7 +4,7 @@ title: setAdminSecret()
sidebar_label: setAdminSecret()
slug: /reference/javascript/storage/set-admin-secret
description: Use `nhost.storage.adminSecret` to set the admin secret to be used for subsequent storage requests. This is useful if you want to run storage in "admin mode".
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/hasura-storage-client.ts#L174
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/hasura-storage-client.ts#L206
---
# `setAdminSecret()`

View File

@@ -4,7 +4,7 @@ title: HasuraStorageClient
sidebar_label: Storage
description: No description provided.
slug: /reference/javascript/storage
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/hasura-storage-client.ts#L25
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/hasura-storage-client.ts#L29
---
# `HasuraStorageClient`

View File

@@ -27,6 +27,6 @@ custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storag
---
**<span className="parameter-name">params</span>** <span className="optional-status">required</span> `Partial<StorageUploadParams>`
**<span className="parameter-name">params</span>** <span className="optional-status">required</span> `Partial<StorageUploadFileParams>`
---

View File

@@ -4,7 +4,7 @@ title: ApiDeleteParams
sidebar_label: ApiDeleteParams
description: No description provided.
displayed_sidebar: referenceSidebar
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/utils/types.ts#L69
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/utils/types.ts#L84
---
# `ApiDeleteParams`

View File

@@ -4,7 +4,7 @@ title: ApiDeleteResponse
sidebar_label: ApiDeleteResponse
description: No description provided.
displayed_sidebar: referenceSidebar
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/utils/types.ts#L73
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/utils/types.ts#L88
---
# `ApiDeleteResponse`

View File

@@ -4,7 +4,7 @@ title: ApiGetPresignedUrlParams
sidebar_label: ApiGetPresignedUrlParams
description: No description provided.
displayed_sidebar: referenceSidebar
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/utils/types.ts#L61
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/utils/types.ts#L76
---
# `ApiGetPresignedUrlParams`

View File

@@ -4,7 +4,7 @@ title: ApiGetPresignedUrlResponse
sidebar_label: ApiGetPresignedUrlResponse
description: No description provided.
displayed_sidebar: referenceSidebar
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/utils/types.ts#L65
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/utils/types.ts#L80
---
# `ApiGetPresignedUrlResponse`

View File

@@ -4,7 +4,7 @@ title: ApiUploadParams
sidebar_label: ApiUploadParams
description: No description provided.
displayed_sidebar: referenceSidebar
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/utils/types.ts#L50
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/utils/types.ts#L65
---
# `ApiUploadParams`
@@ -13,7 +13,7 @@ custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storag
---
**<span className="parameter-name">file</span>** <span className="optional-status">required</span> `FormData`
**<span className="parameter-name">formData</span>** <span className="optional-status">required</span> `FormData`
---

View File

@@ -4,7 +4,7 @@ title: ApiUploadResponse
sidebar_label: ApiUploadResponse
description: No description provided.
displayed_sidebar: referenceSidebar
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/utils/types.ts#L57
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/utils/types.ts#L72
---
# `ApiUploadResponse`

View File

@@ -4,7 +4,7 @@ title: NhostClientReturnType
sidebar_label: NhostClientReturnType
description: No description provided.
displayed_sidebar: referenceSidebar
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/utils/types.ts#L4
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/utils/types.ts#L6
---
# `NhostClientReturnType`

View File

@@ -4,7 +4,7 @@ title: StorageDeleteParams
sidebar_label: StorageDeleteParams
description: No description provided.
displayed_sidebar: referenceSidebar
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/utils/types.ts#L32
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/utils/types.ts#L47
---
# `StorageDeleteParams`

View File

@@ -4,7 +4,7 @@ title: StorageDeleteResponse
sidebar_label: StorageDeleteResponse
description: No description provided.
displayed_sidebar: referenceSidebar
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/utils/types.ts#L36
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/utils/types.ts#L51
---
# `StorageDeleteResponse`

View File

@@ -4,7 +4,7 @@ title: StorageGetPresignedUrlParams
sidebar_label: StorageGetPresignedUrlParams
description: No description provided.
displayed_sidebar: referenceSidebar
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/utils/types.ts#L24
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/utils/types.ts#L39
---
# `StorageGetPresignedUrlParams`

View File

@@ -4,7 +4,7 @@ title: StorageGetPresignedUrlResponse
sidebar_label: StorageGetPresignedUrlResponse
description: No description provided.
displayed_sidebar: referenceSidebar
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/utils/types.ts#L28
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/utils/types.ts#L43
---
# `StorageGetPresignedUrlResponse`

View File

@@ -4,7 +4,7 @@ title: StorageGetUrlParams
sidebar_label: StorageGetUrlParams
description: No description provided.
displayed_sidebar: referenceSidebar
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/utils/types.ts#L20
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/utils/types.ts#L35
---
# `StorageGetUrlParams`

View File

@@ -0,0 +1,30 @@
---
# ⚠️ AUTO-GENERATED CONTENT. DO NOT EDIT THIS FILE DIRECTLY! ⚠️
title: StorageUploadFileParams
sidebar_label: StorageUploadFileParams
description: No description provided.
displayed_sidebar: referenceSidebar
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/utils/types.ts#L13
---
# `StorageUploadFileParams`
## Parameters
---
**<span className="parameter-name">file</span>** <span className="optional-status">required</span> `File`
---
**<span className="parameter-name">bucketId</span>** <span className="optional-status">optional</span> `string`
---
**<span className="parameter-name">name</span>** <span className="optional-status">optional</span> `string`
---
**<span className="parameter-name">id</span>** <span className="optional-status">optional</span> `string`
---

View File

@@ -0,0 +1,30 @@
---
# ⚠️ AUTO-GENERATED CONTENT. DO NOT EDIT THIS FILE DIRECTLY! ⚠️
title: StorageUploadFormDataParams
sidebar_label: StorageUploadFormDataParams
description: No description provided.
displayed_sidebar: referenceSidebar
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/utils/types.ts#L21
---
# `StorageUploadFormDataParams`
## Parameters
---
**<span className="parameter-name">formData</span>** <span className="optional-status">required</span> `FormData`
---
**<span className="parameter-name">bucketId</span>** <span className="optional-status">optional</span> `string`
---
**<span className="parameter-name">name</span>** <span className="optional-status">optional</span> `string`
---
**<span className="parameter-name">id</span>** <span className="optional-status">optional</span> `string`
---

View File

@@ -4,27 +4,11 @@ title: StorageUploadParams
sidebar_label: StorageUploadParams
description: No description provided.
displayed_sidebar: referenceSidebar
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/utils/types.ts#L9
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/utils/types.ts#L29
---
# `StorageUploadParams`
## Parameters
---
**<span className="parameter-name">file</span>** <span className="optional-status">required</span> `File`
---
**<span className="parameter-name">bucketId</span>** <span className="optional-status">optional</span> `string`
---
**<span className="parameter-name">name</span>** <span className="optional-status">optional</span> `string`
---
**<span className="parameter-name">id</span>** <span className="optional-status">optional</span> `string`
---
```ts
type StorageUploadParams = StorageUploadFileParams | StorageUploadFormDataParams
```

View File

@@ -4,7 +4,7 @@ title: StorageUploadResponse
sidebar_label: StorageUploadResponse
description: No description provided.
displayed_sidebar: referenceSidebar
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/utils/types.ts#L16
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/utils/types.ts#L31
---
# `StorageUploadResponse`

View File

@@ -4,7 +4,7 @@ title: UploadHeaders
sidebar_label: UploadHeaders
description: No description provided.
displayed_sidebar: referenceSidebar
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/utils/types.ts#L77
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storage-js/src/packages/hasura-storage-js/src/utils/types.ts#L92
---
# `UploadHeaders`

View File

@@ -67,11 +67,11 @@ Returns the name of the file.
---
**<span className="parameter-name">add</span>** <span className="optional-status">required</span> `(params: StorageUploadParams) => void`
**<span className="parameter-name">add</span>** <span className="optional-status">required</span> `(params: StorageUploadFileParams) => void`
---
**<span className="parameter-name">upload</span>** <span className="optional-status">required</span> `(params: Partial<StorageUploadParams>) => Promise<UploadFileHandlerResult>`
**<span className="parameter-name">upload</span>** <span className="optional-status">required</span> `(params: Partial<StorageUploadFileParams>) => Promise<UploadFileHandlerResult>`
---

View File

@@ -67,11 +67,11 @@ Returns the name of the file.
---
**<span className="parameter-name">add</span>** <span className="optional-status">required</span> `(params: StorageUploadParams) => void`
**<span className="parameter-name">add</span>** <span className="optional-status">required</span> `(params: StorageUploadFileParams) => void`
---
**<span className="parameter-name">upload</span>** <span className="optional-status">required</span> `(params: Partial<StorageUploadParams>) => Promise<UploadFileHandlerResult>`
**<span className="parameter-name">upload</span>** <span className="optional-status">required</span> `(params: Partial<StorageUploadFileParams>) => Promise<UploadFileHandlerResult>`
---

View File

@@ -24,7 +24,7 @@
"generate": "graphql-codegen --config graphql.config.yaml",
"cypress": "cypress open",
"test": "cypress run",
"e2e": "start-test e2e:backend :1337/v1/auth/healthz e2e:frontend 3000 test",
"e2e": "start-test e2e:backend http-get://localhost:9695 e2e:frontend 3000 test",
"e2e:backend": "nhost dev --no-browser",
"e2e:frontend": "run-s build preview",
"build": "vite build",

View File

@@ -1,5 +1,11 @@
# @nhost/apollo
## 0.5.27
### Patch Changes
- @nhost/nhost-js@1.4.10
## 0.5.26
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost/apollo",
"version": "0.5.26",
"version": "0.5.27",
"description": "Nhost Apollo Client library",
"license": "MIT",
"keywords": [

View File

@@ -0,0 +1,10 @@
{
"name": "functions",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {},
"keywords": [],
"author": "",
"license": "ISC"
}

View File

@@ -0,0 +1,11 @@
{
"compilerOptions": {
"allowJs": true,
"skipLibCheck": true,
"noEmit": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"isolatedModules": true,
"strictNullChecks": false
}
}

View File

@@ -46,7 +46,7 @@
"build": "run-p build:lib build:umd",
"build:lib": "vite build",
"build:umd": "vite build --config ../../config/vite.lib.umd.config.js",
"e2e": "start-test e2e:backend :1337/v1/auth/healthz ci:test",
"e2e": "start-test e2e:backend http-get://localhost:9695 ci:test",
"ci:test": "vitest run",
"e2e:backend": "nhost dev --no-browser",
"test:watch": "vitest",
@@ -74,4 +74,4 @@
"mailhog": "^4.16.0",
"start-server-and-test": "^1.14.0"
}
}
}

View File

@@ -1,5 +1,11 @@
# @nhost/hasura-storage-js
## 0.6.0
### Minor Changes
- 607c457f: nhost.storage.upload() now works in NodeJS (server) using FormData.
## 0.5.3
### Patch Changes

View File

@@ -9,7 +9,8 @@
</a>
</p>
Hasura JS SDK to handle **Storage** with [Hasura](https://hasura.io/).
Hasura JavaScript SDK to handle **Storage** with [Hasura](https://hasura.io/).
## Install
`$ npm install @nhost/hasura-storage-js`

View File

@@ -0,0 +1,10 @@
{
"name": "functions",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {},
"keywords": [],
"author": "",
"license": "ISC"
}

View File

@@ -0,0 +1,11 @@
{
"compilerOptions": {
"allowJs": true,
"skipLibCheck": true,
"noEmit": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"isolatedModules": true,
"strictNullChecks": false
}
}

View File

@@ -0,0 +1,134 @@
metadata_directory: metadata
services:
hasura:
image: hasura/graphql-engine:v2.10.1
environment:
hasura_graphql_enable_remote_schema_permissions: false
auth:
image: nhost/hasura-auth:0.10.0
storage:
image: nhost/hasura-storage:0.2.3
auth:
access_control:
email:
allowed_email_domains: ''
allowed_emails: ''
blocked_email_domains: ''
blocked_emails: ''
url:
allowed_redirect_urls: ''
anonymous_users_enabled: false
client_url: http://localhost:3000
disable_new_users: false
email:
enabled: false
passwordless:
enabled: false
signin_email_verified_required: true
template_fetch_url: ''
gravatar:
default: ''
enabled: true
rating: ''
locale:
allowed: en
default: en
password:
hibp_enabled: false
min_length: 3
provider:
apple:
client_id: ''
enabled: false
key_id: ''
private_key: ''
scope: name,email
team_id: ''
bitbucket:
client_id: ''
client_secret: ''
enabled: false
facebook:
client_id: ''
client_secret: ''
enabled: false
scope: email,photos,displayName
github:
client_id: ''
client_secret: ''
enabled: false
scope: user:email
token_url: ''
user_profile_url: ''
gitlab:
base_url: ''
client_id: ''
client_secret: ''
enabled: false
scope: read_user
google:
client_id: ''
client_secret: ''
enabled: false
scope: email,profile
linkedin:
client_id: ''
client_secret: ''
enabled: false
scope: r_emailaddress,r_liteprofile
spotify:
client_id: ''
client_secret: ''
enabled: false
scope: user-read-email,user-read-private
strava:
client_id: ''
client_secret: ''
enabled: false
twilio:
account_sid: ''
auth_token: ''
enabled: false
messaging_service_id: ''
twitter:
consumer_key: ''
consumer_secret: ''
enabled: false
windows_live:
client_id: ''
client_secret: ''
enabled: false
scope: wl.basic,wl.emails,wl.contacts_emails
sms:
enabled: false
passwordless:
enabled: false
provider:
twilio:
account_sid: ''
auth_token: ''
from: ''
messaging_service_id: ''
smtp:
host: mailhog
method: ''
pass: password
port: 1025
secure: false
sender: hasura-auth@example.com
user: user
token:
access:
expires_in: 900
refresh:
expires_in: 43200
user:
allowed_roles: user,me
default_allowed_roles: user,me
default_role: user
mfa:
enabled: false
issuer: nhost
storage:
force_download_for_content_types: text/html,application/javascript
version: 3

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h2>Confirm Email Change</h2>
<p>Use this link to confirm changing email:</p>
<p>
<a href="${link}">
Change email
</a>
</p>
</body>
</html>

View File

@@ -0,0 +1 @@
Change your email address

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h2>Verify Email</h2>
<p>Use this link to verify your email:</p>
<p>
<a href="${link}">
Verify Email
</a>
</p>
</body>
</html>

View File

@@ -0,0 +1 @@
Verify your email

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h2>Reset Password</h2>
<p>Use this link to reset your password:</p>
<p>
<a href="${link}">
Reset password
</a>
</p>
</body>
</html>

View File

@@ -0,0 +1 @@
Reset your password

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h2>Magic Link</h2>
<p>Use this link to securely sign in:</p>
<p>
<a href="${link}">
Sign In
</a>
</p>
</body>
</html>

View File

@@ -0,0 +1 @@
Secure sign-in link

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h2>Confirmer changement de courriel</h2>
<p>Utilisez ce lien pour confirmer le changement de courriel:</p>
<p>
<a href="${link}">
Changer courriel
</a>
</p>
</body>
</html>

View File

@@ -0,0 +1 @@
Changez votre adresse courriel

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h2>V&eacute;rifiez votre courriel</h2>
<p>Utilisez ce lien pour v&eacute;rifier votre courriel:</p>
<p>
<a href="${link}">
V&eacute;rifier courriel
</a>
</p>
</body>
</html>

View File

@@ -0,0 +1 @@
Vérifier votre courriel

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h2>R&eacute;initializer votre mot de passe</h2>
<p>Utilisez ce lien pour r&eacute;initializer votre mot de passe:</p>
<p>
<a href="${link}">
R&eacute;initializer mot de passe
</a>
</p>
</body>
</html>

View File

@@ -0,0 +1 @@
Réinitialiser votre mot de passe

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h2>Lien magique</h2>
<p>Utilisez ce lien pour vous connecter de fa&ccedil;on s&eacute;curitaire:</p>
<p>
<a href="${link}">
Connexion
</a>
</p>
</body>
</html>

View File

@@ -0,0 +1 @@
Lien de connexion sécurisé

View File

@@ -0,0 +1,6 @@
actions: []
custom_types:
enums: []
input_objects: []
objects: []
scalars: []

View File

@@ -0,0 +1 @@
[]

View File

@@ -0,0 +1 @@
{}

View File

@@ -0,0 +1 @@
[]

View File

@@ -0,0 +1,14 @@
- name: default
kind: postgres
configuration:
connection_info:
database_url:
from_env: HASURA_GRAPHQL_DATABASE_URL
isolation_level: read-committed
pool_settings:
connection_lifetime: 600
idle_timeout: 180
max_connections: 50
retries: 20
use_prepared_statements: true
tables: "!include default/tables/tables.yaml"

View File

@@ -0,0 +1,17 @@
table:
name: provider_requests
schema: auth
configuration:
column_config: {}
custom_column_names: {}
custom_name: authProviderRequests
custom_root_fields:
delete: deleteAuthProviderRequests
delete_by_pk: deleteAuthProviderRequest
insert: insertAuthProviderRequests
insert_one: insertAuthProviderRequest
select: authProviderRequests
select_aggregate: authProviderRequestsAggregate
select_by_pk: authProviderRequest
update: updateAuthProviderRequests
update_by_pk: updateAuthProviderRequest

View File

@@ -0,0 +1,25 @@
table:
name: providers
schema: auth
configuration:
column_config: {}
custom_column_names: {}
custom_name: authProviders
custom_root_fields:
delete: deleteAuthProviders
delete_by_pk: deleteAuthProvider
insert: insertAuthProviders
insert_one: insertAuthProvider
select: authProviders
select_aggregate: authProvidersAggregate
select_by_pk: authProvider
update: updateAuthProviders
update_by_pk: updateAuthProvider
array_relationships:
- name: userProviders
using:
foreign_key_constraint_on:
column: provider_id
table:
name: user_providers
schema: auth

View File

@@ -0,0 +1,33 @@
table:
name: refresh_tokens
schema: auth
configuration:
column_config:
created_at:
custom_name: createdAt
expires_at:
custom_name: expiresAt
refresh_token:
custom_name: refreshToken
user_id:
custom_name: userId
custom_column_names:
created_at: createdAt
expires_at: expiresAt
refresh_token: refreshToken
user_id: userId
custom_name: authRefreshTokens
custom_root_fields:
delete: deleteAuthRefreshTokens
delete_by_pk: deleteAuthRefreshToken
insert: insertAuthRefreshTokens
insert_one: insertAuthRefreshToken
select: authRefreshTokens
select_aggregate: authRefreshTokensAggregate
select_by_pk: authRefreshToken
update: updateAuthRefreshTokens
update_by_pk: updateAuthRefreshToken
object_relationships:
- name: user
using:
foreign_key_constraint_on: user_id

View File

@@ -0,0 +1,32 @@
table:
name: roles
schema: auth
configuration:
column_config: {}
custom_column_names: {}
custom_name: authRoles
custom_root_fields:
delete: deleteAuthRoles
delete_by_pk: deleteAuthRole
insert: insertAuthRoles
insert_one: insertAuthRole
select: authRoles
select_aggregate: authRolesAggregate
select_by_pk: authRole
update: updateAuthRoles
update_by_pk: updateAuthRole
array_relationships:
- name: userRoles
using:
foreign_key_constraint_on:
column: role
table:
name: user_roles
schema: auth
- name: usersByDefaultRole
using:
foreign_key_constraint_on:
column: default_role
table:
name: users
schema: auth

View File

@@ -0,0 +1,30 @@
table:
name: user_authenticators
schema: auth
configuration:
column_config:
credential_id:
custom_name: credentialId
credential_public_key:
custom_name: credentialPublicKey
user_id:
custom_name: userId
custom_column_names:
credential_id: credentialId
credential_public_key: credentialPublicKey
user_id: userId
custom_name: authUserAuthenticators
custom_root_fields:
delete: deleteAuthUserAuthenticators
delete_by_pk: deleteAuthUserAuthenticator
insert: insertAuthUserAuthenticators
insert_one: insertAuthUserAuthenticator
select: authUserAuthenticators
select_aggregate: authUserAuthenticatorsAggregate
select_by_pk: authUserAuthenticator
update: updateAuthUserAuthenticators
update_by_pk: updateAuthUserAuthenticator
object_relationships:
- name: user
using:
foreign_key_constraint_on: user_id

View File

@@ -0,0 +1,45 @@
table:
name: user_providers
schema: auth
configuration:
column_config:
access_token:
custom_name: accessToken
created_at:
custom_name: createdAt
provider_id:
custom_name: providerId
provider_user_id:
custom_name: providerUserId
refresh_token:
custom_name: refreshToken
updated_at:
custom_name: updatedAt
user_id:
custom_name: userId
custom_column_names:
access_token: accessToken
created_at: createdAt
provider_id: providerId
provider_user_id: providerUserId
refresh_token: refreshToken
updated_at: updatedAt
user_id: userId
custom_name: authUserProviders
custom_root_fields:
delete: deleteAuthUserProviders
delete_by_pk: deleteAuthUserProvider
insert: insertAuthUserProviders
insert_one: insertAuthUserProvider
select: authUserProviders
select_aggregate: authUserProvidersAggregate
select_by_pk: authUserProvider
update: updateAuthUserProviders
update_by_pk: updateAuthUserProvider
object_relationships:
- name: provider
using:
foreign_key_constraint_on: provider_id
- name: user
using:
foreign_key_constraint_on: user_id

View File

@@ -0,0 +1,30 @@
table:
name: user_roles
schema: auth
configuration:
column_config:
created_at:
custom_name: createdAt
user_id:
custom_name: userId
custom_column_names:
created_at: createdAt
user_id: userId
custom_name: authUserRoles
custom_root_fields:
delete: deleteAuthUserRoles
delete_by_pk: deleteAuthUserRole
insert: insertAuthUserRoles
insert_one: insertAuthUserRole
select: authUserRoles
select_aggregate: authUserRolesAggregate
select_by_pk: authUserRole
update: updateAuthUserRoles
update_by_pk: updateAuthUserRole
object_relationships:
- name: roleByRole
using:
foreign_key_constraint_on: role
- name: user
using:
foreign_key_constraint_on: user_id

View File

@@ -0,0 +1,107 @@
table:
name: users
schema: auth
configuration:
column_config:
active_mfa_type:
custom_name: activeMfaType
avatar_url:
custom_name: avatarUrl
created_at:
custom_name: createdAt
default_role:
custom_name: defaultRole
display_name:
custom_name: displayName
email_verified:
custom_name: emailVerified
is_anonymous:
custom_name: isAnonymous
last_seen:
custom_name: lastSeen
new_email:
custom_name: newEmail
otp_hash:
custom_name: otpHash
otp_hash_expires_at:
custom_name: otpHashExpiresAt
otp_method_last_used:
custom_name: otpMethodLastUsed
password_hash:
custom_name: passwordHash
phone_number:
custom_name: phoneNumber
phone_number_verified:
custom_name: phoneNumberVerified
ticket_expires_at:
custom_name: ticketExpiresAt
totp_secret:
custom_name: totpSecret
updated_at:
custom_name: updatedAt
webauthn_current_challenge:
custom_name: currentChallenge
custom_column_names:
active_mfa_type: activeMfaType
avatar_url: avatarUrl
created_at: createdAt
default_role: defaultRole
display_name: displayName
email_verified: emailVerified
is_anonymous: isAnonymous
last_seen: lastSeen
new_email: newEmail
otp_hash: otpHash
otp_hash_expires_at: otpHashExpiresAt
otp_method_last_used: otpMethodLastUsed
password_hash: passwordHash
phone_number: phoneNumber
phone_number_verified: phoneNumberVerified
ticket_expires_at: ticketExpiresAt
totp_secret: totpSecret
updated_at: updatedAt
webauthn_current_challenge: currentChallenge
custom_name: users
custom_root_fields:
delete: deleteUsers
delete_by_pk: deleteUser
insert: insertUsers
insert_one: insertUser
select: users
select_aggregate: usersAggregate
select_by_pk: user
update: updateUsers
update_by_pk: updateUser
object_relationships:
- name: defaultRoleByRole
using:
foreign_key_constraint_on: default_role
array_relationships:
- name: authenticators
using:
foreign_key_constraint_on:
column: user_id
table:
name: user_authenticators
schema: auth
- name: refreshTokens
using:
foreign_key_constraint_on:
column: user_id
table:
name: refresh_tokens
schema: auth
- name: roles
using:
foreign_key_constraint_on:
column: user_id
table:
name: user_roles
schema: auth
- name: userProviders
using:
foreign_key_constraint_on:
column: user_id
table:
name: user_providers
schema: auth

View File

@@ -0,0 +1,49 @@
table:
name: buckets
schema: storage
configuration:
column_config:
cache_control:
custom_name: cacheControl
created_at:
custom_name: createdAt
download_expiration:
custom_name: downloadExpiration
id:
custom_name: id
max_upload_file_size:
custom_name: maxUploadFileSize
min_upload_file_size:
custom_name: minUploadFileSize
presigned_urls_enabled:
custom_name: presignedUrlsEnabled
updated_at:
custom_name: updatedAt
custom_column_names:
cache_control: cacheControl
created_at: createdAt
download_expiration: downloadExpiration
id: id
max_upload_file_size: maxUploadFileSize
min_upload_file_size: minUploadFileSize
presigned_urls_enabled: presignedUrlsEnabled
updated_at: updatedAt
custom_name: buckets
custom_root_fields:
delete: deleteBuckets
delete_by_pk: deleteBucket
insert: insertBuckets
insert_one: insertBucket
select: buckets
select_aggregate: bucketsAggregate
select_by_pk: bucket
update: updateBuckets
update_by_pk: updateBucket
array_relationships:
- name: files
using:
foreign_key_constraint_on:
column: bucket_id
table:
name: files
schema: storage

View File

@@ -0,0 +1,86 @@
table:
name: files
schema: storage
configuration:
column_config:
bucket_id:
custom_name: bucketId
created_at:
custom_name: createdAt
etag:
custom_name: etag
id:
custom_name: id
is_uploaded:
custom_name: isUploaded
mime_type:
custom_name: mimeType
name:
custom_name: name
size:
custom_name: size
updated_at:
custom_name: updatedAt
uploaded_by_user_id:
custom_name: uploadedByUserId
custom_column_names:
bucket_id: bucketId
created_at: createdAt
etag: etag
id: id
is_uploaded: isUploaded
mime_type: mimeType
name: name
size: size
updated_at: updatedAt
uploaded_by_user_id: uploadedByUserId
custom_name: files
custom_root_fields:
delete: deleteFiles
delete_by_pk: deleteFile
insert: insertFiles
insert_one: insertFile
select: files
select_aggregate: filesAggregate
select_by_pk: file
update: updateFiles
update_by_pk: updateFile
object_relationships:
- name: bucket
using:
foreign_key_constraint_on: bucket_id
insert_permissions:
- role: public
permission:
check: {}
columns:
- is_uploaded
- size
- bucket_id
- etag
- mime_type
- name
- created_at
- updated_at
- id
- uploaded_by_user_id
select_permissions:
- role: public
permission:
columns:
- is_uploaded
- size
- bucket_id
- etag
- mime_type
- name
- created_at
- updated_at
- id
- uploaded_by_user_id
filter: {}
delete_permissions:
- role: public
permission:
backend_only: false
filter: {}

View File

@@ -0,0 +1,10 @@
- "!include auth_provider_requests.yaml"
- "!include auth_providers.yaml"
- "!include auth_refresh_tokens.yaml"
- "!include auth_roles.yaml"
- "!include auth_user_authenticators.yaml"
- "!include auth_user_providers.yaml"
- "!include auth_user_roles.yaml"
- "!include auth_users.yaml"
- "!include storage_buckets.yaml"
- "!include storage_files.yaml"

View File

@@ -0,0 +1 @@
disabled_for_roles: []

View File

@@ -0,0 +1 @@
[]

View File

@@ -0,0 +1 @@
{}

View File

@@ -0,0 +1 @@
[]

View File

@@ -0,0 +1 @@
[]

View File

@@ -0,0 +1 @@
[]

View File

@@ -0,0 +1 @@
version: 3

View File

@@ -0,0 +1 @@
DELETE FROM "storage"."buckets" WHERE "id" = 'test-bucket';

View File

@@ -0,0 +1 @@
INSERT INTO "storage"."buckets"("id", "created_at", "updated_at", "download_expiration", "min_upload_file_size", "max_upload_file_size", "cache_control", "presigned_urls_enabled") VALUES (E'test-bucket', E'2022-08-23T11:09:30.19894+00:00', E'2022-08-23T11:09:30.19894+00:00', 30, 1, 50000000, E'max-age=3600', true);

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost/hasura-storage-js",
"version": "0.5.3",
"version": "0.6.0",
"description": "Hasura-storage client",
"license": "MIT",
"keywords": [
@@ -42,11 +42,13 @@
"scripts": {
"dev": "vite build --config ../../config/vite.lib.dev.config.js",
"build": "run-p build:lib build:umd",
"build:lib": "vite build --config ../../config/vite.lib.config.js",
"build:lib": "vite build",
"build:umd": "vite build --config ../../config/vite.lib.umd.config.js",
"test": "vitest run --config ../../config/vite.lib.config.js",
"test:watch": "vitest --config ../../config/vite.lib.config.js",
"test:coverage": "vitest run --coverage --config ../../config/vite.lib.config.js",
"e2e": "start-test e2e:backend http-get://localhost:9695 ci:test",
"ci:test": "vitest run",
"e2e:backend": "nhost dev --no-browser",
"test:watch": "vitest",
"test:coverage": "vitest run --coverage",
"prettier": "prettier --check src/",
"prettier:fix": "prettier --write src/",
"lint": "eslint . --ext .ts,.tsx",
@@ -58,6 +60,7 @@
},
"dependencies": {
"axios": "^0.27.2",
"form-data": "^4.0.0",
"xstate": "^4.32.1"
},
"peerDependencies": {
@@ -66,6 +69,9 @@
"devDependencies": {
"@nhost/core": "workspace:*",
"@nhost/docgen": "workspace:*",
"msw": "^0.39.2"
"cross-fetch": "^3.1.5",
"msw": "^0.39.2",
"start-server-and-test": "^1.14.0",
"uuid": "^8.3.2"
}
}
}

View File

@@ -30,8 +30,10 @@ export class HasuraStorageApi {
}
async upload(params: ApiUploadParams): Promise<ApiUploadResponse> {
const { formData } = params
try {
const res = await this.httpClient.post('/files', params.file, {
const res = await this.httpClient.post('/files', formData, {
headers: {
...this.generateUploadHeaders(params),
...this.generateAuthHeaders(),

View File

@@ -1,9 +1,13 @@
import FormData from 'form-data'
import {
StorageDeleteParams,
StorageDeleteResponse,
StorageGetPresignedUrlParams,
StorageGetPresignedUrlResponse,
StorageGetUrlParams,
StorageUploadFileParams,
StorageUploadFormDataParams,
StorageUploadParams,
StorageUploadResponse
} from './utils/types'
@@ -33,29 +37,57 @@ export class HasuraStorageClient {
}
/**
* Use `nhost.storage.upload` to upload a file. The `file` must be of type [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File).
* Use `nhost.storage.upload` to upload a file.
*
* If no `bucket` is specified the `default` bucket will be used.
* It's possible to use [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) or [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) to upload a file. The `File` instance is only available in the browser while `FormData` with [`form-data`](https://www.npmjs.com/package/form-data) works both in the browser and in NodeJS (server).
*
* If no `bucketId` is specified the bucket `default` is used.
*
* @example
*
* Upload a file from a browser using `File`.
*
* ```ts
* await nhost.storage.upload({ file })
* ```
*
* Upload a file from a browser using `File` to a specific Bucket.
*
@example
* ```ts
* await nhost.storage.upload({ file, bucketId: '<Bucket-ID>' })
* ```
*
* Upload a file from a server using `FormData` with [`form-data`](https://www.npmjs.com/package/form-data).
*
* @example
* ```ts
* const fd = new FormData()
* fd.append('file', fs.createReadStream('./tests/assets/sample.pdf'))
*
* await storage.upload({
* formData: fd
* })
* ```
*
* @docs https://docs.nhost.io/reference/javascript/storage/upload
*/
async upload(params: StorageUploadFileParams): Promise<StorageUploadResponse>
async upload(params: StorageUploadFormDataParams): Promise<StorageUploadResponse>
async upload(params: StorageUploadParams): Promise<StorageUploadResponse> {
const file = new FormData()
file.append('file', params.file)
let formData: FormData
if ('file' in params) {
formData = new FormData()
formData.append('file', params.file)
} else {
formData = params.formData
}
const { fileMetadata, error } = await this.api.upload({
...params,
file
formData: formData
})
if (error) {
return { fileMetadata: null, error }

View File

@@ -3,7 +3,7 @@ import { InterpreterFrom } from 'xstate'
import { ActionErrorState } from '@nhost/core'
import { FileItemRef, FileUploadMachine } from '../machines'
import { NhostClientReturnType, StorageUploadParams } from '../utils/types'
import { NhostClientReturnType, StorageUploadFileParams } from '../utils/types'
export interface UploadProgressState {
/**
@@ -40,7 +40,7 @@ export interface FileUploadState extends UploadFileHandlerResult, UploadProgress
export const uploadFilePromise = async (
nhost: NhostClientReturnType,
interpreter: FileItemRef | InterpreterFrom<FileUploadMachine>,
params: Partial<StorageUploadParams>
params: Partial<StorageUploadFileParams>
): Promise<UploadFileHandlerResult> =>
new Promise<UploadFileHandlerResult>((resolve) => {
interpreter.send({

View File

@@ -1,3 +1,5 @@
import FormData from 'form-data'
import { HasuraAuthClient } from '@nhost/hasura-auth-js'
// * Avoid circular references and broken links in docusaurus generated docs
@@ -6,13 +8,26 @@ export interface NhostClientReturnType {
storage: { url: string }
adminSecret?: string
}
export interface StorageUploadParams {
// works only in browser. Used for for hooks
export interface StorageUploadFileParams {
file: File
id?: string
name?: string
bucketId?: string
}
// works in browser and server
export interface StorageUploadFormDataParams {
formData: FormData
id?: string
name?: string
bucketId?: string
}
// works in browser and server
export type StorageUploadParams = StorageUploadFileParams | StorageUploadFormDataParams
export type StorageUploadResponse =
| { fileMetadata: FileResponse; error: null }
| { fileMetadata: null; error: Error }
@@ -48,7 +63,7 @@ interface FileResponse {
}
export interface ApiUploadParams {
file: FormData
formData: FormData
id?: string
name?: string
bucketId?: string

View File

@@ -0,0 +1,15 @@
import { describe, it } from 'vitest'
import { storage } from './utils/helpers'
describe('test access token', () => {
it('should be able to set access token', async () => {
const ACCESS_TOKEN = 'my-access-token'
storage.setAccessToken(ACCESS_TOKEN)
})
it('should be able to set admin secret', async () => {
const ADMIN_SECRET = 'my-admin-secret'
storage.setAccessToken(ADMIN_SECRET)
})
})

View File

@@ -0,0 +1,198 @@
%PDF-1.3
%âãÏÓ
1 0 obj
<<
/Type /Catalog
/Outlines 2 0 R
/Pages 3 0 R
>>
endobj
2 0 obj
<<
/Type /Outlines
/Count 0
>>
endobj
3 0 obj
<<
/Type /Pages
/Count 2
/Kids [ 4 0 R 6 0 R ]
>>
endobj
4 0 obj
<<
/Type /Page
/Parent 3 0 R
/Resources <<
/Font <<
/F1 9 0 R
>>
/ProcSet 8 0 R
>>
/MediaBox [0 0 612.0000 792.0000]
/Contents 5 0 R
>>
endobj
5 0 obj
<< /Length 1074 >>
stream
2 J
BT
0 0 0 rg
/F1 0027 Tf
57.3750 722.2800 Td
( A Simple PDF File ) Tj
ET
BT
/F1 0010 Tf
69.2500 688.6080 Td
( This is a small demonstration .pdf file - ) Tj
ET
BT
/F1 0010 Tf
69.2500 664.7040 Td
( just for use in the Virtual Mechanics tutorials. More text. And more ) Tj
ET
BT
/F1 0010 Tf
69.2500 652.7520 Td
( text. And more text. And more text. And more text. ) Tj
ET
BT
/F1 0010 Tf
69.2500 628.8480 Td
( And more text. And more text. And more text. And more text. And more ) Tj
ET
BT
/F1 0010 Tf
69.2500 616.8960 Td
( text. And more text. Boring, zzzzz. And more text. And more text. And ) Tj
ET
BT
/F1 0010 Tf
69.2500 604.9440 Td
( more text. And more text. And more text. And more text. And more text. ) Tj
ET
BT
/F1 0010 Tf
69.2500 592.9920 Td
( And more text. And more text. ) Tj
ET
BT
/F1 0010 Tf
69.2500 569.0880 Td
( And more text. And more text. And more text. And more text. And more ) Tj
ET
BT
/F1 0010 Tf
69.2500 557.1360 Td
( text. And more text. And more text. Even more. Continued on page 2 ...) Tj
ET
endstream
endobj
6 0 obj
<<
/Type /Page
/Parent 3 0 R
/Resources <<
/Font <<
/F1 9 0 R
>>
/ProcSet 8 0 R
>>
/MediaBox [0 0 612.0000 792.0000]
/Contents 7 0 R
>>
endobj
7 0 obj
<< /Length 676 >>
stream
2 J
BT
0 0 0 rg
/F1 0027 Tf
57.3750 722.2800 Td
( Simple PDF File 2 ) Tj
ET
BT
/F1 0010 Tf
69.2500 688.6080 Td
( ...continued from page 1. Yet more text. And more text. And more text. ) Tj
ET
BT
/F1 0010 Tf
69.2500 676.6560 Td
( And more text. And more text. And more text. And more text. And more ) Tj
ET
BT
/F1 0010 Tf
69.2500 664.7040 Td
( text. Oh, how boring typing this stuff. But not as boring as watching ) Tj
ET
BT
/F1 0010 Tf
69.2500 652.7520 Td
( paint dry. And more text. And more text. And more text. And more text. ) Tj
ET
BT
/F1 0010 Tf
69.2500 640.8000 Td
( Boring. More, a little more text. The end, and just as well. ) Tj
ET
endstream
endobj
8 0 obj
[/PDF /Text]
endobj
9 0 obj
<<
/Type /Font
/Subtype /Type1
/Name /F1
/BaseFont /Helvetica
/Encoding /WinAnsiEncoding
>>
endobj
10 0 obj
<<
/Creator (Rave \(http://www.nevrona.com/rave\))
/Producer (Nevrona Designs)
/CreationDate (D:20060301072826)
>>
endobj
xref
0 11
0000000000 65535 f
0000000019 00000 n
0000000093 00000 n
0000000147 00000 n
0000000222 00000 n
0000000390 00000 n
0000001522 00000 n
0000001690 00000 n
0000002423 00000 n
0000002456 00000 n
0000002574 00000 n
trailer
<<
/Size 11
/Root 1 0 R
/Info 10 0 R
>>
startxref
2714
%%EOF

View File

@@ -0,0 +1,33 @@
import fs from 'fs'
import { describe, expect, it } from 'vitest'
import { v4 as uuidv4 } from 'uuid'
import { storage } from './utils/helpers'
import FormData from 'form-data'
describe('test delete file', () => {
it('should be able to get delete file', async () => {
const fd = new FormData()
fd.append('file', fs.createReadStream('./tests/assets/sample.pdf'))
const { fileMetadata } = await storage.upload({
formData: fd
})
const { error } = await storage.delete({
fileId: fileMetadata?.id as string
})
expect(error).toBeNull()
})
it('should fail to delete a file does not exist', async () => {
const RANDOM_UUID = uuidv4()
const { error } = await storage.delete({
fileId: RANDOM_UUID
})
expect(error).toBeTruthy()
})
})

View File

@@ -0,0 +1,31 @@
import fs from 'fs'
import { describe, expect, it } from 'vitest'
import { v4 as uuidv4 } from 'uuid'
import { storage } from './utils/helpers'
import FormData from 'form-data'
describe('test get presigned url of file', () => {
it('should be able to get presigned url of file', async () => {
const fd = new FormData()
fd.append('file', fs.createReadStream('./tests/assets/sample.pdf'))
const { fileMetadata } = await storage.upload({
formData: fd
})
const { error } = await storage.getPresignedUrl({
fileId: fileMetadata?.id as string
})
expect(error).toBeNull()
})
it('should fail to get presigned url of file that does not exist', async () => {
const { error } = await storage.getPresignedUrl({
fileId: uuidv4()
})
expect(error).toBeTruthy()
})
})

View File

@@ -0,0 +1,43 @@
import fs from 'fs'
import { describe, expect, it } from 'vitest'
import fetch from 'cross-fetch'
import { v4 as uuidv4 } from 'uuid'
import { storage } from './utils/helpers'
import FormData from 'form-data'
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 { fileMetadata, error } = await storage.upload({
formData: fd
})
expect(error).toBeNull()
const url = storage.getPublicUrl({
fileId: fileMetadata?.id as string
})
expect(url).toBeTruthy()
const { status } = await fetch(url)
expect(status).toBe(200)
})
it('should fail to get file id that does not exist', async () => {
const RANDOM_UUID = uuidv4()
const url = storage.getPublicUrl({
fileId: RANDOM_UUID
})
expect(url).toBeTruthy()
const { status } = await fetch(url)
expect(status).toBe(404)
})
})

View File

@@ -1,4 +0,0 @@
/**
* Base Nhost backend url for the Nhost client.
*/
export const BASE_URL = 'http://localhost:1337'

View File

@@ -1,20 +0,0 @@
import faker from '@faker-js/faker'
import { NhostSession } from '@nhost/core'
import { rest } from 'msw'
import { BASE_URL } from '../config'
import fakeUser from '../mocks/user'
/**
* Request handler for MSW to mock a successful request for a new access token.
*/
export const authTokenSuccessHandler = rest.post(`${BASE_URL}/v1/auth/token`, (_req, res, ctx) =>
res(
ctx.json<NhostSession>({
accessToken: faker.datatype.string(40),
refreshToken: faker.datatype.uuid(),
accessTokenExpiresIn: 900,
user: fakeUser
})
)
)

View File

@@ -1,2 +0,0 @@
export * from './uploadFileHandlers'
export * from './authHandlers'

View File

@@ -1,23 +0,0 @@
import { rest } from 'msw'
import { BASE_URL } from '../config'
/**
* Request handler for MSW to mock an internal server error when uploading a file.
*/
export const uploadFileInternalErrorHandler = rest.post(
`${BASE_URL}/v1/storage/files`,
(_req, res, ctx) => {
return res(
ctx.status(500),
ctx.json({ status: 500, error: 'internal-error', message: 'Internal error' })
)
}
)
/**
* Request handler for MSW to mock a network error when uploading a file
*/
export const uploadFiledNetworkErrorHandler = rest.post(
`${BASE_URL}/v1/storage/files`,
(_req, res) => res.networkError('Network error')
)

View File

@@ -1,23 +0,0 @@
import faker from '@faker-js/faker'
import { User } from '@nhost/core'
/**
* A fake user object.
*/
export const fakeUser: User = {
id: faker.datatype.uuid(),
createdAt: faker.date.past().toUTCString(),
displayName: `${faker.name.firstName()} ${faker.name.lastName()}`,
avatarUrl: faker.internet.avatar(),
locale: 'en',
isAnonymous: false,
emailVerified: true,
defaultRole: 'user',
roles: ['user', 'me'],
phoneNumber: null,
phoneNumberVerified: false,
activeMfaType: null,
metadata: {}
}
export default fakeUser

View File

@@ -1,8 +0,0 @@
import { setupServer } from 'msw/node'
import { authTokenSuccessHandler } from './handlers'
export const defaultSuccessHandlers = [authTokenSuccessHandler]
export const server = setupServer(...defaultSuccessHandlers)
export default server

View File

@@ -1,14 +0,0 @@
import { ClientStorage, NHOST_REFRESH_TOKEN_KEY, NHOST_JWT_EXPIRES_AT_KEY } from '@nhost/core'
/**
* Custom emory storage implementation that always return a mock refresh token
*/
export const clientStorage: ClientStorage = {
getItem: (key: string) =>
({
[NHOST_REFRESH_TOKEN_KEY]: 'mockRefreshTokenValue',
[NHOST_JWT_EXPIRES_AT_KEY]: Date.now().toString()
}[key]),
setItem: () => {},
removeItem: () => {}
}

View File

@@ -1,30 +0,0 @@
import {
BaseActionObject,
EventObject,
ResolveTypegenMeta,
ServiceMap,
State,
TypegenConstraint
} from 'xstate'
import { FileUploadContext, FileUploadEvents } from '../../src/machines'
export type GeneralState<
Context,
Events extends EventObject,
Typegen extends TypegenConstraint
> = State<
Context,
Events,
any,
{
value: any
context: Context
},
ResolveTypegenMeta<Typegen, Events, BaseActionObject, ServiceMap>
>
export type GeneralFileUploadState<Typegen extends TypegenConstraint> = GeneralState<
FileUploadContext,
FileUploadEvents,
Typegen
>

View File

@@ -0,0 +1,110 @@
import fs from 'fs'
import { describe, expect, it } from 'vitest'
import fetch from 'cross-fetch'
import { v4 as uuidv4 } from 'uuid'
import FormData from 'form-data'
import { storage } from './utils/helpers'
describe('test upload', () => {
it('should upload a file from the file system', async () => {
const fd = new FormData()
fd.append('file', fs.createReadStream('./tests/assets/sample.pdf'))
const { error } = await storage.upload({
formData: fd
})
expect(error).toBeNull()
})
it('should upload a file using blob from fetch', async () => {
const logo = await fetch('http://nodejs.org/images/logo.png')
let blob = await logo.blob()
// create form data
const fd = new FormData()
fd.append('file', blob.stream(), 'logo.png')
const { error } = await storage.upload({
formData: fd
})
expect(error).toBeNull()
})
it('should upload a file with specific id', async () => {
const RANDOM_UUID = uuidv4()
const fd = new FormData()
fd.append('file', fs.createReadStream('./tests/assets/sample.pdf'))
const { fileMetadata, error } = await storage.upload({
formData: fd,
id: RANDOM_UUID
})
expect(error).toBeNull()
expect(fileMetadata?.id).toBe(RANDOM_UUID)
})
it('should upload a file with specific name', async () => {
const FILE_NAME = 'special-name.pdf'
const fd = new FormData()
fd.append('file', fs.createReadStream('./tests/assets/sample.pdf'))
const { fileMetadata, error } = await storage.upload({
formData: fd,
name: FILE_NAME
})
expect(error).toBeNull()
expect(fileMetadata?.name).toBe(FILE_NAME)
})
it('should upload a file with specific id and name', async () => {
const RANDOM_UUID = uuidv4()
const FILE_NAME = 'special-name.pdf'
const fd = new FormData()
fd.append('file', fs.createReadStream('./tests/assets/sample.pdf'))
const { fileMetadata, error } = await storage.upload({
formData: fd,
id: RANDOM_UUID,
name: FILE_NAME
})
expect(error).toBeNull()
expect(fileMetadata?.id).toBe(RANDOM_UUID)
expect(fileMetadata?.name).toBe(FILE_NAME)
})
it('should upload a file with specific bucket id', async () => {
const fd = new FormData()
fd.append('file', fs.createReadStream('./tests/assets/sample.pdf'))
const { fileMetadata, error } = await storage.upload({
formData: fd,
bucketId: 'default'
})
expect(error).toBeNull()
expect(fileMetadata?.bucketId).toBe('default')
})
it('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 { fileMetadata, error } = await storage.upload({
formData: fd,
bucketId: 'test-bucket'
})
expect(error).toBeNull()
expect(fileMetadata?.bucketId).toBe('test-bucket')
})
})

Some files were not shown because too many files have changed in this diff Show More