Compare commits
29 Commits
@nhost/goo
...
@nhost/apo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b0363a4f4c | ||
|
|
17045b2018 | ||
|
|
c49cc11862 | ||
|
|
c83fe7d776 | ||
|
|
235b4c7405 | ||
|
|
c2c0fbd33a | ||
|
|
300e3f49e0 | ||
|
|
a95a77886b | ||
|
|
1f3f683202 | ||
|
|
4c67fd23c4 | ||
|
|
93d8d71e34 | ||
|
|
47bda15ff2 | ||
|
|
4563488b5d | ||
|
|
8fd35f3fea | ||
|
|
9c61c69a7b | ||
|
|
030ad4621e | ||
|
|
ee0b9b8edc | ||
|
|
c6fa8da6df | ||
|
|
dd9dedc226 | ||
|
|
5638a91240 | ||
|
|
cdefbdebee | ||
|
|
923abd3655 | ||
|
|
ef28540f9a | ||
|
|
d54e4cdd4e | ||
|
|
4a00963602 | ||
|
|
7ea9b890c8 | ||
|
|
f866120a65 | ||
|
|
472559276c | ||
|
|
2cdb13b3ef |
@@ -34,7 +34,7 @@ Nhost consists of open source software:
|
||||
- Authentication: [Hasura Auth](https://github.com/nhost/hasura-auth/)
|
||||
- Storage: [Hasura Storage](https://github.com/nhost/hasura-storage)
|
||||
- Serverless Functions: Node.js (JavaScript and TypeScript)
|
||||
- [Nhost CLI](https://docs.nhost.io/reference/cli) for local development
|
||||
- [Nhost CLI](https://docs.nhost.io/cli) for local development
|
||||
|
||||
## Architecture of Nhost
|
||||
|
||||
@@ -97,7 +97,7 @@ Nhost is frontend agnostic, which means Nhost works with all frontend frameworks
|
||||
|
||||
# Resources
|
||||
|
||||
- Start developing locally with the [Nhost CLI](https://docs.nhost.io/reference/cli)
|
||||
- Start developing locally with the [Nhost CLI](https://docs.nhost.io/cli)
|
||||
|
||||
## Nhost Clients
|
||||
|
||||
|
||||
@@ -1,5 +1,48 @@
|
||||
# @nhost/dashboard
|
||||
|
||||
## 0.19.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react-apollo@5.0.32
|
||||
- @nhost/nextjs@1.13.34
|
||||
|
||||
## 0.19.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 9c61c69a7: chore(dashboard):add postgres 14.6-20230705-1 to the version selector
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 47bda15ff: feat(settings): add warning to pull config
|
||||
|
||||
## 0.18.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- ee0b9b8ed: chore(dashboard):add hasura v2.28.2 and v2.29.0 to the version selector
|
||||
|
||||
## 0.17.20
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react-apollo@5.0.31
|
||||
- @nhost/nextjs@1.13.33
|
||||
|
||||
## 0.17.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- f866120a6: fix(users): use the password length from the config
|
||||
|
||||
## 0.17.18
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react-apollo@5.0.30
|
||||
- @nhost/nextjs@1.13.32
|
||||
|
||||
## 0.17.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/dashboard",
|
||||
"version": "0.17.17",
|
||||
"version": "0.19.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
@@ -101,6 +101,7 @@
|
||||
"@testing-library/jest-dom": "^5.16.5",
|
||||
"@testing-library/react": "^14.0.0",
|
||||
"@testing-library/user-event": "^14.4.3",
|
||||
"@types/bcryptjs": "^2.4.2",
|
||||
"@types/lodash.debounce": "^4.0.7",
|
||||
"@types/node": "^16.11.7",
|
||||
"@types/pluralize": "^0.0.29",
|
||||
|
||||
@@ -3,7 +3,10 @@ import { ProjectLayout } from '@/components/layout/ProjectLayout';
|
||||
import type { SettingsSidebarProps } from '@/components/layout/SettingsSidebar';
|
||||
import { SettingsSidebar } from '@/components/layout/SettingsSidebar';
|
||||
import { RetryableErrorBoundary } from '@/components/presentational/RetryableErrorBoundary';
|
||||
import { Alert } from '@/components/ui/v2/Alert';
|
||||
import { Box } from '@/components/ui/v2/Box';
|
||||
import { Text } from '@/components/ui/v2/Text';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
export interface SettingsLayoutProps extends ProjectLayoutProps {
|
||||
@@ -22,6 +25,9 @@ export default function SettingsLayout({
|
||||
sidebarProps: { className: sidebarClassName, ...sidebarProps } = {},
|
||||
...props
|
||||
}: SettingsLayoutProps) {
|
||||
const { currentProject } = useCurrentWorkspaceAndProject();
|
||||
const hasGitRepo = !!currentProject?.githubRepository;
|
||||
|
||||
return (
|
||||
<ProjectLayout
|
||||
mainContainerProps={{
|
||||
@@ -37,9 +43,39 @@ export default function SettingsLayout({
|
||||
|
||||
<Box
|
||||
sx={{ backgroundColor: 'background.default' }}
|
||||
className="flex w-full flex-auto flex-col overflow-x-hidden"
|
||||
className="flex w-full flex-auto flex-col overflow-scroll overflow-x-hidden"
|
||||
>
|
||||
<RetryableErrorBoundary>{children}</RetryableErrorBoundary>
|
||||
<RetryableErrorBoundary>
|
||||
{hasGitRepo && (
|
||||
<Alert
|
||||
severity="warning"
|
||||
className="grid grid-flow-row place-content-center gap-2"
|
||||
>
|
||||
<Text color="warning" className="text-sm ">
|
||||
As you have a connected repository, make sure to synchronize
|
||||
your changes with{' '}
|
||||
<code className="rounded-md bg-slate-200 px-2 py-px text-slate-500">
|
||||
nhost config pull
|
||||
</code>{' '}
|
||||
or they may be reverted with the next push.
|
||||
<br />
|
||||
If there are multiple projects linked to the same repository and
|
||||
you only want these changes to apply to a subset of them, please
|
||||
check out{' '}
|
||||
<a
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="underline"
|
||||
href="https://docs.nhost.io/cli/overlays"
|
||||
>
|
||||
docs.nhost.io/cli/overlays
|
||||
</a>{' '}
|
||||
for guidance.
|
||||
</Text>
|
||||
</Alert>
|
||||
)}
|
||||
{children}
|
||||
</RetryableErrorBoundary>
|
||||
</Box>
|
||||
</ProjectLayout>
|
||||
);
|
||||
|
||||
@@ -3,12 +3,16 @@ import { Form } from '@/components/form/Form';
|
||||
import { Alert } from '@/components/ui/v2/Alert';
|
||||
import { Button } from '@/components/ui/v2/Button';
|
||||
import { Input } from '@/components/ui/v2/Input';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
|
||||
import { useRemoteApplicationGQLClient } from '@/hooks/useRemoteApplicationGQLClient';
|
||||
import type { DialogFormProps } from '@/types/common';
|
||||
import { getToastStyleProps } from '@/utils/constants/settings';
|
||||
import { getServerError } from '@/utils/getServerError';
|
||||
import type { RemoteAppGetUsersQuery } from '@/utils/__generated__/graphql';
|
||||
import { useUpdateRemoteAppUserMutation } from '@/utils/__generated__/graphql';
|
||||
import {
|
||||
useGetSignInMethodsQuery,
|
||||
useUpdateRemoteAppUserMutation,
|
||||
} from '@/utils/__generated__/graphql';
|
||||
import { yupResolver } from '@hookform/resolvers/yup';
|
||||
import bcrypt from 'bcryptjs';
|
||||
import { useState } from 'react';
|
||||
@@ -27,19 +31,6 @@ export interface EditUserPasswordFormProps extends DialogFormProps {
|
||||
user: RemoteAppGetUsersQuery['users'][0];
|
||||
}
|
||||
|
||||
export const validationSchema = Yup.object({
|
||||
password: Yup.string()
|
||||
.label('Users Password')
|
||||
.min(8, 'Password must be at least 8 characters long.')
|
||||
.required('This field is required.'),
|
||||
cpassword: Yup.string()
|
||||
.required('Confirm Password is required')
|
||||
.min(8, 'Password must be at least 8 characters long.')
|
||||
.oneOf([Yup.ref('password')], 'Passwords do not match'),
|
||||
});
|
||||
|
||||
export type EditUserPasswordFormValues = Yup.InferType<typeof validationSchema>;
|
||||
|
||||
export default function EditUserPasswordForm({
|
||||
onCancel,
|
||||
user,
|
||||
@@ -49,26 +40,52 @@ export default function EditUserPasswordForm({
|
||||
client: remoteProjectGQLClient,
|
||||
});
|
||||
const { closeDialog } = useDialog();
|
||||
const { currentProject } = useCurrentWorkspaceAndProject();
|
||||
const { data } = useGetSignInMethodsQuery({
|
||||
variables: { appId: currentProject?.id },
|
||||
skip: !currentProject?.id,
|
||||
});
|
||||
|
||||
const passwordMinLength =
|
||||
data?.config?.auth?.method?.emailPassword?.passwordMinLength || 1;
|
||||
|
||||
const validationSchema = Yup.object({
|
||||
password: Yup.string()
|
||||
.label('Password')
|
||||
.min(
|
||||
passwordMinLength,
|
||||
`Password must be at least ${passwordMinLength} characters long.`,
|
||||
)
|
||||
.required('This field is required.'),
|
||||
cpassword: Yup.string()
|
||||
.label('Password Confirmation')
|
||||
.min(
|
||||
passwordMinLength,
|
||||
`Password must be at least ${passwordMinLength} characters long.`,
|
||||
)
|
||||
.oneOf([Yup.ref('password')], 'Passwords do not match')
|
||||
.required('This field is required.'),
|
||||
});
|
||||
|
||||
const [editUserPasswordFormError, setEditUserPasswordFormError] =
|
||||
useState<Error | null>(null);
|
||||
|
||||
const form = useForm<EditUserPasswordFormValues>({
|
||||
const form = useForm<Yup.InferType<typeof validationSchema>>({
|
||||
defaultValues: {},
|
||||
reValidateMode: 'onSubmit',
|
||||
resolver: yupResolver(validationSchema),
|
||||
});
|
||||
|
||||
const handleSubmit = async ({ password }: EditUserPasswordFormValues) => {
|
||||
const handleSubmit = async ({
|
||||
password,
|
||||
}: Yup.InferType<typeof validationSchema>) => {
|
||||
setEditUserPasswordFormError(null);
|
||||
const passwordHash = await bcrypt.hash(password, 10);
|
||||
|
||||
const updateUserPasswordPromise = updateUser({
|
||||
variables: {
|
||||
id: user.id,
|
||||
user: {
|
||||
passwordHash,
|
||||
},
|
||||
user: { passwordHash },
|
||||
},
|
||||
client: remoteProjectGQLClient,
|
||||
});
|
||||
|
||||
@@ -31,6 +31,7 @@ export type DatabaseServiceVersionFormValues = Yup.InferType<
|
||||
>;
|
||||
|
||||
const AVAILABLE_POSTGRES_VERSIONS = [
|
||||
'14.6-20230705-1',
|
||||
'14.6-20230613-1',
|
||||
'14.6-20230525',
|
||||
'14.6-20230406-2',
|
||||
|
||||
@@ -31,6 +31,8 @@ export type HasuraServiceVersionFormValues = Yup.InferType<
|
||||
>;
|
||||
|
||||
const AVAILABLE_HASURA_VERSIONS = [
|
||||
'v2.29.0-ce',
|
||||
'v2.28.2-ce',
|
||||
'v2.27.0-ce',
|
||||
'v2.25.1-ce',
|
||||
'v2.25.0-ce',
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
# @nhost/docs
|
||||
|
||||
## 0.4.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- c6fa8da6d: fix(docs): remove outdated reference/cli
|
||||
|
||||
## 0.3.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 923abd365: chore(deps): update dependency @tsconfig/docusaurus to v2
|
||||
|
||||
## 0.3.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -35,4 +35,4 @@ sudo nhost sw upgrade
|
||||
- [Local Development](/cli/local-development)
|
||||
- [Migrate to Nhost Config](/cli/migrate-config)
|
||||
- [Multiple Projects in Parallel](/cli/multiple-projects)
|
||||
- [CLI commands reference](/reference/cli)
|
||||
- [CLI Documentation](/cli)
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
---
|
||||
title: 'down'
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
Delete all containers created by `nhost up`
|
||||
|
||||
```bash
|
||||
nhost down
|
||||
```
|
||||
|
||||
To delete all containers **and the local database**, append `--data` to the command.
|
||||
|
||||
```bash
|
||||
nhost down --data
|
||||
```
|
||||
@@ -1,22 +0,0 @@
|
||||
---
|
||||
title: 'Global Flags'
|
||||
sidebar_position: 9
|
||||
---
|
||||
|
||||
### `--debug`, `-d`
|
||||
|
||||
Turn on debug output.
|
||||
|
||||
```bash
|
||||
nhost up --debug
|
||||
nhost init -d
|
||||
```
|
||||
|
||||
### `--log-file`, `-f`
|
||||
|
||||
Save output to a given file.
|
||||
|
||||
```bash
|
||||
nhost up -d --log-file some-file.txt
|
||||
nhost logs -f some-file.txt
|
||||
```
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
title: 'CLI'
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
This section is a reference for the commands available in the [Nhost CLI](/cli).
|
||||
@@ -1,24 +0,0 @@
|
||||
---
|
||||
title: 'init'
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
Initialize a local Nhost project.
|
||||
|
||||
```
|
||||
nhost init
|
||||
```
|
||||
|
||||
If you have an existing Nhost project in Nhost Cloud that you want to use as a starting point for local development and for the [Git-based workflow](/platform/git), run `nhost init --remote`.
|
||||
|
||||
The `nhost init --remote` command does the following:
|
||||
|
||||
- Creates a new local Nhost project.
|
||||
- Pulls the database migrations and Hasura metadata from the Nhost Cloud project.
|
||||
- Resets the remote Nhost Cloud project's database migrations.
|
||||
|
||||
:::warning
|
||||
|
||||
The `nhost init --remote` command should only be run **once**. Running it multiple times will reset the remote Nhost Cloud project's database migrations which can cause migration conflict issues in your development team.
|
||||
|
||||
:::
|
||||
@@ -1,10 +0,0 @@
|
||||
---
|
||||
title: 'link'
|
||||
sidebar_position: 4
|
||||
---
|
||||
|
||||
Link the local Nhost project in your working directory to a project in Nhost Cloud.
|
||||
|
||||
```bash
|
||||
nhost link
|
||||
```
|
||||
@@ -1,10 +0,0 @@
|
||||
---
|
||||
title: 'list'
|
||||
sidebar_position: 7
|
||||
---
|
||||
|
||||
List projects in Nhost Cloud.
|
||||
|
||||
```bash
|
||||
nhost list
|
||||
```
|
||||
@@ -1,10 +0,0 @@
|
||||
---
|
||||
title: 'login'
|
||||
sidebar_position: 5
|
||||
---
|
||||
|
||||
Authenticate the CLI with your Nhost user.
|
||||
|
||||
```bash
|
||||
nhost login
|
||||
```
|
||||
@@ -1,10 +0,0 @@
|
||||
---
|
||||
title: 'logout'
|
||||
sidebar_position: 6
|
||||
---
|
||||
|
||||
Remove authentication for the CLI.
|
||||
|
||||
```bash
|
||||
nhost logout
|
||||
```
|
||||
@@ -1,10 +0,0 @@
|
||||
---
|
||||
title: 'logs'
|
||||
sidebar_position: 9
|
||||
---
|
||||
|
||||
View logs of all services.
|
||||
|
||||
```bash
|
||||
nhost logs
|
||||
```
|
||||
@@ -1,19 +0,0 @@
|
||||
---
|
||||
title: 'up'
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
To launch the development environment for your project, use the command `nhost up`. Once the environment is running, this command will
|
||||
|
||||
- Apply database migrations.
|
||||
- Apply Hasura metadata.
|
||||
|
||||
```bash
|
||||
nhost up
|
||||
```
|
||||
|
||||
If it's the first time you start the project, [seed data](/database#seed-data) will be applied.
|
||||
|
||||
## Stop
|
||||
|
||||
Use `ctrl+c` to stop the development environment.
|
||||
@@ -1,10 +0,0 @@
|
||||
---
|
||||
title: 'upgrade'
|
||||
sidebar_position: 8
|
||||
---
|
||||
|
||||
Upgrade the CLI to the latest version.
|
||||
|
||||
```bash
|
||||
nhost upgrade
|
||||
```
|
||||
@@ -30,7 +30,3 @@ In this section:
|
||||
- [Getting started](/reference/vue)
|
||||
- [Protecting routes](/reference/vue/protecting-routes)
|
||||
- [Apollo GraphQL](/reference/vue/apollo)
|
||||
|
||||
### Nhost CLI
|
||||
|
||||
- [CLI overview](/reference/cli)
|
||||
|
||||
@@ -69,12 +69,12 @@ HTTP endpoints are automatically generated based on the file structure inside `f
|
||||
|
||||
Here's an example of four Serverless Functions with their files and their HTTP endpoints:
|
||||
|
||||
| File | HTTP Endpoint |
|
||||
| --------------------------- | ----------------------------------------------------------------- |
|
||||
| `functions/index.js` | `https://[project-subdomain].nhost.run/v1/functions/` |
|
||||
| `functions/users/index.ts` | `https://[project-subdomain].nhost.run/v1/functions/users` |
|
||||
| `functions/users/active.ts` | `https://[project-subdomain].nhost.run/v1/functions/users/active` |
|
||||
| `functions/my-company.js` | `https://[project-subdomain].nhost.run/v1/functions/my-company` |
|
||||
| File | HTTP Endpoint |
|
||||
| --------------------------- | ------------------------------------------------------------------ |
|
||||
| `functions/index.js` | `https://[subdomain].functions.[region].nhost.run/v1/` |
|
||||
| `functions/users/index.ts` | `https://[subdomain].functions.[region].nhost.run/v1/users` |
|
||||
| `functions/users/active.ts` | `https://[subdomain].functions.[region].nhost.run/v1/users/active` |
|
||||
| `functions/my-company.js` | `https://[subdomain].functions.[region].nhost.run/v1/my-company` |
|
||||
|
||||
You can prepend files and folders with an underscore (`_`) to prevent them from being treated as Serverless Functions and
|
||||
be turned into HTTP endpoints. This is useful if you have, for example, a utils file (`functions/_utils.js`) or a utils-f
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/docs",
|
||||
"version": "0.3.4",
|
||||
"version": "0.4.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"docusaurus": "docusaurus",
|
||||
@@ -31,7 +31,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@docusaurus/module-type-aliases": "2.4.1",
|
||||
"@tsconfig/docusaurus": "^1.0.6",
|
||||
"@tsconfig/docusaurus": "^2.0.0",
|
||||
"typescript": "^4.8.4"
|
||||
},
|
||||
"browserslist": {
|
||||
|
||||
@@ -183,23 +183,6 @@ const sidebars = {
|
||||
dirName: 'reference/docgen/vue/content'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'CLI',
|
||||
link: { type: 'doc', id: 'reference/cli/index' },
|
||||
items: [
|
||||
'reference/cli/init',
|
||||
'reference/cli/up',
|
||||
'reference/cli/down',
|
||||
'reference/cli/link',
|
||||
'reference/cli/login',
|
||||
'reference/cli/logout',
|
||||
'reference/cli/list',
|
||||
'reference/cli/upgrade',
|
||||
'reference/cli/logs',
|
||||
'reference/cli/global-flags'
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
4
examples/node-storage/.gitignore
vendored
4
examples/node-storage/.gitignore
vendored
@@ -1 +1,3 @@
|
||||
.secrets.nhost
|
||||
.secrets
|
||||
.nhost
|
||||
cat.jpg
|
||||
@@ -1,5 +1,19 @@
|
||||
# @nhost-examples/node-storage
|
||||
|
||||
## 0.0.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- d54e4cdd4: fix(buckets): allow using custom buckets for upload
|
||||
- @nhost/nhost-js@2.2.12
|
||||
|
||||
## 0.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 2cdb13b3e: fix(upload): allow specifying `id` and `name` only when not using `form-data`
|
||||
- @nhost/nhost-js@2.2.11
|
||||
|
||||
## 0.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -26,5 +26,4 @@ You can use the `.env.example` file as a starting point.
|
||||
pnpm start
|
||||
```
|
||||
|
||||
The example will download a file from a public URL and upload it to your Nhost
|
||||
Storage bucket.
|
||||
The example will run a few upload operations and then exit.
|
||||
|
||||
6
examples/node-storage/nhost/metadata/actions.yaml
Normal file
6
examples/node-storage/nhost/metadata/actions.yaml
Normal file
@@ -0,0 +1,6 @@
|
||||
actions: []
|
||||
custom_types:
|
||||
enums: []
|
||||
input_objects: []
|
||||
objects: []
|
||||
scalars: []
|
||||
1
examples/node-storage/nhost/metadata/allow_list.yaml
Normal file
1
examples/node-storage/nhost/metadata/allow_list.yaml
Normal file
@@ -0,0 +1 @@
|
||||
[]
|
||||
1
examples/node-storage/nhost/metadata/api_limits.yaml
Normal file
1
examples/node-storage/nhost/metadata/api_limits.yaml
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
1
examples/node-storage/nhost/metadata/cron_triggers.yaml
Normal file
1
examples/node-storage/nhost/metadata/cron_triggers.yaml
Normal file
@@ -0,0 +1 @@
|
||||
[]
|
||||
@@ -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: 1
|
||||
use_prepared_statements: true
|
||||
tables: "!include default/tables/tables.yaml"
|
||||
@@ -0,0 +1,23 @@
|
||||
table:
|
||||
name: provider_requests
|
||||
schema: auth
|
||||
configuration:
|
||||
column_config:
|
||||
id:
|
||||
custom_name: id
|
||||
options:
|
||||
custom_name: options
|
||||
custom_column_names:
|
||||
id: id
|
||||
options: options
|
||||
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
|
||||
@@ -0,0 +1,28 @@
|
||||
table:
|
||||
name: providers
|
||||
schema: auth
|
||||
configuration:
|
||||
column_config:
|
||||
id:
|
||||
custom_name: id
|
||||
custom_column_names:
|
||||
id: id
|
||||
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
|
||||
@@ -0,0 +1,26 @@
|
||||
table:
|
||||
name: refresh_token_types
|
||||
schema: auth
|
||||
is_enum: true
|
||||
configuration:
|
||||
column_config: {}
|
||||
custom_column_names: {}
|
||||
custom_name: authRefreshTokenTypes
|
||||
custom_root_fields:
|
||||
delete: deleteAuthRefreshTokenTypes
|
||||
delete_by_pk: deleteAuthRefreshTokenType
|
||||
insert: insertAuthRefreshTokenTypes
|
||||
insert_one: insertAuthRefreshTokenType
|
||||
select: authRefreshTokenTypes
|
||||
select_aggregate: authRefreshTokenTypesAggregate
|
||||
select_by_pk: authRefreshTokenType
|
||||
update: updateAuthRefreshTokenTypes
|
||||
update_by_pk: updateAuthRefreshTokenType
|
||||
array_relationships:
|
||||
- name: refreshTokens
|
||||
using:
|
||||
foreign_key_constraint_on:
|
||||
column: type
|
||||
table:
|
||||
name: refresh_tokens
|
||||
schema: auth
|
||||
@@ -0,0 +1,55 @@
|
||||
table:
|
||||
name: refresh_tokens
|
||||
schema: auth
|
||||
configuration:
|
||||
column_config:
|
||||
created_at:
|
||||
custom_name: createdAt
|
||||
expires_at:
|
||||
custom_name: expiresAt
|
||||
refresh_token_hash:
|
||||
custom_name: refreshTokenHash
|
||||
user_id:
|
||||
custom_name: userId
|
||||
custom_column_names:
|
||||
created_at: createdAt
|
||||
expires_at: expiresAt
|
||||
refresh_token_hash: refreshTokenHash
|
||||
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
|
||||
select_permissions:
|
||||
- role: user
|
||||
permission:
|
||||
columns:
|
||||
- id
|
||||
- created_at
|
||||
- expires_at
|
||||
- metadata
|
||||
- type
|
||||
- user_id
|
||||
filter:
|
||||
user_id:
|
||||
_eq: X-Hasura-User-Id
|
||||
delete_permissions:
|
||||
- role: user
|
||||
permission:
|
||||
filter:
|
||||
_and:
|
||||
- user_id:
|
||||
_eq: X-Hasura-User-Id
|
||||
- type:
|
||||
_eq: pat
|
||||
@@ -0,0 +1,35 @@
|
||||
table:
|
||||
name: roles
|
||||
schema: auth
|
||||
configuration:
|
||||
column_config:
|
||||
role:
|
||||
custom_name: role
|
||||
custom_column_names:
|
||||
role: role
|
||||
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
|
||||
@@ -0,0 +1,48 @@
|
||||
table:
|
||||
name: user_providers
|
||||
schema: auth
|
||||
configuration:
|
||||
column_config:
|
||||
access_token:
|
||||
custom_name: accessToken
|
||||
created_at:
|
||||
custom_name: createdAt
|
||||
id:
|
||||
custom_name: id
|
||||
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
|
||||
id: id
|
||||
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
|
||||
@@ -0,0 +1,36 @@
|
||||
table:
|
||||
name: user_roles
|
||||
schema: auth
|
||||
configuration:
|
||||
column_config:
|
||||
created_at:
|
||||
custom_name: createdAt
|
||||
id:
|
||||
custom_name: id
|
||||
role:
|
||||
custom_name: role
|
||||
user_id:
|
||||
custom_name: userId
|
||||
custom_column_names:
|
||||
created_at: createdAt
|
||||
id: id
|
||||
role: role
|
||||
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
|
||||
@@ -0,0 +1,33 @@
|
||||
table:
|
||||
name: user_security_keys
|
||||
schema: auth
|
||||
configuration:
|
||||
column_config:
|
||||
credential_id:
|
||||
custom_name: credentialId
|
||||
credential_public_key:
|
||||
custom_name: credentialPublicKey
|
||||
id:
|
||||
custom_name: id
|
||||
user_id:
|
||||
custom_name: userId
|
||||
custom_column_names:
|
||||
credential_id: credentialId
|
||||
credential_public_key: credentialPublicKey
|
||||
id: id
|
||||
user_id: userId
|
||||
custom_name: authUserSecurityKeys
|
||||
custom_root_fields:
|
||||
delete: deleteAuthUserSecurityKeys
|
||||
delete_by_pk: deleteAuthUserSecurityKey
|
||||
insert: insertAuthUserSecurityKeys
|
||||
insert_one: insertAuthUserSecurityKey
|
||||
select: authUserSecurityKeys
|
||||
select_aggregate: authUserSecurityKeysAggregate
|
||||
select_by_pk: authUserSecurityKey
|
||||
update: updateAuthUserSecurityKeys
|
||||
update_by_pk: updateAuthUserSecurityKey
|
||||
object_relationships:
|
||||
- name: user
|
||||
using:
|
||||
foreign_key_constraint_on: user_id
|
||||
@@ -0,0 +1,122 @@
|
||||
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
|
||||
disabled:
|
||||
custom_name: disabled
|
||||
display_name:
|
||||
custom_name: displayName
|
||||
email:
|
||||
custom_name: email
|
||||
email_verified:
|
||||
custom_name: emailVerified
|
||||
id:
|
||||
custom_name: id
|
||||
is_anonymous:
|
||||
custom_name: isAnonymous
|
||||
last_seen:
|
||||
custom_name: lastSeen
|
||||
locale:
|
||||
custom_name: locale
|
||||
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:
|
||||
custom_name: ticket
|
||||
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
|
||||
disabled: disabled
|
||||
display_name: displayName
|
||||
email: email
|
||||
email_verified: emailVerified
|
||||
id: id
|
||||
is_anonymous: isAnonymous
|
||||
last_seen: lastSeen
|
||||
locale: locale
|
||||
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: ticket
|
||||
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: 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: securityKeys
|
||||
using:
|
||||
foreign_key_constraint_on:
|
||||
column: user_id
|
||||
table:
|
||||
name: user_security_keys
|
||||
schema: auth
|
||||
- name: userProviders
|
||||
using:
|
||||
foreign_key_constraint_on:
|
||||
column: user_id
|
||||
table:
|
||||
name: user_providers
|
||||
schema: auth
|
||||
@@ -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
|
||||
@@ -0,0 +1,51 @@
|
||||
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
|
||||
@@ -0,0 +1,11 @@
|
||||
- "!include auth_provider_requests.yaml"
|
||||
- "!include auth_providers.yaml"
|
||||
- "!include auth_refresh_token_types.yaml"
|
||||
- "!include auth_refresh_tokens.yaml"
|
||||
- "!include auth_roles.yaml"
|
||||
- "!include auth_user_providers.yaml"
|
||||
- "!include auth_user_roles.yaml"
|
||||
- "!include auth_user_security_keys.yaml"
|
||||
- "!include auth_users.yaml"
|
||||
- "!include storage_buckets.yaml"
|
||||
- "!include storage_files.yaml"
|
||||
@@ -0,0 +1 @@
|
||||
disabled_for_roles: []
|
||||
@@ -0,0 +1 @@
|
||||
[]
|
||||
1
examples/node-storage/nhost/metadata/metrics_config.yaml
Normal file
1
examples/node-storage/nhost/metadata/metrics_config.yaml
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
1
examples/node-storage/nhost/metadata/network.yaml
Normal file
1
examples/node-storage/nhost/metadata/network.yaml
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
1
examples/node-storage/nhost/metadata/opentelemetry.yaml
Normal file
1
examples/node-storage/nhost/metadata/opentelemetry.yaml
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -0,0 +1 @@
|
||||
[]
|
||||
1
examples/node-storage/nhost/metadata/remote_schemas.yaml
Normal file
1
examples/node-storage/nhost/metadata/remote_schemas.yaml
Normal file
@@ -0,0 +1 @@
|
||||
[]
|
||||
1
examples/node-storage/nhost/metadata/rest_endpoints.yaml
Normal file
1
examples/node-storage/nhost/metadata/rest_endpoints.yaml
Normal file
@@ -0,0 +1 @@
|
||||
[]
|
||||
1
examples/node-storage/nhost/metadata/version.yaml
Normal file
1
examples/node-storage/nhost/metadata/version.yaml
Normal file
@@ -0,0 +1 @@
|
||||
version: 3
|
||||
@@ -0,0 +1 @@
|
||||
DELETE FROM "storage"."buckets" WHERE "id" = 'custom';
|
||||
@@ -0,0 +1 @@
|
||||
INSERT INTO "storage"."buckets"("presigned_urls_enabled", "download_expiration", "max_upload_file_size", "min_upload_file_size", "cache_control", "id", "created_at", "updated_at") VALUES (true, 30, 30000000, 1, E'max-age=3600', E'custom', E'2023-06-29T14:30:13.859559+00:00', E'2023-06-29T14:30:13.859559+00:00');
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost-examples/node-storage",
|
||||
"version": "0.0.2",
|
||||
"version": "0.0.4",
|
||||
"private": true,
|
||||
"description": "This is an example of how to use the Storage with Node.js",
|
||||
"main": "src/index.mjs",
|
||||
@@ -14,9 +14,12 @@
|
||||
"@nhost/nhost-js": "*",
|
||||
"dotenv": "^16.1.3",
|
||||
"form-data": "^4.0.0",
|
||||
"node-fetch": "^3.3.0"
|
||||
"fs-extra": "^11.1.1",
|
||||
"node-fetch": "^3.3.0",
|
||||
"uuid": "^9.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.15.11"
|
||||
"@types/node": "^18.15.11",
|
||||
"@types/uuid": "^9.0.1"
|
||||
}
|
||||
}
|
||||
|
||||
44
examples/node-storage/pnpm-lock.yaml
generated
44
examples/node-storage/pnpm-lock.yaml
generated
@@ -10,14 +10,23 @@ dependencies:
|
||||
form-data:
|
||||
specifier: ^4.0.0
|
||||
version: 4.0.0
|
||||
fs-extra:
|
||||
specifier: ^11.1.1
|
||||
version: 11.1.1
|
||||
node-fetch:
|
||||
specifier: ^3.3.0
|
||||
version: 3.3.0
|
||||
uuid:
|
||||
specifier: ^9.0.0
|
||||
version: 9.0.0
|
||||
|
||||
devDependencies:
|
||||
'@types/node':
|
||||
specifier: ^18.15.11
|
||||
version: 18.15.11
|
||||
'@types/uuid':
|
||||
specifier: ^9.0.1
|
||||
version: 9.0.1
|
||||
|
||||
packages:
|
||||
|
||||
@@ -32,6 +41,10 @@ packages:
|
||||
resolution: {integrity: sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==}
|
||||
dev: true
|
||||
|
||||
/@types/uuid@9.0.1:
|
||||
resolution: {integrity: sha512-rFT3ak0/2trgvp4yYZo5iKFEPsET7vKydKF+VRCxlQ9bpheehyAJH89dAkaLEq/j/RZXJIqcgsmPJKUP1Z28HA==}
|
||||
dev: true
|
||||
|
||||
/asynckit@0.4.0:
|
||||
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
|
||||
dev: false
|
||||
@@ -92,6 +105,27 @@ packages:
|
||||
fetch-blob: 3.2.0
|
||||
dev: false
|
||||
|
||||
/fs-extra@11.1.1:
|
||||
resolution: {integrity: sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==}
|
||||
engines: {node: '>=14.14'}
|
||||
dependencies:
|
||||
graceful-fs: 4.2.11
|
||||
jsonfile: 6.1.0
|
||||
universalify: 2.0.0
|
||||
dev: false
|
||||
|
||||
/graceful-fs@4.2.11:
|
||||
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
|
||||
dev: false
|
||||
|
||||
/jsonfile@6.1.0:
|
||||
resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==}
|
||||
dependencies:
|
||||
universalify: 2.0.0
|
||||
optionalDependencies:
|
||||
graceful-fs: 4.2.11
|
||||
dev: false
|
||||
|
||||
/jwt-decode@3.1.2:
|
||||
resolution: {integrity: sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==}
|
||||
dev: false
|
||||
@@ -142,6 +176,16 @@ packages:
|
||||
engines: {node: '>=4'}
|
||||
dev: false
|
||||
|
||||
/universalify@2.0.0:
|
||||
resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
dev: false
|
||||
|
||||
/uuid@9.0.0:
|
||||
resolution: {integrity: sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==}
|
||||
hasBin: true
|
||||
dev: false
|
||||
|
||||
/web-streams-polyfill@3.2.1:
|
||||
resolution: {integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==}
|
||||
engines: {node: '>= 8'}
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import { NhostClient } from '@nhost/nhost-js'
|
||||
import dotenv from 'dotenv'
|
||||
|
||||
dotenv.config()
|
||||
|
||||
/**
|
||||
* Create a new Nhost client.
|
||||
|
||||
@@ -1,62 +1,17 @@
|
||||
import dotenv from 'dotenv'
|
||||
import FormData from 'form-data'
|
||||
import fetch from 'node-fetch'
|
||||
import { createClient } from './client.mjs'
|
||||
import { uploadFile } from './uploadFile.mjs'
|
||||
import { uploadFormData } from './uploadFormData.mjs'
|
||||
import { uploadToBucket } from './uploadToBucket.mjs'
|
||||
|
||||
dotenv.config()
|
||||
async function uploadFiles() {
|
||||
await uploadFormData()
|
||||
|
||||
const client = createClient()
|
||||
console.info('-----')
|
||||
|
||||
async function uploadImage() {
|
||||
try {
|
||||
// Download image from remote URL
|
||||
const response = await fetch(
|
||||
'https://hips.hearstapps.com/hmg-prod/images/cute-cat-photos-1593441022.jpg?crop=1.00xw:0.753xh;0,0.153xh&resize=1200:*'
|
||||
)
|
||||
await uploadFile()
|
||||
|
||||
if (!response.ok) {
|
||||
console.error('Image not found!')
|
||||
console.info('-----')
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
const arrayBuffer = await response.arrayBuffer()
|
||||
|
||||
const formData = new FormData()
|
||||
formData.append('file[]', Buffer.from(arrayBuffer), 'cat.jpg')
|
||||
|
||||
// Upload file to Nhost Storage
|
||||
const { error: uploadError, fileMetadata } = await client.storage.upload({
|
||||
formData,
|
||||
headers: { ...formData.getHeaders() }
|
||||
})
|
||||
|
||||
if (uploadError) {
|
||||
console.error(uploadError)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
console.info(`File has been uploaded successfully!`)
|
||||
|
||||
const uploadedFile =
|
||||
'processedFiles' in fileMetadata ? fileMetadata.processedFiles[0] : fileMetadata
|
||||
|
||||
console.info(`ID: ${uploadedFile?.id}`)
|
||||
|
||||
// Generate a presigned URL for the uploaded file
|
||||
const { error: presignError, presignedUrl: blurredImage } =
|
||||
await client.storage.getPresignedUrl({ fileId: uploadedFile.id })
|
||||
|
||||
if (presignError) {
|
||||
console.error(presignError)
|
||||
return
|
||||
}
|
||||
|
||||
console.info(`Presigned URL: ${blurredImage.url}`)
|
||||
} catch (error) {
|
||||
console.error(error.message)
|
||||
}
|
||||
await uploadToBucket()
|
||||
}
|
||||
|
||||
uploadImage()
|
||||
uploadFiles()
|
||||
|
||||
70
examples/node-storage/src/uploadFile.mjs
Normal file
70
examples/node-storage/src/uploadFile.mjs
Normal file
@@ -0,0 +1,70 @@
|
||||
import fs from 'fs'
|
||||
import fetch from 'node-fetch'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { createClient } from './client.mjs'
|
||||
|
||||
const client = createClient()
|
||||
|
||||
export async function uploadFile() {
|
||||
console.info('Uploading a Single File Directly...')
|
||||
|
||||
try {
|
||||
// Download image from remote URL
|
||||
const response = await fetch(
|
||||
'https://hips.hearstapps.com/hmg-prod/images/cute-cat-photos-1593441022.jpg?crop=1.00xw:0.753xh;0,0.153xh&resize=1200:*'
|
||||
)
|
||||
|
||||
if (!response.ok) {
|
||||
console.error(`[file]`, 'Image not found!')
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
const arrayBuffer = await response.arrayBuffer()
|
||||
|
||||
const fileBuffer = Buffer.from(arrayBuffer)
|
||||
const fileName = 'cat.jpg'
|
||||
|
||||
fs.writeFile(fileName, fileBuffer, async (err) => {
|
||||
if (err) {
|
||||
console.error(`[file]`, err)
|
||||
return
|
||||
}
|
||||
|
||||
const file = fs.createReadStream(fileName)
|
||||
const customFileId = uuidv4()
|
||||
|
||||
const { error: uploadError, fileMetadata } = await client.storage.upload({
|
||||
file,
|
||||
id: customFileId
|
||||
})
|
||||
|
||||
if (uploadError) {
|
||||
console.error(`[file]`, uploadError)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
console.info(`[file]`, `File has been uploaded successfully!`)
|
||||
|
||||
console.info(`[file]`, `ID: ${fileMetadata?.id}`)
|
||||
console.info(`[file]`, `Matches custom ID: ${fileMetadata?.id === customFileId}`)
|
||||
|
||||
// Generate a presigned URL for the uploaded file
|
||||
const { error: presignError, presignedUrl: image } = await client.storage.getPresignedUrl({
|
||||
fileId: fileMetadata.id
|
||||
})
|
||||
|
||||
if (presignError) {
|
||||
console.error(`[file]`, presignError)
|
||||
return
|
||||
}
|
||||
|
||||
console.info(`[file]`, `Presigned URL: ${image.url}`)
|
||||
})
|
||||
|
||||
// Upload file to Nhost Storage
|
||||
} catch (error) {
|
||||
console.error(`[file]`, error.message)
|
||||
}
|
||||
}
|
||||
90
examples/node-storage/src/uploadFormData.mjs
Normal file
90
examples/node-storage/src/uploadFormData.mjs
Normal file
@@ -0,0 +1,90 @@
|
||||
import FormData from 'form-data'
|
||||
import fetch from 'node-fetch'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { createClient } from './client.mjs'
|
||||
|
||||
const client = createClient()
|
||||
|
||||
export async function uploadFormData() {
|
||||
console.info('Uploading 2 Files via Form Data...')
|
||||
|
||||
try {
|
||||
// Download image from remote URL
|
||||
const response = await fetch(
|
||||
'https://hips.hearstapps.com/hmg-prod/images/cute-cat-photos-1593441022.jpg?crop=1.00xw:0.753xh;0,0.153xh&resize=1200:*'
|
||||
)
|
||||
|
||||
if (!response.ok) {
|
||||
console.error(`[form-data]`, 'Image not found!')
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
const arrayBuffer = await response.arrayBuffer()
|
||||
|
||||
const customValues = [
|
||||
{
|
||||
id: uuidv4(),
|
||||
name: 'cat1.jpg'
|
||||
},
|
||||
{
|
||||
id: uuidv4(),
|
||||
name: 'cat2.jpg'
|
||||
}
|
||||
]
|
||||
|
||||
const formData = new FormData()
|
||||
|
||||
formData.append('file[]', Buffer.from(arrayBuffer), customValues[0].name)
|
||||
formData.append('metadata[]', JSON.stringify({ id: customValues[0].id }))
|
||||
formData.append('file[]', Buffer.from(arrayBuffer), customValues[1].name)
|
||||
formData.append('metadata[]', JSON.stringify({ id: customValues[1].id }))
|
||||
|
||||
// Upload files to Nhost Storage
|
||||
const { error: uploadError, fileMetadata } = await client.storage.upload({
|
||||
formData,
|
||||
headers: { ...formData.getHeaders() }
|
||||
})
|
||||
|
||||
if (uploadError) {
|
||||
console.error(`[form-data]`, uploadError)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if (fileMetadata.processedFiles.length !== 2) {
|
||||
console.error(
|
||||
`[form-data]`,
|
||||
`Expected 2 files to be uploaded, but got ${fileMetadata.processedFiles.length}`
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
await Promise.all(
|
||||
fileMetadata?.processedFiles.map(async (processedFile, index) => {
|
||||
console.info(`[form-data]`, `File has been uploaded successfully!`)
|
||||
|
||||
console.info(`[form-data]`, `ID: ${processedFile.id}`)
|
||||
console.info(
|
||||
`[form-data]`,
|
||||
`Matches custom ID: ${customValues.some(({ id }) => processedFile.id === id)}`
|
||||
)
|
||||
|
||||
// Generate a presigned URL for the uploaded file
|
||||
const { error: presignError, presignedUrl: image } = await client.storage.getPresignedUrl({
|
||||
fileId: processedFile.id
|
||||
})
|
||||
|
||||
if (presignError) {
|
||||
console.error(`[form-data]`, presignError)
|
||||
return
|
||||
}
|
||||
|
||||
console.info(`[form-data]`, `Presigned URL: ${image.url}`)
|
||||
})
|
||||
)
|
||||
} catch (error) {
|
||||
console.error(`[form-data]`, error.message)
|
||||
}
|
||||
}
|
||||
68
examples/node-storage/src/uploadToBucket.mjs
Normal file
68
examples/node-storage/src/uploadToBucket.mjs
Normal file
@@ -0,0 +1,68 @@
|
||||
import fs from 'fs'
|
||||
import fetch from 'node-fetch'
|
||||
import { createClient } from './client.mjs'
|
||||
|
||||
const client = createClient()
|
||||
|
||||
export async function uploadToBucket() {
|
||||
console.info('Uploading a Single File to a custom bucket...')
|
||||
|
||||
try {
|
||||
// Download image from remote URL
|
||||
const response = await fetch(
|
||||
'https://hips.hearstapps.com/hmg-prod/images/cute-cat-photos-1593441022.jpg?crop=1.00xw:0.753xh;0,0.153xh&resize=1200:*'
|
||||
)
|
||||
|
||||
if (!response.ok) {
|
||||
console.error(`[file-to-bucket]`, 'Image not found!')
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
const arrayBuffer = await response.arrayBuffer()
|
||||
|
||||
const fileBuffer = Buffer.from(arrayBuffer)
|
||||
const fileName = 'cat.jpg'
|
||||
|
||||
fs.writeFile(fileName, fileBuffer, async (err) => {
|
||||
if (err) {
|
||||
console.error(`[file-to-bucket]`, err)
|
||||
return
|
||||
}
|
||||
|
||||
const file = fs.createReadStream(fileName)
|
||||
|
||||
const { error: uploadError, fileMetadata } = await client.storage.upload({
|
||||
file,
|
||||
bucketId: 'custom'
|
||||
})
|
||||
|
||||
if (uploadError) {
|
||||
console.error(`[file-to-bucket]`, uploadError)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
console.info(`[file-to-bucket]`, `File has been uploaded successfully!`)
|
||||
console.info(`[file-to-bucket]`, `ID: ${fileMetadata?.id}`)
|
||||
|
||||
console.log(fileMetadata.bucketId)
|
||||
|
||||
// Generate a presigned URL for the uploaded file
|
||||
const { error: presignError, presignedUrl: image } = await client.storage.getPresignedUrl({
|
||||
fileId: fileMetadata.id
|
||||
})
|
||||
|
||||
if (presignError) {
|
||||
console.error(`[file-to-bucket]`, presignError)
|
||||
return
|
||||
}
|
||||
|
||||
console.info(`[file-to-bucket]`, `Presigned URL: ${image.url}`)
|
||||
})
|
||||
|
||||
// Upload file to Nhost Storage
|
||||
} catch (error) {
|
||||
console.error(`[file-to-bucket]`, error.message)
|
||||
}
|
||||
}
|
||||
11
examples/node-storage/tsconfig.json
Normal file
11
examples/node-storage/tsconfig.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"strictNullChecks": false
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
HASURA_GRAPHQL_ADMIN_SECRET=nhost-admin-secret
|
||||
HASURA_GRAPHQL_JWT_SECRET=oqpdwyffgxncqamwlyebkaifyazvqgso
|
||||
NHOST_WEBHOOK_SECRET=nhost-webhook-secret
|
||||
GRAFANA_ADMIN_PASSWORD=FIXME
|
||||
HASURA_GRAPHQL_ADMIN_SECRET='nhost-admin-secret'
|
||||
HASURA_GRAPHQL_JWT_SECRET='oqpdwyffgxncqamwlyebkaifyazvqgso'
|
||||
NHOST_WEBHOOK_SECRET='nhost-webhook-secret'
|
||||
GRAFANA_ADMIN_PASSWORD='FIXME'
|
||||
|
||||
@@ -125,7 +125,7 @@
|
||||
buildInputs = with pkgs; [
|
||||
nhost
|
||||
nodejs_18
|
||||
# nodePackages.pnpm
|
||||
nodePackages.pnpm
|
||||
] ++ buildInputs ++ nativeBuildInputs;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
# @nhost/apollo
|
||||
|
||||
## 5.2.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@2.2.13
|
||||
|
||||
## 5.2.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@2.2.12
|
||||
|
||||
## 5.2.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@2.2.11
|
||||
|
||||
## 5.2.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/apollo",
|
||||
"version": "5.2.12",
|
||||
"version": "5.2.15",
|
||||
"description": "Nhost Apollo Client library",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
|
||||
@@ -1,5 +1,26 @@
|
||||
# @nhost/react-apollo
|
||||
|
||||
## 5.0.32
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/apollo@5.2.15
|
||||
- @nhost/react@2.0.28
|
||||
|
||||
## 5.0.31
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/apollo@5.2.14
|
||||
- @nhost/react@2.0.27
|
||||
|
||||
## 5.0.30
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/apollo@5.2.13
|
||||
- @nhost/react@2.0.26
|
||||
|
||||
## 5.0.29
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/react-apollo",
|
||||
"version": "5.0.29",
|
||||
"version": "5.0.32",
|
||||
"description": "Nhost React Apollo client",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
# @nhost/react-urql
|
||||
|
||||
## 2.0.29
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@2.0.28
|
||||
|
||||
## 2.0.28
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@2.0.27
|
||||
|
||||
## 2.0.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@2.0.26
|
||||
|
||||
## 2.0.26
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/react-urql",
|
||||
"version": "2.0.26",
|
||||
"version": "2.0.29",
|
||||
"description": "Nhost React URQL client",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
|
||||
@@ -629,6 +629,103 @@
|
||||
"title": "Network Traffic",
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${DS_PROMETHEUS}"
|
||||
},
|
||||
"description": "This graph shows when a service was restarted. There are two main reasons why a service may be restarted:\n\n- OOMKilled - This means the service tried to use more memory than it has available and had to be restarted. For more information on resources you can check the [documentation](https://docs.nhost.io/platform/compute).\n- Error - This can show for mainly two reasons; when new configuration needs to be applied the service is terminated and due to limitations this shows as \"Error\" but it is, in fact, part of normal operations. This can also show if your service is misconfigured and/or can't start correctly for some reason. If this error doesn't show constantly it is safe to ignore this error.",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"custom": {
|
||||
"axisCenteredZero": false,
|
||||
"axisColorMode": "text",
|
||||
"axisLabel": "",
|
||||
"axisPlacement": "auto",
|
||||
"barAlignment": 0,
|
||||
"drawStyle": "line",
|
||||
"fillOpacity": 0,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"legend": false,
|
||||
"tooltip": false,
|
||||
"viz": false
|
||||
},
|
||||
"lineInterpolation": "linear",
|
||||
"lineWidth": 1,
|
||||
"pointSize": 5,
|
||||
"scaleDistribution": {
|
||||
"type": "linear"
|
||||
},
|
||||
"showPoints": "auto",
|
||||
"spanNulls": false,
|
||||
"stacking": {
|
||||
"group": "A",
|
||||
"mode": "none"
|
||||
},
|
||||
"thresholdsStyle": {
|
||||
"mode": "off"
|
||||
}
|
||||
},
|
||||
"decimals": 2,
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 80
|
||||
}
|
||||
]
|
||||
},
|
||||
"unit": "none"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 29
|
||||
},
|
||||
"id": 37,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "list",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": {
|
||||
"mode": "single",
|
||||
"sort": "none"
|
||||
}
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${DS_PROMETHEUS}"
|
||||
},
|
||||
"editorMode": "code",
|
||||
"expr": "sum by(container, reason) (increase(pod_terminated_total[$__rate_interval]))",
|
||||
"hide": false,
|
||||
"interval": "2m",
|
||||
"legendFormat": "{{container}}-{{reason}}",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "Service Restarts",
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"collapsed": false,
|
||||
"gridPos": {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
HASURA_GRAPHQL_ADMIN_SECRET=nhost-admin-secret
|
||||
HASURA_GRAPHQL_JWT_SECRET=oqpdwyffgxncqamwlyebkaifyazvqgso
|
||||
NHOST_WEBHOOK_SECRET=nhost-webhook-secret
|
||||
GRAFANA_ADMIN_PASSWORD=FIXME
|
||||
HASURA_GRAPHQL_ADMIN_SECRET='nhost-admin-secret'
|
||||
HASURA_GRAPHQL_JWT_SECRET='oqpdwyffgxncqamwlyebkaifyazvqgso'
|
||||
NHOST_WEBHOOK_SECRET='nhost-webhook-secret'
|
||||
GRAFANA_ADMIN_PASSWORD='FIXME'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
HASURA_GRAPHQL_ADMIN_SECRET=nhost-admin-secret
|
||||
HASURA_GRAPHQL_JWT_SECRET=oqpdwyffgxncqamwlyebkaifyazvqgso
|
||||
NHOST_WEBHOOK_SECRET=nhost-webhook-secret
|
||||
GRAFANA_ADMIN_PASSWORD=FIXME
|
||||
HASURA_GRAPHQL_ADMIN_SECRET='nhost-admin-secret'
|
||||
HASURA_GRAPHQL_JWT_SECRET='oqpdwyffgxncqamwlyebkaifyazvqgso'
|
||||
NHOST_WEBHOOK_SECRET='nhost-webhook-secret'
|
||||
GRAFANA_ADMIN_PASSWORD='FIXME'
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
# @nhost/hasura-storage-js
|
||||
|
||||
## 2.2.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 300e3f49e: fix(hasura-storage-js): fix file upload formData field
|
||||
|
||||
## 2.2.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- d54e4cdd4: fix(buckets): allow using custom buckets for upload
|
||||
|
||||
## 2.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 2cdb13b3e: fix(upload): allow specifying `id` and `name` only when not using `form-data`
|
||||
|
||||
## 2.1.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -0,0 +1,26 @@
|
||||
table:
|
||||
name: refresh_token_types
|
||||
schema: auth
|
||||
is_enum: true
|
||||
configuration:
|
||||
column_config: {}
|
||||
custom_column_names: {}
|
||||
custom_name: authRefreshTokenTypes
|
||||
custom_root_fields:
|
||||
delete: deleteAuthRefreshTokenTypes
|
||||
delete_by_pk: deleteAuthRefreshTokenType
|
||||
insert: insertAuthRefreshTokenTypes
|
||||
insert_one: insertAuthRefreshTokenType
|
||||
select: authRefreshTokenTypes
|
||||
select_aggregate: authRefreshTokenTypesAggregate
|
||||
select_by_pk: authRefreshTokenType
|
||||
update: updateAuthRefreshTokenTypes
|
||||
update_by_pk: updateAuthRefreshTokenType
|
||||
array_relationships:
|
||||
- name: refreshTokens
|
||||
using:
|
||||
foreign_key_constraint_on:
|
||||
column: type
|
||||
table:
|
||||
name: refresh_tokens
|
||||
schema: auth
|
||||
@@ -7,14 +7,14 @@ configuration:
|
||||
custom_name: createdAt
|
||||
expires_at:
|
||||
custom_name: expiresAt
|
||||
refresh_token:
|
||||
custom_name: refreshToken
|
||||
refresh_token_hash:
|
||||
custom_name: refreshTokenHash
|
||||
user_id:
|
||||
custom_name: userId
|
||||
custom_column_names:
|
||||
created_at: createdAt
|
||||
expires_at: expiresAt
|
||||
refresh_token: refreshToken
|
||||
refresh_token_hash: refreshTokenHash
|
||||
user_id: userId
|
||||
custom_name: authRefreshTokens
|
||||
custom_root_fields:
|
||||
@@ -31,3 +31,25 @@ object_relationships:
|
||||
- name: user
|
||||
using:
|
||||
foreign_key_constraint_on: user_id
|
||||
select_permissions:
|
||||
- role: user
|
||||
permission:
|
||||
columns:
|
||||
- id
|
||||
- created_at
|
||||
- expires_at
|
||||
- metadata
|
||||
- type
|
||||
- user_id
|
||||
filter:
|
||||
user_id:
|
||||
_eq: X-Hasura-User-Id
|
||||
delete_permissions:
|
||||
- role: user
|
||||
permission:
|
||||
filter:
|
||||
_and:
|
||||
- user_id:
|
||||
_eq: X-Hasura-User-Id
|
||||
- type:
|
||||
_eq: pat
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
- "!include auth_provider_requests.yaml"
|
||||
- "!include auth_providers.yaml"
|
||||
- "!include auth_refresh_token_types.yaml"
|
||||
- "!include auth_refresh_tokens.yaml"
|
||||
- "!include auth_roles.yaml"
|
||||
- "!include auth_user_providers.yaml"
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/hasura-storage-js",
|
||||
"version": "2.1.6",
|
||||
"version": "2.2.2",
|
||||
"description": "Hasura-storage client",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
import fetchPonyfill from 'fetch-ponyfill'
|
||||
import FormData from 'form-data'
|
||||
import {
|
||||
ApiDeleteParams,
|
||||
ApiDeleteResponse,
|
||||
ApiGetPresignedUrlParams,
|
||||
ApiGetPresignedUrlResponse,
|
||||
StorageUploadFileParams,
|
||||
StorageUploadFileResponse,
|
||||
StorageUploadFormDataParams,
|
||||
StorageUploadResponse
|
||||
StorageUploadFormDataResponse
|
||||
} from './utils/types'
|
||||
import { fetchUpload } from './utils/upload'
|
||||
|
||||
@@ -24,21 +27,65 @@ export class HasuraStorageApi {
|
||||
this.url = url
|
||||
}
|
||||
|
||||
async upload({
|
||||
async uploadFormData({
|
||||
formData,
|
||||
headers,
|
||||
bucketId
|
||||
}: StorageUploadFormDataParams): Promise<StorageUploadFormDataResponse> {
|
||||
const { error, fileMetadata } = await fetchUpload(this.url, formData, {
|
||||
accessToken: this.accessToken,
|
||||
adminSecret: this.adminSecret,
|
||||
bucketId,
|
||||
headers
|
||||
})
|
||||
|
||||
if (error) {
|
||||
return { fileMetadata: null, error }
|
||||
}
|
||||
|
||||
if (fileMetadata && !('processedFiles' in fileMetadata)) {
|
||||
return {
|
||||
fileMetadata: {
|
||||
processedFiles: [fileMetadata]
|
||||
},
|
||||
error: null
|
||||
}
|
||||
}
|
||||
|
||||
return { fileMetadata, error: null }
|
||||
}
|
||||
|
||||
async uploadFile({
|
||||
file,
|
||||
bucketId,
|
||||
id,
|
||||
name
|
||||
}: StorageUploadFormDataParams): Promise<StorageUploadResponse> {
|
||||
return fetchUpload(this.url, formData, {
|
||||
}: StorageUploadFileParams): Promise<StorageUploadFileResponse> {
|
||||
const formData = new FormData()
|
||||
|
||||
formData.append('file[]', file)
|
||||
formData.append('metadata[]', JSON.stringify({ id, name }))
|
||||
|
||||
const { error, fileMetadata } = await fetchUpload(this.url, formData, {
|
||||
accessToken: this.accessToken,
|
||||
adminSecret: this.adminSecret,
|
||||
bucketId,
|
||||
fileId: id,
|
||||
name,
|
||||
headers
|
||||
name
|
||||
})
|
||||
|
||||
if (error) {
|
||||
return { fileMetadata: null, error }
|
||||
}
|
||||
|
||||
if (fileMetadata && 'processedFiles' in fileMetadata) {
|
||||
return {
|
||||
fileMetadata: fileMetadata.processedFiles[0],
|
||||
error: null
|
||||
}
|
||||
}
|
||||
|
||||
return { fileMetadata, error: null }
|
||||
}
|
||||
|
||||
async getPresignedUrl(params: ApiGetPresignedUrlParams): Promise<ApiGetPresignedUrlResponse> {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import FormData from 'form-data'
|
||||
import { HasuraStorageApi } from './hasura-storage-api'
|
||||
import {
|
||||
appendImageTransformationParameters,
|
||||
@@ -8,7 +7,9 @@ import {
|
||||
StorageGetPresignedUrlResponse,
|
||||
StorageGetUrlParams,
|
||||
StorageUploadFileParams,
|
||||
StorageUploadFileResponse,
|
||||
StorageUploadFormDataParams,
|
||||
StorageUploadFormDataResponse,
|
||||
StorageUploadParams,
|
||||
StorageUploadResponse
|
||||
} from './utils'
|
||||
@@ -73,21 +74,14 @@ export class HasuraStorageClient {
|
||||
* @docs https://docs.nhost.io/reference/javascript/storage/upload
|
||||
*/
|
||||
|
||||
async upload(params: StorageUploadFileParams): Promise<StorageUploadResponse>
|
||||
async upload(params: StorageUploadFormDataParams): Promise<StorageUploadResponse>
|
||||
async upload(params: StorageUploadFileParams): Promise<StorageUploadFileResponse>
|
||||
async upload(params: StorageUploadFormDataParams): Promise<StorageUploadFormDataResponse>
|
||||
async upload(params: StorageUploadParams): Promise<StorageUploadResponse> {
|
||||
if ('file' in params) {
|
||||
const formData = new FormData()
|
||||
|
||||
formData.append('file[]', params.file)
|
||||
|
||||
return this.api.upload({
|
||||
...params,
|
||||
formData
|
||||
})
|
||||
return this.api.uploadFile(params)
|
||||
}
|
||||
|
||||
return this.api.upload(params)
|
||||
return this.api.uploadFormData(params)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -118,7 +118,7 @@ export const createFileUploadMachine = () =>
|
||||
uploadFile: (context, event) => (callback) => {
|
||||
const file = (event.file || context.file)!
|
||||
const data = new FormData()
|
||||
data.append('file', file)
|
||||
data.append('file[]', file)
|
||||
|
||||
let currentLoaded = 0
|
||||
|
||||
|
||||
@@ -36,8 +36,6 @@ export interface StorageUploadFileParams {
|
||||
// works in browser and server
|
||||
export interface StorageUploadFormDataParams {
|
||||
formData: FormData
|
||||
id?: string
|
||||
name?: string
|
||||
bucketId?: string
|
||||
headers?: Record<string, string>
|
||||
}
|
||||
@@ -45,10 +43,16 @@ export interface StorageUploadFormDataParams {
|
||||
// works in browser and server
|
||||
export type StorageUploadParams = StorageUploadFileParams | StorageUploadFormDataParams
|
||||
|
||||
export type StorageUploadResponse =
|
||||
| { fileMetadata: FileResponse | { processedFiles: FileResponse[] }; error: null }
|
||||
export type StorageUploadFileResponse =
|
||||
| { fileMetadata: FileResponse; error: null }
|
||||
| { fileMetadata: null; error: StorageErrorPayload }
|
||||
|
||||
export type StorageUploadFormDataResponse =
|
||||
| { fileMetadata: { processedFiles: FileResponse[] }; error: null }
|
||||
| { fileMetadata: null; error: StorageErrorPayload }
|
||||
|
||||
export type StorageUploadResponse = StorageUploadFileResponse | StorageUploadFormDataResponse
|
||||
|
||||
export interface StorageImageTransformationParams {
|
||||
/** Image width, in pixels */
|
||||
width?: number
|
||||
|
||||
@@ -38,15 +38,8 @@ export const fetchUpload = async (
|
||||
const headers: HeadersInit = {
|
||||
...initialHeaders
|
||||
}
|
||||
|
||||
if (fileId) {
|
||||
headers['x-nhost-file-id'] = fileId
|
||||
}
|
||||
if (bucketId) {
|
||||
headers['x-nhost-bucket-id'] = bucketId
|
||||
}
|
||||
if (name) {
|
||||
headers['x-nhost-file-name'] = toIso88591(name)
|
||||
data.append('bucket-id', bucketId)
|
||||
}
|
||||
if (adminSecret) {
|
||||
headers['x-hasura-admin-secret'] = adminSecret
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
import fs from 'fs'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
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 file = fs.createReadStream('./tests/assets/sample.pdf')
|
||||
|
||||
const { fileMetadata } = await storage.upload({
|
||||
formData: fd
|
||||
file: file as unknown as File
|
||||
})
|
||||
|
||||
const { error } = await storage.delete({
|
||||
|
||||
@@ -38,11 +38,10 @@ describe('test upload', () => {
|
||||
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 file = fs.createReadStream('./tests/assets/sample.pdf')
|
||||
|
||||
const { fileMetadata, error } = await storage.upload({
|
||||
formData: fd,
|
||||
file: file as unknown as File,
|
||||
id: RANDOM_UUID
|
||||
})
|
||||
|
||||
@@ -50,8 +49,7 @@ describe('test upload', () => {
|
||||
throw new Error('fileMetadata is missing')
|
||||
}
|
||||
|
||||
const { id: fileId } =
|
||||
'processedFiles' in fileMetadata ? fileMetadata.processedFiles[0] : fileMetadata
|
||||
const { id: fileId } = fileMetadata
|
||||
|
||||
expect(error).toBeNull()
|
||||
expect(fileId).toBe(RANDOM_UUID)
|
||||
@@ -60,11 +58,10 @@ describe('test upload', () => {
|
||||
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 file = fs.createReadStream('./tests/assets/sample.pdf')
|
||||
|
||||
const { fileMetadata, error } = await storage.upload({
|
||||
formData: fd,
|
||||
file: file as unknown as File,
|
||||
name: FILE_NAME
|
||||
})
|
||||
|
||||
@@ -72,19 +69,17 @@ describe('test upload', () => {
|
||||
throw new Error('fileMetadata is missing')
|
||||
}
|
||||
|
||||
const { name: fileName } =
|
||||
'processedFiles' in fileMetadata ? fileMetadata.processedFiles[0] : fileMetadata
|
||||
const { name: fileName } = fileMetadata
|
||||
|
||||
expect(error).toBeNull()
|
||||
expect(fileName).toBe(FILE_NAME)
|
||||
})
|
||||
|
||||
it('should upload a file with a non-ISO 8859-1 name', async () => {
|
||||
const fd = new FormData()
|
||||
fd.append('file', fs.createReadStream('./tests/assets/sample.pdf'))
|
||||
const file = fs.createReadStream('./tests/assets/sample.pdf')
|
||||
|
||||
const { fileMetadata, error } = await storage.upload({
|
||||
formData: fd,
|
||||
file: file as unknown as File,
|
||||
name: '你 好'
|
||||
})
|
||||
|
||||
@@ -92,8 +87,7 @@ describe('test upload', () => {
|
||||
throw new Error('fileMetadata is missing')
|
||||
}
|
||||
|
||||
const { name: fileName } =
|
||||
'processedFiles' in fileMetadata ? fileMetadata.processedFiles[0] : fileMetadata
|
||||
const { name: fileName } = fileMetadata
|
||||
|
||||
expect(error).toBeNull()
|
||||
expect(fileName).toMatchInlineSnapshot('"%E4%BD%A0%20%E5%A5%BD"')
|
||||
@@ -103,11 +97,10 @@ describe('test upload', () => {
|
||||
const RANDOM_UUID = uuidv4()
|
||||
const FILE_NAME = 'special-name.pdf'
|
||||
|
||||
const fd = new FormData()
|
||||
fd.append('file', fs.createReadStream('./tests/assets/sample.pdf'))
|
||||
const file = fs.createReadStream('./tests/assets/sample.pdf')
|
||||
|
||||
const { fileMetadata, error } = await storage.upload({
|
||||
formData: fd,
|
||||
file: file as unknown as File,
|
||||
id: RANDOM_UUID,
|
||||
name: FILE_NAME
|
||||
})
|
||||
@@ -116,8 +109,7 @@ describe('test upload', () => {
|
||||
throw new Error('fileMetadata is missing')
|
||||
}
|
||||
|
||||
const { id: fileId, name: fileName } =
|
||||
'processedFiles' in fileMetadata ? fileMetadata.processedFiles[0] : fileMetadata
|
||||
const { id: fileId, name: fileName } = fileMetadata
|
||||
|
||||
expect(error).toBeNull()
|
||||
expect(fileId).toBe(RANDOM_UUID)
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
# @nhost/nextjs
|
||||
|
||||
## 1.13.34
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@2.0.28
|
||||
|
||||
## 1.13.33
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@2.0.27
|
||||
|
||||
## 1.13.32
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@2.0.26
|
||||
|
||||
## 1.13.31
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/nextjs",
|
||||
"version": "1.13.31",
|
||||
"version": "1.13.34",
|
||||
"description": "Nhost NextJS library",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
HASURA_GRAPHQL_ADMIN_SECRET=nhost-admin-secret
|
||||
HASURA_GRAPHQL_JWT_SECRET=oqpdwyffgxncqamwlyebkaifyazvqgso
|
||||
NHOST_WEBHOOK_SECRET=nhost-webhook-secret
|
||||
GRAFANA_ADMIN_PASSWORD=FIXME
|
||||
HASURA_GRAPHQL_ADMIN_SECRET='nhost-admin-secret'
|
||||
HASURA_GRAPHQL_JWT_SECRET='oqpdwyffgxncqamwlyebkaifyazvqgso'
|
||||
NHOST_WEBHOOK_SECRET='nhost-webhook-secret'
|
||||
GRAFANA_ADMIN_PASSWORD='FIXME'
|
||||
|
||||
@@ -1,5 +1,26 @@
|
||||
# @nhost/nhost-js
|
||||
|
||||
## 2.2.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [300e3f49e]
|
||||
- @nhost/hasura-storage-js@2.2.2
|
||||
|
||||
## 2.2.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [d54e4cdd4]
|
||||
- @nhost/hasura-storage-js@2.2.1
|
||||
|
||||
## 2.2.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [2cdb13b3e]
|
||||
- @nhost/hasura-storage-js@2.2.0
|
||||
|
||||
## 2.2.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/nhost-js",
|
||||
"version": "2.2.10",
|
||||
"version": "2.2.13",
|
||||
"description": "Nhost JavaScript SDK",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
# @nhost/react
|
||||
|
||||
## 2.0.28
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@2.2.13
|
||||
|
||||
## 2.0.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@2.2.12
|
||||
|
||||
## 2.0.26
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@2.2.11
|
||||
|
||||
## 2.0.25
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/react",
|
||||
"version": "2.0.25",
|
||||
"version": "2.0.28",
|
||||
"description": "Nhost React library",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
# @nhost/vue
|
||||
|
||||
## 1.13.33
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@2.2.13
|
||||
|
||||
## 1.13.32
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@2.2.12
|
||||
|
||||
## 1.13.31
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@2.2.11
|
||||
|
||||
## 1.13.30
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/vue",
|
||||
"version": "1.13.30",
|
||||
"version": "1.13.33",
|
||||
"description": "Nhost Vue library",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user