diff --git a/.changeset/eleven-experts-rule.md b/.changeset/eleven-experts-rule.md new file mode 100644 index 0000000000..4486e9140e --- /dev/null +++ b/.changeset/eleven-experts-rule.md @@ -0,0 +1,9 @@ +--- +'@nhost/hasura-auth-js': minor +'@nhost-examples/react-apollo': minor +'@nhost-examples/vue-apollo': minor +'@nhost/react': minor +'@nhost/vue': minor +--- + +feat: add 'elevateEmailSecurityKey' to the SDKs along with integration into react-apollo and vue-apollo examples diff --git a/.changeset/spicy-ducks-dress.md b/.changeset/spicy-ducks-dress.md new file mode 100644 index 0000000000..0fc882e751 --- /dev/null +++ b/.changeset/spicy-ducks-dress.md @@ -0,0 +1,7 @@ +--- +'@nhost-examples/nextjs-server-components': minor +'@nhost/hasura-storage-js': minor +'@nhost/docs': minor +--- + +feat: Add support for authenticated download of files diff --git a/docs/guides/ai/local-development.mdx b/docs/guides/ai/local-development.mdx new file mode 100644 index 0000000000..226c5d7d99 --- /dev/null +++ b/docs/guides/ai/local-development.mdx @@ -0,0 +1,45 @@ +--- +title: "Local Development" +icon: code +--- + +If you are using the Nhost CLI for local development, as of [v0.12.0](https://github.com/nhost/cli/releases/tag/v1.12.0) you can also start Graphite locally. To do so, follow the next steps: + + + + + + Follow the steps highlighed in the ["Enabling Service"](enabling-service) guide and don't forget to add the relevant secrets to your `.secrets` file. + + + Run `nhost up`: + + ![nhost up](/images/guides/ai/local-development/nhost_up.png) + + After starting the service the first thing you will notice is that there is a new `ai` service running. + + + As you start the AI service metadata changes may be proposed: + + ![git status](/images/guides/ai/local-development/git_status.png) + + We strongly recommmend you to commit them to your git repository so they can be deployed alongside your application. + + + + +### Synhcronizing Auto-Embeddings + +If you add [auto-embeddings](/guides/ai/auto-embeddings) configuration locally and want to synchronize them with the cloud we recommend inserting them using a migration rather than with the auto-embeddings UI: + +![migration](/images/guides/ai/local-development/migration.png) + +And then running `nhost up` to download the updated metadata. Afterwards you should see both database migrations and functions' metadata changes in your local project: + +![git status](/images/guides/ai/local-development/git_status_functions.png) + +Pushing them to your deployment branch will also deploy them to your cloud project. + +### Synhcronizing Assistants + +Similar to auto-embeddings, if you want to synchronize [assistants](/guides/ai/assistants) we recommend you to insert them using a migration and then running `nhost up` to update any metadata if necessary. After pushing the proposed changes to the deployment branch all the changes should be deployed to the cloud project. diff --git a/docs/images/guides/ai/local-development/git_status.png b/docs/images/guides/ai/local-development/git_status.png new file mode 100644 index 0000000000..24524f0001 Binary files /dev/null and b/docs/images/guides/ai/local-development/git_status.png differ diff --git a/docs/images/guides/ai/local-development/git_status_functions.png b/docs/images/guides/ai/local-development/git_status_functions.png new file mode 100644 index 0000000000..52b8b7ad0e Binary files /dev/null and b/docs/images/guides/ai/local-development/git_status_functions.png differ diff --git a/docs/images/guides/ai/local-development/migration.png b/docs/images/guides/ai/local-development/migration.png new file mode 100644 index 0000000000..34fdff9f29 Binary files /dev/null and b/docs/images/guides/ai/local-development/migration.png differ diff --git a/docs/images/guides/ai/local-development/nhost_up.png b/docs/images/guides/ai/local-development/nhost_up.png new file mode 100644 index 0000000000..1f903b2a26 Binary files /dev/null and b/docs/images/guides/ai/local-development/nhost_up.png differ diff --git a/docs/mint.json b/docs/mint.json index 3b85c409ba..50953b9ce0 100644 --- a/docs/mint.json +++ b/docs/mint.json @@ -102,7 +102,7 @@ "group": "AI", "pages": [ "guides/ai/enabling-service", - "guides/ai/local_development", + "guides/ai/local-development", "guides/ai/auto-embeddings", "guides/ai/assistants", "guides/ai/dev-assistant" @@ -319,12 +319,13 @@ "group": "Storage", "pages": [ "reference/javascript/storage/hasura-storage-client", - "reference/javascript/storage/delete", + "reference/javascript/storage/upload", + "reference/javascript/storage/download", "reference/javascript/storage/get-presigned-url", "reference/javascript/storage/get-public-url", + "reference/javascript/storage/delete", "reference/javascript/storage/set-access-token", - "reference/javascript/storage/set-admin-secret", - "reference/javascript/storage/upload" + "reference/javascript/storage/set-admin-secret" ] }, { diff --git a/docs/reference/javascript/storage/download.mdx b/docs/reference/javascript/storage/download.mdx new file mode 100644 index 0000000000..341299e3af --- /dev/null +++ b/docs/reference/javascript/storage/download.mdx @@ -0,0 +1,27 @@ +--- +title: download() +sidebarTitle: download() +--- + +Use `nhost.storage.download` to download a file. To download a file the user must have permission to select the file in the `storage.files` table. + +```ts +const { file, error } = await nhost.storage.download({ fileId: '' }) +``` + +## Parameters + +--- + +**params** required [`StorageDownloadFileParams`](/reference/javascript/storage/types/storage-download-file-params) + +| Property | Type | Required | Notes | +| :----------------------------------------------------------------------------------------- | :---------------------------------------- | :------: | :----------------------------------------------------------- | +| params.fileId | string | ✔️ | | +| params.blur | number | | Image blur, between 0 and 100 | +| params.quality | number | | Image quality, between 1 and 100, 100 being the best quality | +| params.height | number | | Image height, in pixels | +| params.width | number | | Image width, in pixels | +| params.headers | Record<string, string> | | Optional headers to be sent with the request | + +--- diff --git a/docs/reference/javascript/storage/types/storage-download-file-params.mdx b/docs/reference/javascript/storage/types/storage-download-file-params.mdx new file mode 100644 index 0000000000..0a2312f44a --- /dev/null +++ b/docs/reference/javascript/storage/types/storage-download-file-params.mdx @@ -0,0 +1,45 @@ +--- +title: StorageDownloadFileParams +sidebarTitle: StorageDownloadFileParams +description: No description provided. +--- + +# `StorageDownloadFileParams` + +## Parameters + +--- + +**fileId** required string + +--- + +**blur** optional number + +Image blur, between 0 and 100 + +--- + +**quality** optional number + +Image quality, between 1 and 100, 100 being the best quality + +--- + +**height** optional number + +Image height, in pixels + +--- + +**width** optional number + +Image width, in pixels + +--- + +**headers** optional Record<string, string> + +Optional headers to be sent with the request + +--- diff --git a/docs/reference/javascript/storage/types/storage-download-file-response.mdx b/docs/reference/javascript/storage/types/storage-download-file-response.mdx new file mode 100644 index 0000000000..1962d71853 --- /dev/null +++ b/docs/reference/javascript/storage/types/storage-download-file-response.mdx @@ -0,0 +1,13 @@ +--- +title: StorageDownloadFileResponse +sidebarTitle: StorageDownloadFileResponse +description: No description provided. +--- + +# `StorageDownloadFileResponse` + +```ts +type StorageDownloadFileResponse = + | { file: Blob; error: null } + | { file: null; error: Error } +``` diff --git a/examples/quickstarts/nextjs-server-components/src/components/input.tsx b/examples/quickstarts/nextjs-server-components/src/components/input.tsx index ba4111d257..51dd76f04a 100644 --- a/examples/quickstarts/nextjs-server-components/src/components/input.tsx +++ b/examples/quickstarts/nextjs-server-components/src/components/input.tsx @@ -2,7 +2,7 @@ import { DetailedHTMLProps, HTMLProps } from 'react' // @ts-ignore -import { experimental_useFormStatus as useFormStatus } from 'react-dom' +import { useFormStatus } from 'react-dom' export default function Input({ id, diff --git a/examples/quickstarts/nextjs-server-components/src/components/submit-button.tsx b/examples/quickstarts/nextjs-server-components/src/components/submit-button.tsx index 137c2ff432..6603b92f9e 100644 --- a/examples/quickstarts/nextjs-server-components/src/components/submit-button.tsx +++ b/examples/quickstarts/nextjs-server-components/src/components/submit-button.tsx @@ -2,12 +2,12 @@ import { ButtonHTMLAttributes, DetailedHTMLProps } from 'react' // @ts-ignore -import { experimental_useFormStatus as useFormStatus } from 'react-dom' +import { useFormStatus } from 'react-dom' import { twMerge } from 'tailwind-merge' type ButtonProps = { - type?: 'button' | 'submit' | 'reset' | undefined; -} & DetailedHTMLProps, HTMLButtonElement>; + type?: 'button' | 'submit' | 'reset' | undefined +} & DetailedHTMLProps, HTMLButtonElement> export default function SubmitButton({ disabled, @@ -16,7 +16,7 @@ export default function SubmitButton({ children, ...rest }: ButtonProps) { - const { pending } = useFormStatus(); + const { pending } = useFormStatus() return ( - ); -} \ No newline at end of file + ) +} diff --git a/examples/quickstarts/nextjs-server-components/src/components/todo-item.tsx b/examples/quickstarts/nextjs-server-components/src/components/todo-item.tsx index 4d0ec172bb..453ea366d8 100644 --- a/examples/quickstarts/nextjs-server-components/src/components/todo-item.tsx +++ b/examples/quickstarts/nextjs-server-components/src/components/todo-item.tsx @@ -32,6 +32,20 @@ const TodoItem = ({ todo }: { todo: Todo }) => { await deleteTodo(todo.id) } + const handleDownloadAttachment = async () => { + if (todo.attachment) { + const response = await nhost.storage.download({ fileId: todo.attachment.id }) + if (response.file) { + const url = window.URL.createObjectURL(response.file) + const a = document.createElement('a') + a.href = url + a.download = todo.title + a.click() + window.URL.revokeObjectURL(url) + } + } + } + return (
{ )} + + + + + + Secret Notes + + + e.code === 'Enter' && add()} + /> + + + + + +
    + {data?.notes.map((note) => ( +
  • + + {note.content} + { + event.preventDefault() + deleteNote(note.id) + }} + > + + + +
  • + ))} +
+
+ + ) +} diff --git a/examples/react-apollo/src/generated.ts b/examples/react-apollo/src/generated.ts index 60640f5d37..3518e4123d 100644 --- a/examples/react-apollo/src/generated.ts +++ b/examples/react-apollo/src/generated.ts @@ -75,6 +75,132 @@ export type StringComparisonExp = { _similar?: InputMaybe; }; +export enum AuthRefreshTokenTypesEnum { + /** Personal access token */ + Pat = 'pat', + /** Regular refresh token */ + Regular = 'regular' +} + +/** Boolean expression to compare columns of type "authRefreshTokenTypes_enum". All fields are combined with logical 'AND'. */ +export type AuthRefreshTokenTypesEnumComparisonExp = { + _eq?: InputMaybe; + _in?: InputMaybe>; + _is_null?: InputMaybe; + _neq?: InputMaybe; + _nin?: InputMaybe>; +}; + +/** User refresh tokens. Hasura auth uses them to rotate new access tokens as long as the refresh token is not expired. Don't modify its structure as Hasura Auth relies on it to function properly. */ +export type AuthRefreshTokens = { + __typename?: 'authRefreshTokens'; + createdAt: Scalars['timestamptz']; + expiresAt: Scalars['timestamptz']; + id: Scalars['uuid']; + metadata?: Maybe; + type: AuthRefreshTokenTypesEnum; + /** An object relationship */ + user: Users; + userId: Scalars['uuid']; +}; + + +/** User refresh tokens. Hasura auth uses them to rotate new access tokens as long as the refresh token is not expired. Don't modify its structure as Hasura Auth relies on it to function properly. */ +export type AuthRefreshTokensMetadataArgs = { + path?: InputMaybe; +}; + +/** order by aggregate values of table "auth.refresh_tokens" */ +export type AuthRefreshTokensAggregateOrderBy = { + count?: InputMaybe; + max?: InputMaybe; + min?: InputMaybe; +}; + +/** Boolean expression to filter rows from the table "auth.refresh_tokens". All fields are combined with a logical 'AND'. */ +export type AuthRefreshTokensBoolExp = { + _and?: InputMaybe>; + _not?: InputMaybe; + _or?: InputMaybe>; + createdAt?: InputMaybe; + expiresAt?: InputMaybe; + id?: InputMaybe; + metadata?: InputMaybe; + type?: InputMaybe; + user?: InputMaybe; + userId?: InputMaybe; +}; + +/** order by max() on columns of table "auth.refresh_tokens" */ +export type AuthRefreshTokensMaxOrderBy = { + createdAt?: InputMaybe; + expiresAt?: InputMaybe; + id?: InputMaybe; + userId?: InputMaybe; +}; + +/** order by min() on columns of table "auth.refresh_tokens" */ +export type AuthRefreshTokensMinOrderBy = { + createdAt?: InputMaybe; + expiresAt?: InputMaybe; + id?: InputMaybe; + userId?: InputMaybe; +}; + +/** response of any mutation on the table "auth.refresh_tokens" */ +export type AuthRefreshTokensMutationResponse = { + __typename?: 'authRefreshTokens_mutation_response'; + /** number of rows affected by the mutation */ + affected_rows: Scalars['Int']; + /** data from the rows affected by the mutation */ + returning: Array; +}; + +/** Ordering options when selecting data from "auth.refresh_tokens". */ +export type AuthRefreshTokensOrderBy = { + createdAt?: InputMaybe; + expiresAt?: InputMaybe; + id?: InputMaybe; + metadata?: InputMaybe; + type?: InputMaybe; + user?: InputMaybe; + userId?: InputMaybe; +}; + +/** select columns of table "auth.refresh_tokens" */ +export enum AuthRefreshTokensSelectColumn { + /** column name */ + CreatedAt = 'createdAt', + /** column name */ + ExpiresAt = 'expiresAt', + /** column name */ + Id = 'id', + /** column name */ + Metadata = 'metadata', + /** column name */ + Type = 'type', + /** column name */ + UserId = 'userId' +} + +/** Streaming cursor of the table "authRefreshTokens" */ +export type AuthRefreshTokensStreamCursorInput = { + /** Stream column input with initial value */ + initial_value: AuthRefreshTokensStreamCursorValueInput; + /** cursor ordering */ + ordering?: InputMaybe; +}; + +/** Initial value of the column from where the streaming should start */ +export type AuthRefreshTokensStreamCursorValueInput = { + createdAt?: InputMaybe; + expiresAt?: InputMaybe; + id?: InputMaybe; + metadata?: InputMaybe; + type?: InputMaybe; + userId?: InputMaybe; +}; + /** User webauthn security keys. Don't modify its structure as Hasura Auth relies on it to function properly. */ export type AuthUserSecurityKeys = { __typename?: 'authUserSecurityKeys'; @@ -144,6 +270,21 @@ export enum AuthUserSecurityKeysSelectColumn { UserId = 'userId' } +/** Streaming cursor of the table "authUserSecurityKeys" */ +export type AuthUserSecurityKeysStreamCursorInput = { + /** Stream column input with initial value */ + initial_value: AuthUserSecurityKeysStreamCursorValueInput; + /** cursor ordering */ + ordering?: InputMaybe; +}; + +/** Initial value of the column from where the streaming should start */ +export type AuthUserSecurityKeysStreamCursorValueInput = { + id?: InputMaybe; + nickname?: InputMaybe; + userId?: InputMaybe; +}; + /** Boolean expression to compare columns of type "citext". All fields are combined with logical 'AND'. */ export type CitextComparisonExp = { _eq?: InputMaybe; @@ -177,6 +318,14 @@ export type CitextComparisonExp = { _similar?: InputMaybe; }; +/** ordering argument of a cursor */ +export enum CursorOrdering { + /** ascending ordering of the cursor */ + Asc = 'ASC', + /** descending ordering of the cursor */ + Desc = 'DESC' +} + /** columns and relationships of "storage.files" */ export type Files = { __typename?: 'files'; @@ -264,7 +413,7 @@ export type FilesOrderBy = { uploadedByUserId?: InputMaybe; }; -/** primary key columns input for table: files */ +/** primary key columns input for table: storage.files */ export type FilesPkColumnsInput = { id: Scalars['uuid']; }; @@ -307,6 +456,28 @@ export type FilesSetInput = { uploadedByUserId?: InputMaybe; }; +/** Streaming cursor of the table "files" */ +export type FilesStreamCursorInput = { + /** Stream column input with initial value */ + initial_value: FilesStreamCursorValueInput; + /** cursor ordering */ + ordering?: InputMaybe; +}; + +/** Initial value of the column from where the streaming should start */ +export type FilesStreamCursorValueInput = { + bucketId?: InputMaybe; + createdAt?: InputMaybe; + etag?: InputMaybe; + id?: InputMaybe; + isUploaded?: InputMaybe; + mimeType?: InputMaybe; + name?: InputMaybe; + size?: InputMaybe; + updatedAt?: InputMaybe; + uploadedByUserId?: InputMaybe; +}; + /** update columns of table "storage.files" */ export enum FilesUpdateColumn { /** column name */ @@ -336,6 +507,7 @@ export type FilesUpdates = { _inc?: InputMaybe; /** sets the columns of the filtered rows to the given values */ _set?: InputMaybe; + /** filter the rows which have to be updated */ where: FilesBoolExp; }; @@ -370,6 +542,10 @@ export type JsonbComparisonExp = { /** mutation root */ export type MutationRoot = { __typename?: 'mutation_root'; + /** delete single row from the table: "auth.refresh_tokens" */ + deleteAuthRefreshToken?: Maybe; + /** delete data from the table: "auth.refresh_tokens" */ + deleteAuthRefreshTokens?: Maybe; /** delete single row from the table: "auth.user_security_keys" */ deleteAuthUserSecurityKey?: Maybe; /** delete data from the table: "auth.user_security_keys" */ @@ -378,14 +554,22 @@ export type MutationRoot = { deleteFile?: Maybe; /** delete data from the table: "storage.files" */ deleteFiles?: Maybe; + /** delete single row from the table: "notes" */ + deleteNote?: Maybe; + /** delete data from the table: "notes" */ + deleteNotes?: Maybe; /** delete single row from the table: "todos" */ deleteTodo?: Maybe; /** delete data from the table: "todos" */ deleteTodos?: Maybe; + /** insert data into the table: "notes" */ + inserNotes?: Maybe; /** insert a single row into the table: "storage.files" */ insertFile?: Maybe; /** insert data into the table: "storage.files" */ insertFiles?: Maybe; + /** insert a single row into the table: "notes" */ + insertNote?: Maybe; /** insert a single row into the table: "todos" */ insertTodo?: Maybe; /** insert data into the table: "todos" */ @@ -394,17 +578,35 @@ export type MutationRoot = { updateFile?: Maybe; /** update data of the table: "storage.files" */ updateFiles?: Maybe; + /** update single row of the table: "notes" */ + updateNote?: Maybe; + /** update data of the table: "notes" */ + updateNotes?: Maybe; /** update single row of the table: "todos" */ updateTodo?: Maybe; /** update data of the table: "todos" */ updateTodos?: Maybe; /** update multiples rows of table: "storage.files" */ update_files_many?: Maybe>>; + /** update multiples rows of table: "notes" */ + update_notes_many?: Maybe>>; /** update multiples rows of table: "todos" */ update_todos_many?: Maybe>>; }; +/** mutation root */ +export type MutationRootDeleteAuthRefreshTokenArgs = { + id: Scalars['uuid']; +}; + + +/** mutation root */ +export type MutationRootDeleteAuthRefreshTokensArgs = { + where: AuthRefreshTokensBoolExp; +}; + + /** mutation root */ export type MutationRootDeleteAuthUserSecurityKeyArgs = { id: Scalars['uuid']; @@ -429,6 +631,18 @@ export type MutationRootDeleteFilesArgs = { }; +/** mutation root */ +export type MutationRootDeleteNoteArgs = { + id: Scalars['uuid']; +}; + + +/** mutation root */ +export type MutationRootDeleteNotesArgs = { + where: NotesBoolExp; +}; + + /** mutation root */ export type MutationRootDeleteTodoArgs = { id: Scalars['uuid']; @@ -441,6 +655,13 @@ export type MutationRootDeleteTodosArgs = { }; +/** mutation root */ +export type MutationRootInserNotesArgs = { + objects: Array; + on_conflict?: InputMaybe; +}; + + /** mutation root */ export type MutationRootInsertFileArgs = { object: FilesInsertInput; @@ -455,6 +676,13 @@ export type MutationRootInsertFilesArgs = { }; +/** mutation root */ +export type MutationRootInsertNoteArgs = { + object: NotesInsertInput; + on_conflict?: InputMaybe; +}; + + /** mutation root */ export type MutationRootInsertTodoArgs = { object: TodosInsertInput; @@ -485,6 +713,20 @@ export type MutationRootUpdateFilesArgs = { }; +/** mutation root */ +export type MutationRootUpdateNoteArgs = { + _set?: InputMaybe; + pk_columns: NotesPkColumnsInput; +}; + + +/** mutation root */ +export type MutationRootUpdateNotesArgs = { + _set?: InputMaybe; + where: NotesBoolExp; +}; + + /** mutation root */ export type MutationRootUpdateTodoArgs = { _set?: InputMaybe; @@ -505,11 +747,167 @@ export type MutationRootUpdateFilesManyArgs = { }; +/** mutation root */ +export type MutationRootUpdateNotesManyArgs = { + updates: Array; +}; + + /** mutation root */ export type MutationRootUpdateTodosManyArgs = { updates: Array; }; +/** columns and relationships of "notes" */ +export type Notes = { + __typename?: 'notes'; + content: Scalars['String']; + createdAt: Scalars['timestamptz']; + id: Scalars['uuid']; + updatedAt: Scalars['timestamptz']; + /** An object relationship */ + user: Users; +}; + +/** aggregated selection of "notes" */ +export type NotesAggregate = { + __typename?: 'notes_aggregate'; + aggregate?: Maybe; + nodes: Array; +}; + +/** aggregate fields of "notes" */ +export type NotesAggregateFields = { + __typename?: 'notes_aggregate_fields'; + count: Scalars['Int']; + max?: Maybe; + min?: Maybe; +}; + + +/** aggregate fields of "notes" */ +export type NotesAggregateFieldsCountArgs = { + columns?: InputMaybe>; + distinct?: InputMaybe; +}; + +/** Boolean expression to filter rows from the table "notes". All fields are combined with a logical 'AND'. */ +export type NotesBoolExp = { + _and?: InputMaybe>; + _not?: InputMaybe; + _or?: InputMaybe>; + content?: InputMaybe; + createdAt?: InputMaybe; + id?: InputMaybe; + updatedAt?: InputMaybe; + user?: InputMaybe; +}; + +/** unique or primary key constraints on table "notes" */ +export enum NotesConstraint { + /** unique or primary key constraint on columns "id" */ + NotesPkey = 'notes_pkey' +} + +/** input type for inserting data into table "notes" */ +export type NotesInsertInput = { + content?: InputMaybe; +}; + +/** aggregate max on columns */ +export type NotesMaxFields = { + __typename?: 'notes_max_fields'; + content?: Maybe; + createdAt?: Maybe; + id?: Maybe; + updatedAt?: Maybe; +}; + +/** aggregate min on columns */ +export type NotesMinFields = { + __typename?: 'notes_min_fields'; + content?: Maybe; + createdAt?: Maybe; + id?: Maybe; + updatedAt?: Maybe; +}; + +/** response of any mutation on the table "notes" */ +export type NotesMutationResponse = { + __typename?: 'notes_mutation_response'; + /** number of rows affected by the mutation */ + affected_rows: Scalars['Int']; + /** data from the rows affected by the mutation */ + returning: Array; +}; + +/** on_conflict condition type for table "notes" */ +export type NotesOnConflict = { + constraint: NotesConstraint; + update_columns?: Array; + where?: InputMaybe; +}; + +/** Ordering options when selecting data from "notes". */ +export type NotesOrderBy = { + content?: InputMaybe; + createdAt?: InputMaybe; + id?: InputMaybe; + updatedAt?: InputMaybe; + user?: InputMaybe; +}; + +/** primary key columns input for table: notes */ +export type NotesPkColumnsInput = { + id: Scalars['uuid']; +}; + +/** select columns of table "notes" */ +export enum NotesSelectColumn { + /** column name */ + Content = 'content', + /** column name */ + CreatedAt = 'createdAt', + /** column name */ + Id = 'id', + /** column name */ + UpdatedAt = 'updatedAt' +} + +/** input type for updating data in table "notes" */ +export type NotesSetInput = { + content?: InputMaybe; +}; + +/** Streaming cursor of the table "notes" */ +export type NotesStreamCursorInput = { + /** Stream column input with initial value */ + initial_value: NotesStreamCursorValueInput; + /** cursor ordering */ + ordering?: InputMaybe; +}; + +/** Initial value of the column from where the streaming should start */ +export type NotesStreamCursorValueInput = { + content?: InputMaybe; + createdAt?: InputMaybe; + id?: InputMaybe; + updatedAt?: InputMaybe; +}; + +/** update columns of table "notes" */ +export enum NotesUpdateColumn { + /** column name */ + Content = 'content' +} + +export type NotesUpdates = { + /** sets the columns of the filtered rows to the given values */ + _set?: InputMaybe; + /** filter the rows which have to be updated */ + where: NotesBoolExp; +}; + /** column ordering options */ export enum OrderBy { /** in ascending order, nulls last */ @@ -528,6 +926,10 @@ export enum OrderBy { export type QueryRoot = { __typename?: 'query_root'; + /** fetch data from the table: "auth.refresh_tokens" using primary key columns */ + authRefreshToken?: Maybe; + /** fetch data from the table: "auth.refresh_tokens" */ + authRefreshTokens: Array; /** fetch data from the table: "auth.user_security_keys" using primary key columns */ authUserSecurityKey?: Maybe; /** fetch data from the table: "auth.user_security_keys" */ @@ -536,6 +938,12 @@ export type QueryRoot = { file?: Maybe; /** fetch data from the table: "storage.files" */ files: Array; + /** fetch data from the table: "notes" using primary key columns */ + note?: Maybe; + /** fetch data from the table: "notes" */ + notes: Array; + /** fetch aggregated fields from the table: "notes" */ + notesAggregate: NotesAggregate; /** fetch data from the table: "todos" using primary key columns */ todo?: Maybe; /** fetch data from the table: "todos" */ @@ -549,6 +957,20 @@ export type QueryRoot = { }; +export type QueryRootAuthRefreshTokenArgs = { + id: Scalars['uuid']; +}; + + +export type QueryRootAuthRefreshTokensArgs = { + distinct_on?: InputMaybe>; + limit?: InputMaybe; + offset?: InputMaybe; + order_by?: InputMaybe>; + where?: InputMaybe; +}; + + export type QueryRootAuthUserSecurityKeyArgs = { id: Scalars['uuid']; }; @@ -577,6 +999,29 @@ export type QueryRootFilesArgs = { }; +export type QueryRootNoteArgs = { + id: Scalars['uuid']; +}; + + +export type QueryRootNotesArgs = { + distinct_on?: InputMaybe>; + limit?: InputMaybe; + offset?: InputMaybe; + order_by?: InputMaybe>; + where?: InputMaybe; +}; + + +export type QueryRootNotesAggregateArgs = { + distinct_on?: InputMaybe>; + limit?: InputMaybe; + offset?: InputMaybe; + order_by?: InputMaybe>; + where?: InputMaybe; +}; + + export type QueryRootTodoArgs = { id: Scalars['uuid']; }; @@ -615,24 +1060,67 @@ export type QueryRootUsersArgs = { export type SubscriptionRoot = { __typename?: 'subscription_root'; + /** fetch data from the table: "auth.refresh_tokens" using primary key columns */ + authRefreshToken?: Maybe; + /** fetch data from the table: "auth.refresh_tokens" */ + authRefreshTokens: Array; + /** fetch data from the table in a streaming manner: "auth.refresh_tokens" */ + authRefreshTokens_stream: Array; /** fetch data from the table: "auth.user_security_keys" using primary key columns */ authUserSecurityKey?: Maybe; /** fetch data from the table: "auth.user_security_keys" */ authUserSecurityKeys: Array; + /** fetch data from the table in a streaming manner: "auth.user_security_keys" */ + authUserSecurityKeys_stream: Array; /** fetch data from the table: "storage.files" using primary key columns */ file?: Maybe; /** fetch data from the table: "storage.files" */ files: Array; + /** fetch data from the table in a streaming manner: "storage.files" */ + files_stream: Array; + /** fetch data from the table: "notes" using primary key columns */ + note?: Maybe; + /** fetch data from the table: "notes" */ + notes: Array; + /** fetch aggregated fields from the table: "notes" */ + notesAggregate: NotesAggregate; + /** fetch data from the table in a streaming manner: "notes" */ + notes_stream: Array; /** fetch data from the table: "todos" using primary key columns */ todo?: Maybe; /** fetch data from the table: "todos" */ todos: Array; /** fetch aggregated fields from the table: "todos" */ todosAggregate: TodosAggregate; + /** fetch data from the table in a streaming manner: "todos" */ + todos_stream: Array; /** fetch data from the table: "auth.users" using primary key columns */ user?: Maybe; /** fetch data from the table: "auth.users" */ users: Array; + /** fetch data from the table in a streaming manner: "auth.users" */ + users_stream: Array; +}; + + +export type SubscriptionRootAuthRefreshTokenArgs = { + id: Scalars['uuid']; +}; + + +export type SubscriptionRootAuthRefreshTokensArgs = { + distinct_on?: InputMaybe>; + limit?: InputMaybe; + offset?: InputMaybe; + order_by?: InputMaybe>; + where?: InputMaybe; +}; + + +export type SubscriptionRootAuthRefreshTokensStreamArgs = { + batch_size: Scalars['Int']; + cursor: Array>; + where?: InputMaybe; }; @@ -650,6 +1138,13 @@ export type SubscriptionRootAuthUserSecurityKeysArgs = { }; +export type SubscriptionRootAuthUserSecurityKeysStreamArgs = { + batch_size: Scalars['Int']; + cursor: Array>; + where?: InputMaybe; +}; + + export type SubscriptionRootFileArgs = { id: Scalars['uuid']; }; @@ -664,6 +1159,43 @@ export type SubscriptionRootFilesArgs = { }; +export type SubscriptionRootFilesStreamArgs = { + batch_size: Scalars['Int']; + cursor: Array>; + where?: InputMaybe; +}; + + +export type SubscriptionRootNoteArgs = { + id: Scalars['uuid']; +}; + + +export type SubscriptionRootNotesArgs = { + distinct_on?: InputMaybe>; + limit?: InputMaybe; + offset?: InputMaybe; + order_by?: InputMaybe>; + where?: InputMaybe; +}; + + +export type SubscriptionRootNotesAggregateArgs = { + distinct_on?: InputMaybe>; + limit?: InputMaybe; + offset?: InputMaybe; + order_by?: InputMaybe>; + where?: InputMaybe; +}; + + +export type SubscriptionRootNotesStreamArgs = { + batch_size: Scalars['Int']; + cursor: Array>; + where?: InputMaybe; +}; + + export type SubscriptionRootTodoArgs = { id: Scalars['uuid']; }; @@ -687,6 +1219,13 @@ export type SubscriptionRootTodosAggregateArgs = { }; +export type SubscriptionRootTodosStreamArgs = { + batch_size: Scalars['Int']; + cursor: Array>; + where?: InputMaybe; +}; + + export type SubscriptionRootUserArgs = { id: Scalars['uuid']; }; @@ -700,6 +1239,13 @@ export type SubscriptionRootUsersArgs = { where?: InputMaybe; }; + +export type SubscriptionRootUsersStreamArgs = { + batch_size: Scalars['Int']; + cursor: Array>; + where?: InputMaybe; +}; + /** Boolean expression to compare columns of type "timestamptz". All fields are combined with logical 'AND'. */ export type TimestamptzComparisonExp = { _eq?: InputMaybe; @@ -842,6 +1388,23 @@ export type TodosSetInput = { contents?: InputMaybe; }; +/** Streaming cursor of the table "todos" */ +export type TodosStreamCursorInput = { + /** Stream column input with initial value */ + initial_value: TodosStreamCursorValueInput; + /** cursor ordering */ + ordering?: InputMaybe; +}; + +/** Initial value of the column from where the streaming should start */ +export type TodosStreamCursorValueInput = { + contents?: InputMaybe; + createdAt?: InputMaybe; + id?: InputMaybe; + updatedAt?: InputMaybe; + userId?: InputMaybe; +}; + /** update columns of table "todos" */ export enum TodosUpdateColumn { /** column name */ @@ -851,6 +1414,7 @@ export enum TodosUpdateColumn { export type TodosUpdates = { /** sets the columns of the filtered rows to the given values */ _set?: InputMaybe; + /** filter the rows which have to be updated */ where: TodosBoolExp; }; @@ -876,6 +1440,8 @@ export type Users = { phoneNumber?: Maybe; phoneNumberVerified: Scalars['Boolean']; /** An array relationship */ + refreshTokens: Array; + /** An array relationship */ securityKeys: Array; updatedAt: Scalars['timestamptz']; }; @@ -887,6 +1453,16 @@ export type UsersMetadataArgs = { }; +/** User account information. Don't modify its structure as Hasura Auth relies on it to function properly. */ +export type UsersRefreshTokensArgs = { + distinct_on?: InputMaybe>; + limit?: InputMaybe; + offset?: InputMaybe; + order_by?: InputMaybe>; + where?: InputMaybe; +}; + + /** User account information. Don't modify its structure as Hasura Auth relies on it to function properly. */ export type UsersSecurityKeysArgs = { distinct_on?: InputMaybe>; @@ -919,6 +1495,7 @@ export type UsersBoolExp = { otpMethodLastUsed?: InputMaybe; phoneNumber?: InputMaybe; phoneNumberVerified?: InputMaybe; + refreshTokens?: InputMaybe; securityKeys?: InputMaybe; updatedAt?: InputMaybe; }; @@ -943,6 +1520,7 @@ export type UsersOrderBy = { otpMethodLastUsed?: InputMaybe; phoneNumber?: InputMaybe; phoneNumberVerified?: InputMaybe; + refreshTokens_aggregate?: InputMaybe; securityKeys_aggregate?: InputMaybe; updatedAt?: InputMaybe; }; @@ -989,6 +1567,37 @@ export enum UsersSelectColumn { UpdatedAt = 'updatedAt' } +/** Streaming cursor of the table "users" */ +export type UsersStreamCursorInput = { + /** Stream column input with initial value */ + initial_value: UsersStreamCursorValueInput; + /** cursor ordering */ + ordering?: InputMaybe; +}; + +/** Initial value of the column from where the streaming should start */ +export type UsersStreamCursorValueInput = { + activeMfaType?: InputMaybe; + avatarUrl?: InputMaybe; + createdAt?: InputMaybe; + currentChallenge?: InputMaybe; + defaultRole?: InputMaybe; + disabled?: InputMaybe; + displayName?: InputMaybe; + email?: InputMaybe; + emailVerified?: InputMaybe; + id?: InputMaybe; + isAnonymous?: InputMaybe; + lastSeen?: InputMaybe; + locale?: InputMaybe; + metadata?: InputMaybe; + otpHash?: InputMaybe; + otpMethodLastUsed?: InputMaybe; + phoneNumber?: InputMaybe; + phoneNumberVerified?: InputMaybe; + updatedAt?: InputMaybe; +}; + /** Boolean expression to compare columns of type "uuid". All fields are combined with logical 'AND'. */ export type UuidComparisonExp = { _eq?: InputMaybe; @@ -1016,6 +1625,27 @@ export type AddItemMutation = { __typename?: 'mutation_root', insertTodo?: { __t export type NewTodoFragment = { __typename?: 'todos', id: string, contents: string }; +export type NotesListQueryVariables = Exact<{ [key: string]: never; }>; + + +export type NotesListQuery = { __typename?: 'query_root', notes: Array<{ __typename?: 'notes', id: string, content: string }> }; + +export type InsertNoteMutationVariables = Exact<{ + content: Scalars['String']; +}>; + + +export type InsertNoteMutation = { __typename?: 'mutation_root', insertNote?: { __typename?: 'notes', id: string, content: string } | null }; + +export type DeleteNoteMutationVariables = Exact<{ + noteId: Scalars['uuid']; +}>; + + +export type DeleteNoteMutation = { __typename?: 'mutation_root', deleteNote?: { __typename?: 'notes', id: string, content: string } | null }; + +export type NewNoteFragment = { __typename?: 'notes', id: string, content: string }; + export type SecurityKeysQueryVariables = Exact<{ userId: Scalars['uuid']; }>; diff --git a/examples/vue-apollo/nhost/metadata/backend_configs.yaml b/examples/vue-apollo/nhost/metadata/backend_configs.yaml new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/examples/vue-apollo/nhost/metadata/backend_configs.yaml @@ -0,0 +1 @@ +{} diff --git a/examples/vue-apollo/nhost/metadata/databases/default/tables/auth_provider_requests.yaml b/examples/vue-apollo/nhost/metadata/databases/default/tables/auth_provider_requests.yaml index 64243722ef..91ba1967d3 100644 --- a/examples/vue-apollo/nhost/metadata/databases/default/tables/auth_provider_requests.yaml +++ b/examples/vue-apollo/nhost/metadata/databases/default/tables/auth_provider_requests.yaml @@ -2,8 +2,14 @@ table: name: provider_requests schema: auth configuration: - column_config: {} - custom_column_names: {} + 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 diff --git a/examples/vue-apollo/nhost/metadata/databases/default/tables/auth_providers.yaml b/examples/vue-apollo/nhost/metadata/databases/default/tables/auth_providers.yaml index ddd89d52af..3de528dc92 100644 --- a/examples/vue-apollo/nhost/metadata/databases/default/tables/auth_providers.yaml +++ b/examples/vue-apollo/nhost/metadata/databases/default/tables/auth_providers.yaml @@ -2,8 +2,11 @@ table: name: providers schema: auth configuration: - column_config: {} - custom_column_names: {} + column_config: + id: + custom_name: id + custom_column_names: + id: id custom_name: authProviders custom_root_fields: delete: deleteAuthProviders diff --git a/examples/vue-apollo/nhost/metadata/databases/default/tables/auth_refresh_token_types.yaml b/examples/vue-apollo/nhost/metadata/databases/default/tables/auth_refresh_token_types.yaml new file mode 100644 index 0000000000..8abaa86046 --- /dev/null +++ b/examples/vue-apollo/nhost/metadata/databases/default/tables/auth_refresh_token_types.yaml @@ -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 diff --git a/examples/vue-apollo/nhost/metadata/databases/default/tables/auth_refresh_tokens.yaml b/examples/vue-apollo/nhost/metadata/databases/default/tables/auth_refresh_tokens.yaml index 8fbfaf82b6..2a332c4f2c 100644 --- a/examples/vue-apollo/nhost/metadata/databases/default/tables/auth_refresh_tokens.yaml +++ b/examples/vue-apollo/nhost/metadata/databases/default/tables/auth_refresh_tokens.yaml @@ -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 diff --git a/examples/vue-apollo/nhost/metadata/databases/default/tables/auth_roles.yaml b/examples/vue-apollo/nhost/metadata/databases/default/tables/auth_roles.yaml index 83df52fdb5..bc6d5a2cfb 100644 --- a/examples/vue-apollo/nhost/metadata/databases/default/tables/auth_roles.yaml +++ b/examples/vue-apollo/nhost/metadata/databases/default/tables/auth_roles.yaml @@ -2,8 +2,11 @@ table: name: roles schema: auth configuration: - column_config: {} - custom_column_names: {} + column_config: + role: + custom_name: role + custom_column_names: + role: role custom_name: authRoles custom_root_fields: delete: deleteAuthRoles diff --git a/examples/vue-apollo/nhost/metadata/databases/default/tables/auth_user_providers.yaml b/examples/vue-apollo/nhost/metadata/databases/default/tables/auth_user_providers.yaml index ed5407e6dc..02b8eb2da7 100644 --- a/examples/vue-apollo/nhost/metadata/databases/default/tables/auth_user_providers.yaml +++ b/examples/vue-apollo/nhost/metadata/databases/default/tables/auth_user_providers.yaml @@ -7,6 +7,8 @@ configuration: custom_name: accessToken created_at: custom_name: createdAt + id: + custom_name: id provider_id: custom_name: providerId provider_user_id: @@ -20,6 +22,7 @@ configuration: custom_column_names: access_token: accessToken created_at: createdAt + id: id provider_id: providerId provider_user_id: providerUserId refresh_token: refreshToken diff --git a/examples/vue-apollo/nhost/metadata/databases/default/tables/auth_user_roles.yaml b/examples/vue-apollo/nhost/metadata/databases/default/tables/auth_user_roles.yaml index c62f6e9463..f90553941e 100644 --- a/examples/vue-apollo/nhost/metadata/databases/default/tables/auth_user_roles.yaml +++ b/examples/vue-apollo/nhost/metadata/databases/default/tables/auth_user_roles.yaml @@ -5,10 +5,16 @@ 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: diff --git a/examples/vue-apollo/nhost/metadata/databases/default/tables/auth_user_security_keys.yaml b/examples/vue-apollo/nhost/metadata/databases/default/tables/auth_user_security_keys.yaml new file mode 100644 index 0000000000..9963b62342 --- /dev/null +++ b/examples/vue-apollo/nhost/metadata/databases/default/tables/auth_user_security_keys.yaml @@ -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 diff --git a/examples/vue-apollo/nhost/metadata/databases/default/tables/auth_users.yaml b/examples/vue-apollo/nhost/metadata/databases/default/tables/auth_users.yaml index 92ce48e90e..730001730a 100644 --- a/examples/vue-apollo/nhost/metadata/databases/default/tables/auth_users.yaml +++ b/examples/vue-apollo/nhost/metadata/databases/default/tables/auth_users.yaml @@ -11,14 +11,22 @@ configuration: 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: @@ -33,6 +41,8 @@ configuration: custom_name: phoneNumber phone_number_verified: custom_name: phoneNumberVerified + ticket: + custom_name: ticket ticket_expires_at: custom_name: ticketExpiresAt totp_secret: @@ -46,10 +56,14 @@ configuration: 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 @@ -57,6 +71,7 @@ configuration: password_hash: passwordHash phone_number: phoneNumber phone_number_verified: phoneNumberVerified + ticket: ticket ticket_expires_at: ticketExpiresAt totp_secret: totpSecret updated_at: updatedAt @@ -77,26 +92,26 @@ object_relationships: using: foreign_key_constraint_on: default_role array_relationships: - - name: authenticators + - name: refreshTokens using: foreign_key_constraint_on: column: user_id table: - name: user_authenticators + name: refresh_tokens schema: auth - - name: refreshTokens + - name: roles using: foreign_key_constraint_on: column: user_id table: - name: refresh_tokens + name: user_roles schema: auth - - name: roles + - name: securityKeys using: foreign_key_constraint_on: column: user_id table: - name: user_roles + name: user_security_keys schema: auth - name: userProviders using: diff --git a/examples/vue-apollo/nhost/metadata/databases/default/tables/public_notes.yaml b/examples/vue-apollo/nhost/metadata/databases/default/tables/public_notes.yaml new file mode 100644 index 0000000000..40b8f9a96a --- /dev/null +++ b/examples/vue-apollo/nhost/metadata/databases/default/tables/public_notes.yaml @@ -0,0 +1,58 @@ +table: + name: notes + schema: public +configuration: + column_config: {} + custom_column_names: {} + custom_root_fields: + delete: deleteNotes + delete_by_pk: deleteNote + insert: insertNotes + insert_one: insertNote + select: notes + select_aggregate: notesAggregate + select_by_pk: note + update: updateNotes + update_by_pk: updateNote +object_relationships: + - name: user + using: + foreign_key_constraint_on: user_id +insert_permissions: + - role: user + permission: + check: + user_id: + _eq: x-hasura-auth-elevated + set: + user_id: x-hasura-User-Id + columns: + - content + - id +select_permissions: + - role: user + permission: + columns: + - content + - created_at + - id + - updated_at + filter: + user_id: + _eq: X-Hasura-User-Id + allow_aggregations: true +update_permissions: + - role: user + permission: + columns: + - content + filter: + user_id: + _eq: x-hasura-auth-elevated + check: {} +delete_permissions: + - role: user + permission: + filter: + user_id: + _eq: x-hasura-auth-elevated diff --git a/examples/vue-apollo/nhost/metadata/databases/default/tables/tables.yaml b/examples/vue-apollo/nhost/metadata/databases/default/tables/tables.yaml index de6fd8a9a8..52221b8d90 100644 --- a/examples/vue-apollo/nhost/metadata/databases/default/tables/tables.yaml +++ b/examples/vue-apollo/nhost/metadata/databases/default/tables/tables.yaml @@ -1,11 +1,13 @@ - "!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_authenticators.yaml" - "!include auth_user_providers.yaml" - "!include auth_user_roles.yaml" +- "!include auth_user_security_keys.yaml" - "!include auth_users.yaml" - "!include public_books.yaml" +- "!include public_notes.yaml" - "!include storage_buckets.yaml" - "!include storage_files.yaml" diff --git a/examples/vue-apollo/nhost/metadata/metrics_config.yaml b/examples/vue-apollo/nhost/metadata/metrics_config.yaml new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/examples/vue-apollo/nhost/metadata/metrics_config.yaml @@ -0,0 +1 @@ +{} diff --git a/examples/vue-apollo/nhost/metadata/opentelemetry.yaml b/examples/vue-apollo/nhost/metadata/opentelemetry.yaml new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/examples/vue-apollo/nhost/metadata/opentelemetry.yaml @@ -0,0 +1 @@ +{} diff --git a/examples/vue-apollo/nhost/migrations/default/1706824985181_create_table_public_notes/down.sql b/examples/vue-apollo/nhost/migrations/default/1706824985181_create_table_public_notes/down.sql new file mode 100644 index 0000000000..921e4903b9 --- /dev/null +++ b/examples/vue-apollo/nhost/migrations/default/1706824985181_create_table_public_notes/down.sql @@ -0,0 +1 @@ +DROP TABLE "public"."notes"; diff --git a/examples/vue-apollo/nhost/migrations/default/1706824985181_create_table_public_notes/up.sql b/examples/vue-apollo/nhost/migrations/default/1706824985181_create_table_public_notes/up.sql new file mode 100644 index 0000000000..bf2ff45030 --- /dev/null +++ b/examples/vue-apollo/nhost/migrations/default/1706824985181_create_table_public_notes/up.sql @@ -0,0 +1,2 @@ +CREATE TABLE "public"."notes" ("id" uuid NOT NULL DEFAULT gen_random_uuid(), "content" text NOT NULL, "created_at" timestamptz NOT NULL DEFAULT now(), "updated_at" timestamptz NOT NULL DEFAULT now(), "user_id" uuid NOT NULL, PRIMARY KEY ("id") , FOREIGN KEY ("user_id") REFERENCES "auth"."users"("id") ON UPDATE restrict ON DELETE restrict, UNIQUE ("id")); +CREATE EXTENSION IF NOT EXISTS pgcrypto; diff --git a/examples/vue-apollo/nhost/nhost.toml b/examples/vue-apollo/nhost/nhost.toml index a4b9d3ddec..3330a52b92 100644 --- a/examples/vue-apollo/nhost/nhost.toml +++ b/examples/vue-apollo/nhost/nhost.toml @@ -28,10 +28,10 @@ httpPoolSize = 100 version = 18 [auth] -version = '0.20.2' +version = '0.24.1' [auth.redirections] -clientUrl = 'http://localhost:3000' +clientUrl = 'http://localhost:5173' [auth.signUp] enabled = true @@ -70,7 +70,7 @@ enabled = false [auth.method.emailPassword] hibpEnabled = false -emailVerificationRequired = true +emailVerificationRequired = false passwordMinLength = 9 [auth.method.smsPasswordless] @@ -124,7 +124,11 @@ enabled = false enabled = false [auth.method.webauthn] -enabled = false +enabled = true + +[auth.method.webauthn.relyingParty] +name = 'apollo-example' +origins = ['https://react-apollo.example.nhost.io'] [auth.method.webauthn.attestation] timeout = 60000 diff --git a/examples/vue-apollo/pnpm-lock.yaml b/examples/vue-apollo/pnpm-lock.yaml index 5504385169..5a3966c9df 100644 --- a/examples/vue-apollo/pnpm-lock.yaml +++ b/examples/vue-apollo/pnpm-lock.yaml @@ -6,58 +6,64 @@ settings: dependencies: '@apollo/client': - specifier: ^3.7.1 - version: 3.7.1(graphql@15.7.2) + specifier: ^3.8.9 + version: 3.9.1(graphql@16.8.1) '@mdi/font': specifier: 5.9.55 version: 5.9.55 '@nhost/apollo': - specifier: '*' - version: 0.2.0 + specifier: ^6.0.2 + version: 6.0.2(@apollo/client@3.9.1)(@nhost/nhost-js@3.0.2) + '@nhost/nhost-js': + specifier: ^3.0.2 + version: 3.0.2(graphql@16.8.1) '@nhost/vue': - specifier: '*' - version: 0.1.0(graphql@15.7.2)(vue@3.2.41) + specifier: ^2.0.3 + version: 2.0.3(graphql@16.8.1)(vue@3.4.15)(xstate@4.38.2) '@vue/apollo-composable': specifier: 4.0.0-alpha.18 - version: 4.0.0-alpha.18(@apollo/client@3.7.1)(graphql@15.7.2)(typescript@4.9.4)(vue@3.2.41) + version: 4.0.0-alpha.18(@apollo/client@3.9.1)(graphql@16.8.1)(typescript@4.9.4)(vue@3.4.15) graphql: - specifier: 15.7.2 - version: 15.7.2 + specifier: 16.8.1 + version: 16.8.1 graphql-tag: specifier: ^2.12.6 - version: 2.12.6(graphql@15.7.2) + version: 2.12.6(graphql@16.8.1) roboto-fontface: - specifier: '*' - version: 0.4.1 + specifier: ^0.10.0 + version: 0.10.0 vite-plugin-vuetify: - specifier: ^1.0.1 - version: 1.0.1(vite@4.0.2)(vue@3.2.41)(vuetify@3.0.0-beta.10) + specifier: ^1.0.2 + version: 1.0.2(vite@5.0.12)(vue@3.4.15)(vuetify@3.0.0-beta.10) vue: - specifier: ^3.2.41 - version: 3.2.41 + specifier: ^3.4.11 + version: 3.4.15(typescript@4.9.4) vue-router: - specifier: ^4.1.6 - version: 4.1.6(vue@3.2.41) + specifier: ^4.2.5 + version: 4.2.5(vue@3.4.15) + vue3-dropzone: + specifier: ^2.2.1 + version: 2.2.1(vue@3.4.15) vuetify: specifier: 3.0.0-beta.10 - version: 3.0.0-beta.10(vite-plugin-vuetify@1.0.1)(vue@3.2.41) + version: 3.0.0-beta.10(vite-plugin-vuetify@1.0.2)(vue@3.4.15) webfontloader: - specifier: ^1.0.0 - version: 1.5.14 + specifier: ^1.6.28 + version: 1.6.28 devDependencies: '@nhost/hasura-auth-js': - specifier: '*' - version: 0.0.1 + specifier: ^2.1.11 + version: 2.1.11 '@types/webfontloader': - specifier: ^1.6.35 - version: 1.6.35 + specifier: ^1.6.38 + version: 1.6.38 '@vitejs/plugin-vue': - specifier: ^4.0.0 - version: 4.0.0(vite@4.0.2)(vue@3.2.41) + specifier: ^4.6.2 + version: 4.6.2(vite@5.0.12)(vue@3.4.15) '@xstate/inspect': - specifier: ^0.6.2 - version: 0.6.2(ws@8.14.2) + specifier: ^0.6.5 + version: 0.6.5(ws@8.14.2)(xstate@4.38.2) sass: specifier: 1.32.0 version: 1.32.0 @@ -65,52 +71,18 @@ devDependencies: specifier: 4.9.4 version: 4.9.4 vite: - specifier: ^4.0.2 - version: 4.0.2(sass@1.32.0) + specifier: ^5.0.12 + version: 5.0.12(sass@1.32.0) vue-tsc: specifier: ^0.38.9 version: 0.38.9(typescript@4.9.4) packages: - /@apollo/client@3.7.1(graphql@15.7.2): - resolution: {integrity: sha512-xu5M/l7p9gT9Fx7nF3AQivp0XukjB7TM7tOd5wifIpI8RskYveL4I+rpTijzWrnqCPZabkbzJKH7WEAKdctt9w==} + /@apollo/client@3.9.1(graphql@16.8.1): + resolution: {integrity: sha512-gpnIwMrEZ4n811gy2Ksz51Ax4zjAR5O5Tg1vlKs70Eig5Qj7kGGfnWfH5B37LSCIXanRyuMgVbQx+Aty5WruBA==} peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 - graphql-ws: ^5.5.5 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - subscriptions-transport-ws: ^0.9.0 || ^0.11.0 - peerDependenciesMeta: - graphql-ws: - optional: true - react: - optional: true - react-dom: - optional: true - subscriptions-transport-ws: - optional: true - dependencies: - '@graphql-typed-document-node/core': 3.2.0(graphql@15.7.2) - '@wry/context': 0.7.3 - '@wry/equality': 0.5.6 - '@wry/trie': 0.3.2 - graphql: 15.7.2 - graphql-tag: 2.12.6(graphql@15.7.2) - hoist-non-react-statics: 3.3.2 - optimism: 0.16.2 - prop-types: 15.8.1 - response-iterator: 0.2.6 - symbol-observable: 4.0.0 - ts-invariant: 0.10.3 - tslib: 2.6.2 - zen-observable-ts: 1.2.5 - dev: false - - /@apollo/client@3.7.1(graphql@16.8.1)(subscriptions-transport-ws@0.11.0): - resolution: {integrity: sha512-xu5M/l7p9gT9Fx7nF3AQivp0XukjB7TM7tOd5wifIpI8RskYveL4I+rpTijzWrnqCPZabkbzJKH7WEAKdctt9w==} - peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 + graphql: ^15.0.0 || ^16.0.0 graphql-ws: ^5.5.5 react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -126,20 +98,22 @@ packages: optional: true dependencies: '@graphql-typed-document-node/core': 3.2.0(graphql@16.8.1) - '@wry/context': 0.7.3 + '@wry/caches': 1.0.1 '@wry/equality': 0.5.6 - '@wry/trie': 0.3.2 + '@wry/trie': 0.5.0 graphql: 16.8.1 graphql-tag: 2.12.6(graphql@16.8.1) hoist-non-react-statics: 3.3.2 - optimism: 0.16.2 + optimism: 0.18.0 prop-types: 15.8.1 + rehackt: 0.0.3 response-iterator: 0.2.6 - subscriptions-transport-ws: 0.11.0(graphql@16.8.1) symbol-observable: 4.0.0 ts-invariant: 0.10.3 tslib: 2.6.2 zen-observable-ts: 1.2.5 + transitivePeerDependencies: + - '@types/react' dev: false /@babel/helper-string-parser@7.22.5: @@ -156,13 +130,14 @@ packages: hasBin: true dependencies: '@babel/types': 7.23.0 + dev: true - /@babel/runtime@7.20.7: - resolution: {integrity: sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ==} - engines: {node: '>=6.9.0'} + /@babel/parser@7.23.9: + resolution: {integrity: sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==} + engines: {node: '>=6.0.0'} + hasBin: true dependencies: - regenerator-runtime: 0.13.11 - dev: false + '@babel/types': 7.23.0 /@babel/types@7.23.0: resolution: {integrity: sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==} @@ -172,190 +147,190 @@ packages: '@babel/helper-validator-identifier': 7.22.20 to-fast-properties: 2.0.0 - /@esbuild/android-arm64@0.16.17: - resolution: {integrity: sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg==} + /@esbuild/aix-ppc64@0.19.12: + resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + requiresBuild: true + optional: true + + /@esbuild/android-arm64@0.19.12: + resolution: {integrity: sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==} engines: {node: '>=12'} cpu: [arm64] os: [android] requiresBuild: true optional: true - /@esbuild/android-arm@0.16.17: - resolution: {integrity: sha512-N9x1CMXVhtWEAMS7pNNONyA14f71VPQN9Cnavj1XQh6T7bskqiLLrSca4O0Vr8Wdcga943eThxnVp3JLnBMYtw==} + /@esbuild/android-arm@0.19.12: + resolution: {integrity: sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==} engines: {node: '>=12'} cpu: [arm] os: [android] requiresBuild: true optional: true - /@esbuild/android-x64@0.16.17: - resolution: {integrity: sha512-a3kTv3m0Ghh4z1DaFEuEDfz3OLONKuFvI4Xqczqx4BqLyuFaFkuaG4j2MtA6fuWEFeC5x9IvqnX7drmRq/fyAQ==} + /@esbuild/android-x64@0.19.12: + resolution: {integrity: sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==} engines: {node: '>=12'} cpu: [x64] os: [android] requiresBuild: true optional: true - /@esbuild/darwin-arm64@0.16.17: - resolution: {integrity: sha512-/2agbUEfmxWHi9ARTX6OQ/KgXnOWfsNlTeLcoV7HSuSTv63E4DqtAc+2XqGw1KHxKMHGZgbVCZge7HXWX9Vn+w==} + /@esbuild/darwin-arm64@0.19.12: + resolution: {integrity: sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] requiresBuild: true optional: true - /@esbuild/darwin-x64@0.16.17: - resolution: {integrity: sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg==} + /@esbuild/darwin-x64@0.19.12: + resolution: {integrity: sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==} engines: {node: '>=12'} cpu: [x64] os: [darwin] requiresBuild: true optional: true - /@esbuild/freebsd-arm64@0.16.17: - resolution: {integrity: sha512-mt+cxZe1tVx489VTb4mBAOo2aKSnJ33L9fr25JXpqQqzbUIw/yzIzi+NHwAXK2qYV1lEFp4OoVeThGjUbmWmdw==} + /@esbuild/freebsd-arm64@0.19.12: + resolution: {integrity: sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] requiresBuild: true optional: true - /@esbuild/freebsd-x64@0.16.17: - resolution: {integrity: sha512-8ScTdNJl5idAKjH8zGAsN7RuWcyHG3BAvMNpKOBaqqR7EbUhhVHOqXRdL7oZvz8WNHL2pr5+eIT5c65kA6NHug==} + /@esbuild/freebsd-x64@0.19.12: + resolution: {integrity: sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] requiresBuild: true optional: true - /@esbuild/linux-arm64@0.16.17: - resolution: {integrity: sha512-7S8gJnSlqKGVJunnMCrXHU9Q8Q/tQIxk/xL8BqAP64wchPCTzuM6W3Ra8cIa1HIflAvDnNOt2jaL17vaW+1V0g==} + /@esbuild/linux-arm64@0.19.12: + resolution: {integrity: sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==} engines: {node: '>=12'} cpu: [arm64] os: [linux] requiresBuild: true optional: true - /@esbuild/linux-arm@0.16.17: - resolution: {integrity: sha512-iihzrWbD4gIT7j3caMzKb/RsFFHCwqqbrbH9SqUSRrdXkXaygSZCZg1FybsZz57Ju7N/SHEgPyaR0LZ8Zbe9gQ==} + /@esbuild/linux-arm@0.19.12: + resolution: {integrity: sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==} engines: {node: '>=12'} cpu: [arm] os: [linux] requiresBuild: true optional: true - /@esbuild/linux-ia32@0.16.17: - resolution: {integrity: sha512-kiX69+wcPAdgl3Lonh1VI7MBr16nktEvOfViszBSxygRQqSpzv7BffMKRPMFwzeJGPxcio0pdD3kYQGpqQ2SSg==} + /@esbuild/linux-ia32@0.19.12: + resolution: {integrity: sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==} engines: {node: '>=12'} cpu: [ia32] os: [linux] requiresBuild: true optional: true - /@esbuild/linux-loong64@0.16.17: - resolution: {integrity: sha512-dTzNnQwembNDhd654cA4QhbS9uDdXC3TKqMJjgOWsC0yNCbpzfWoXdZvp0mY7HU6nzk5E0zpRGGx3qoQg8T2DQ==} + /@esbuild/linux-loong64@0.19.12: + resolution: {integrity: sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==} engines: {node: '>=12'} cpu: [loong64] os: [linux] requiresBuild: true optional: true - /@esbuild/linux-mips64el@0.16.17: - resolution: {integrity: sha512-ezbDkp2nDl0PfIUn0CsQ30kxfcLTlcx4Foz2kYv8qdC6ia2oX5Q3E/8m6lq84Dj/6b0FrkgD582fJMIfHhJfSw==} + /@esbuild/linux-mips64el@0.19.12: + resolution: {integrity: sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] requiresBuild: true optional: true - /@esbuild/linux-ppc64@0.16.17: - resolution: {integrity: sha512-dzS678gYD1lJsW73zrFhDApLVdM3cUF2MvAa1D8K8KtcSKdLBPP4zZSLy6LFZ0jYqQdQ29bjAHJDgz0rVbLB3g==} + /@esbuild/linux-ppc64@0.19.12: + resolution: {integrity: sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] requiresBuild: true optional: true - /@esbuild/linux-riscv64@0.16.17: - resolution: {integrity: sha512-ylNlVsxuFjZK8DQtNUwiMskh6nT0vI7kYl/4fZgV1llP5d6+HIeL/vmmm3jpuoo8+NuXjQVZxmKuhDApK0/cKw==} + /@esbuild/linux-riscv64@0.19.12: + resolution: {integrity: sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] requiresBuild: true optional: true - /@esbuild/linux-s390x@0.16.17: - resolution: {integrity: sha512-gzy7nUTO4UA4oZ2wAMXPNBGTzZFP7mss3aKR2hH+/4UUkCOyqmjXiKpzGrY2TlEUhbbejzXVKKGazYcQTZWA/w==} + /@esbuild/linux-s390x@0.19.12: + resolution: {integrity: sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==} engines: {node: '>=12'} cpu: [s390x] os: [linux] requiresBuild: true optional: true - /@esbuild/linux-x64@0.16.17: - resolution: {integrity: sha512-mdPjPxfnmoqhgpiEArqi4egmBAMYvaObgn4poorpUaqmvzzbvqbowRllQ+ZgzGVMGKaPkqUmPDOOFQRUFDmeUw==} + /@esbuild/linux-x64@0.19.12: + resolution: {integrity: sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==} engines: {node: '>=12'} cpu: [x64] os: [linux] requiresBuild: true optional: true - /@esbuild/netbsd-x64@0.16.17: - resolution: {integrity: sha512-/PzmzD/zyAeTUsduZa32bn0ORug+Jd1EGGAUJvqfeixoEISYpGnAezN6lnJoskauoai0Jrs+XSyvDhppCPoKOA==} + /@esbuild/netbsd-x64@0.19.12: + resolution: {integrity: sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] requiresBuild: true optional: true - /@esbuild/openbsd-x64@0.16.17: - resolution: {integrity: sha512-2yaWJhvxGEz2RiftSk0UObqJa/b+rIAjnODJgv2GbGGpRwAfpgzyrg1WLK8rqA24mfZa9GvpjLcBBg8JHkoodg==} + /@esbuild/openbsd-x64@0.19.12: + resolution: {integrity: sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] requiresBuild: true optional: true - /@esbuild/sunos-x64@0.16.17: - resolution: {integrity: sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw==} + /@esbuild/sunos-x64@0.19.12: + resolution: {integrity: sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==} engines: {node: '>=12'} cpu: [x64] os: [sunos] requiresBuild: true optional: true - /@esbuild/win32-arm64@0.16.17: - resolution: {integrity: sha512-ga8+JqBDHY4b6fQAmOgtJJue36scANy4l/rL97W+0wYmijhxKetzZdKOJI7olaBaMhWt8Pac2McJdZLxXWUEQw==} + /@esbuild/win32-arm64@0.19.12: + resolution: {integrity: sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==} engines: {node: '>=12'} cpu: [arm64] os: [win32] requiresBuild: true optional: true - /@esbuild/win32-ia32@0.16.17: - resolution: {integrity: sha512-WnsKaf46uSSF/sZhwnqE4L/F89AYNMiD4YtEcYekBt9Q7nj0DiId2XH2Ng2PHM54qi5oPrQ8luuzGszqi/veig==} + /@esbuild/win32-ia32@0.19.12: + resolution: {integrity: sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==} engines: {node: '>=12'} cpu: [ia32] os: [win32] requiresBuild: true optional: true - /@esbuild/win32-x64@0.16.17: - resolution: {integrity: sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q==} + /@esbuild/win32-x64@0.19.12: + resolution: {integrity: sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==} engines: {node: '>=12'} cpu: [x64] os: [win32] requiresBuild: true optional: true - /@graphql-typed-document-node/core@3.2.0(graphql@15.7.2): - resolution: {integrity: sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==} - peerDependencies: - graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - dependencies: - graphql: 15.7.2 - dev: false - /@graphql-typed-document-node/core@3.2.0(graphql@16.8.1): resolution: {integrity: sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==} peerDependencies: @@ -366,135 +341,203 @@ packages: /@jridgewell/sourcemap-codec@1.4.15: resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} - dev: true /@mdi/font@5.9.55: resolution: {integrity: sha512-jswRF6q3eq8NWpWiqct6q+6Fg/I7nUhrxYJfiEM8JJpap0wVJLQdbKtyS65GdlK7S7Ytnx3TTi/bmw+tBhkGmg==} dev: false - /@nhost/apollo@0.2.0: - resolution: {integrity: sha512-X3OTEEc9EwxFbmW0ZbLYvs5uVpqCn9St9JFaFvERF0nin9RY5ca9MvleFN/6V51IidUmD9wnUCC1EiTun9fa2A==} + /@nhost/apollo@6.0.2(@apollo/client@3.9.1)(@nhost/nhost-js@3.0.2): + resolution: {integrity: sha512-ekueQ7eZEu+GPXkEg86fB5aVl8R9/ECRffPlL4yKqfyR7uXLdEWBsAxij+L1Pw6PqhSR6aroEM3p2prbUhG/8A==} + peerDependencies: + '@apollo/client': ^3.7.10 + '@nhost/nhost-js': 3.0.2 dependencies: - '@apollo/client': 3.7.1(graphql@16.8.1)(subscriptions-transport-ws@0.11.0) - '@nhost/client': 0.2.1 + '@apollo/client': 3.9.1(graphql@16.8.1) + '@nhost/nhost-js': 3.0.2(graphql@16.8.1) graphql: 16.8.1 - subscriptions-transport-ws: 0.11.0(graphql@16.8.1) - transitivePeerDependencies: - - bufferutil - - debug - - graphql-ws - - react - - react-dom - - utf-8-validate + graphql-ws: 5.14.3(graphql@16.8.1) dev: false - /@nhost/client@0.2.1: - resolution: {integrity: sha512-fen8sQ/pAeJml01pz2uiauKNOln5J/LA857MqW4+hGsBLu72mudM4pTKQH4lEf8ewnQV7WcTbwd3bW2jPZnQtQ==} + /@nhost/graphql-js@0.1.5(graphql@16.8.1): + resolution: {integrity: sha512-YvEwYNe+SZEsarPSQs7xMI4mXbkfDM1iRE2Nxe1+LC1Jlj33lD3eJA0UJZhF50rkBiNrbX2chx+c64K4OPnBxA==} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 dependencies: - axios: 0.25.0 - broadcast-channel: 4.20.2 - immer: 9.0.21 - js-cookie: 3.0.5 - xstate: 4.38.2 + '@graphql-typed-document-node/core': 3.2.0(graphql@16.8.1) + graphql: 16.8.1 + isomorphic-unfetch: 3.1.0 transitivePeerDependencies: - - debug + - encoding dev: false - /@nhost/core@0.6.0: - resolution: {integrity: sha512-aqnGJwLLg2XBY2dn9iITb4fmmkzOyrqv21JYlEGWiOaON5Er/XuBpbOhCFoqaVsF3StvoKJBOGiCV52v5gWkSg==} + /@nhost/hasura-auth-js@2.1.11: + resolution: {integrity: sha512-nuhOpVau3PyvQBdd5dKM6oen8f6V0Mgldrtd/4Frqcx9mY13f0gXk9MqDbLnInE4JbwStuDUutxzKA2ZwYwqXA==} dependencies: - axios: 0.27.2 + '@simplewebauthn/browser': 6.2.2 + fetch-ponyfill: 7.1.0 js-cookie: 3.0.5 - xstate: 4.38.2 - transitivePeerDependencies: - - debug - dev: false - - /@nhost/hasura-auth-js@0.0.1: - resolution: {integrity: sha512-fZ3iHVUQN6QU4wR+wW9WUZjdM8ovuns6pokrF8AuW9u774a4BIg0beDOx3qtZg1T1kupPeJMhcnOJJnC6oovfA==} - dependencies: - '@types/jwt-decode': 2.2.1 - axios: 0.21.4 - jwt-decode: 2.2.0 - query-string: 6.14.1 - transitivePeerDependencies: - - debug - dev: true - - /@nhost/hasura-auth-js@1.1.9: - resolution: {integrity: sha512-gKrZRM7HN1c/Z1dgBAXkJyzzbFPYAYTZ9R71oOsP+3rCs3dGFyER19pK7bfKTQEh3x6Vda7ddKhUlvRT0pi26g==} - dependencies: - '@nhost/core': 0.6.0 jwt-decode: 3.1.2 - xstate: 4.38.2 + xstate: 4.38.3 transitivePeerDependencies: - - debug - dev: false + - encoding - /@nhost/hasura-storage-js@0.2.2: - resolution: {integrity: sha512-rZ8AtgB/iN7qHZ9s+nuzduwfFfmAzUeBN1ei9SHLsVOYllGrrhKrUK83UiZvK8vm0ND5tji2NGFsZ7cXEiElPw==} + /@nhost/hasura-storage-js@2.2.6: + resolution: {integrity: sha512-0s2T8iwJHChopwZhL/nbJJwRlKeyBOpjo4H+mJXL7D/wqPLdeFMhgacfA/rhePQ1SXPUwkXIgXzcwxt5SYLghA==} dependencies: - axios: 0.27.2 + fetch-ponyfill: 7.1.0 + form-data: 4.0.0 + graphql: 16.8.1 + xstate: 4.38.3 transitivePeerDependencies: - - debug + - encoding dev: false - /@nhost/nhost-js@1.1.14(graphql@15.7.2): - resolution: {integrity: sha512-FMM3QnB6o3Xyrmp9duKy1ViH5KUuh+v6MsPw9HPToPAP7X/dod1E5BHjZyWCpjiL15/Pw0ofSVUvgZKIIVHLlQ==} + /@nhost/nhost-js@3.0.2(graphql@16.8.1): + resolution: {integrity: sha512-kwnzyKoTPGY+D/yMQl+huiVAPSVfo14TgNgX/Uu2pyATwDs1JDNuGZoqToWKS8D7zIw9oXUqagtrBFRlFYPvSw==} peerDependencies: graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 dependencies: - '@nhost/hasura-auth-js': 1.1.9 - '@nhost/hasura-storage-js': 0.2.2 - axios: 0.27.2 - graphql: 15.7.2 - jwt-decode: 3.1.2 - query-string: 7.1.3 + '@nhost/graphql-js': 0.1.5(graphql@16.8.1) + '@nhost/hasura-auth-js': 2.1.11 + '@nhost/hasura-storage-js': 2.2.6 + graphql: 16.8.1 + isomorphic-unfetch: 3.1.0 transitivePeerDependencies: - - debug + - encoding dev: false - /@nhost/vue@0.1.0(graphql@15.7.2)(vue@3.2.41): - resolution: {integrity: sha512-+f/pu6GU607WAhfSdXUWaqCCXiIR6r21Tig2dO6CDPvfpCMD8EvwvycwZUIyBuCEpp+cEyZvBN5orNLeSWW7Sw==} + /@nhost/vue@2.0.3(graphql@16.8.1)(vue@3.4.15)(xstate@4.38.2): + resolution: {integrity: sha512-KhQ0p5fqUhwLLKh16TcEm6imy6MjPv7wd1fA012ZNiYkKMsbNpuwBbLsTnw+P07QkM+r4lTijWzrgG0fyjB0UQ==} peerDependencies: vue: ^3.2.31 dependencies: - '@nhost/core': 0.6.0 - '@nhost/nhost-js': 1.1.14(graphql@15.7.2) - '@vueuse/core': 8.9.4(vue@3.2.41) - '@xstate/vue': 1.0.0(vue@3.2.41) - immer: 9.0.21 + '@nhost/nhost-js': 3.0.2(graphql@16.8.1) + '@vueuse/core': 10.7.2(vue@3.4.15) + '@xstate/vue': 2.0.0(vue@3.4.15)(xstate@4.38.2) jwt-decode: 3.1.2 - vue: 3.2.41 + vue: 3.4.15(typescript@4.9.4) transitivePeerDependencies: - '@vue/composition-api' - '@xstate/fsm' - - debug + - encoding - graphql - xstate dev: false - /@types/jwt-decode@2.2.1: - resolution: {integrity: sha512-aWw2YTtAdT7CskFyxEX2K21/zSDStuf/ikI3yBqmwpwJF0pS+/IX5DWv+1UFffZIbruP6cnT9/LAJV1gFwAT1A==} - dev: true + /@rollup/rollup-android-arm-eabi@4.9.6: + resolution: {integrity: sha512-MVNXSSYN6QXOulbHpLMKYi60ppyO13W9my1qogeiAqtjb2yR4LSmfU2+POvDkLzhjYLXz9Rf9+9a3zFHW1Lecg==} + cpu: [arm] + os: [android] + requiresBuild: true + optional: true + + /@rollup/rollup-android-arm64@4.9.6: + resolution: {integrity: sha512-T14aNLpqJ5wzKNf5jEDpv5zgyIqcpn1MlwCrUXLrwoADr2RkWA0vOWP4XxbO9aiO3dvMCQICZdKeDrFl7UMClw==} + cpu: [arm64] + os: [android] + requiresBuild: true + optional: true + + /@rollup/rollup-darwin-arm64@4.9.6: + resolution: {integrity: sha512-CqNNAyhRkTbo8VVZ5R85X73H3R5NX9ONnKbXuHisGWC0qRbTTxnF1U4V9NafzJbgGM0sHZpdO83pLPzq8uOZFw==} + cpu: [arm64] + os: [darwin] + requiresBuild: true + optional: true + + /@rollup/rollup-darwin-x64@4.9.6: + resolution: {integrity: sha512-zRDtdJuRvA1dc9Mp6BWYqAsU5oeLixdfUvkTHuiYOHwqYuQ4YgSmi6+/lPvSsqc/I0Omw3DdICx4Tfacdzmhog==} + cpu: [x64] + os: [darwin] + requiresBuild: true + optional: true + + /@rollup/rollup-linux-arm-gnueabihf@4.9.6: + resolution: {integrity: sha512-oNk8YXDDnNyG4qlNb6is1ojTOGL/tRhbbKeE/YuccItzerEZT68Z9gHrY3ROh7axDc974+zYAPxK5SH0j/G+QQ==} + cpu: [arm] + os: [linux] + requiresBuild: true + optional: true + + /@rollup/rollup-linux-arm64-gnu@4.9.6: + resolution: {integrity: sha512-Z3O60yxPtuCYobrtzjo0wlmvDdx2qZfeAWTyfOjEDqd08kthDKexLpV97KfAeUXPosENKd8uyJMRDfFMxcYkDQ==} + cpu: [arm64] + os: [linux] + requiresBuild: true + optional: true + + /@rollup/rollup-linux-arm64-musl@4.9.6: + resolution: {integrity: sha512-gpiG0qQJNdYEVad+1iAsGAbgAnZ8j07FapmnIAQgODKcOTjLEWM9sRb+MbQyVsYCnA0Im6M6QIq6ax7liws6eQ==} + cpu: [arm64] + os: [linux] + requiresBuild: true + optional: true + + /@rollup/rollup-linux-riscv64-gnu@4.9.6: + resolution: {integrity: sha512-+uCOcvVmFUYvVDr27aiyun9WgZk0tXe7ThuzoUTAukZJOwS5MrGbmSlNOhx1j80GdpqbOty05XqSl5w4dQvcOA==} + cpu: [riscv64] + os: [linux] + requiresBuild: true + optional: true + + /@rollup/rollup-linux-x64-gnu@4.9.6: + resolution: {integrity: sha512-HUNqM32dGzfBKuaDUBqFB7tP6VMN74eLZ33Q9Y1TBqRDn+qDonkAUyKWwF9BR9unV7QUzffLnz9GrnKvMqC/fw==} + cpu: [x64] + os: [linux] + requiresBuild: true + optional: true + + /@rollup/rollup-linux-x64-musl@4.9.6: + resolution: {integrity: sha512-ch7M+9Tr5R4FK40FHQk8VnML0Szi2KRujUgHXd/HjuH9ifH72GUmw6lStZBo3c3GB82vHa0ZoUfjfcM7JiiMrQ==} + cpu: [x64] + os: [linux] + requiresBuild: true + optional: true + + /@rollup/rollup-win32-arm64-msvc@4.9.6: + resolution: {integrity: sha512-VD6qnR99dhmTQ1mJhIzXsRcTBvTjbfbGGwKAHcu+52cVl15AC/kplkhxzW/uT0Xl62Y/meBKDZvoJSJN+vTeGA==} + cpu: [arm64] + os: [win32] + requiresBuild: true + optional: true + + /@rollup/rollup-win32-ia32-msvc@4.9.6: + resolution: {integrity: sha512-J9AFDq/xiRI58eR2NIDfyVmTYGyIZmRcvcAoJ48oDld/NTR8wyiPUu2X/v1navJ+N/FGg68LEbX3Ejd6l8B7MQ==} + cpu: [ia32] + os: [win32] + requiresBuild: true + optional: true - /@types/web-bluetooth@0.0.14: - resolution: {integrity: sha512-5d2RhCard1nQUC3aHcq/gHzWYO6K0WJmAbjO7mQJgCQKtZpgXxv1rOM6O/dBDhDYYVutk1sciOgNSe+5YyfM8A==} + /@rollup/rollup-win32-x64-msvc@4.9.6: + resolution: {integrity: sha512-jqzNLhNDvIZOrt69Ce4UjGRpXJBzhUBzawMwnaDAwyHriki3XollsewxWzOzz+4yOFDkuJHtTsZFwMxhYJWmLQ==} + cpu: [x64] + os: [win32] + requiresBuild: true + optional: true + + /@simplewebauthn/browser@6.2.2: + resolution: {integrity: sha512-VUtne7+s6BmW4usnbitjZEI1VNT/PNh6bYg+AI4OMdfpo5z+yAq+6iVAWBJlIUGVk5InetEQvTUp6OefBam8qg==} + + /@types/estree@1.0.5: + resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + + /@types/web-bluetooth@0.0.20: + resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==} dev: false - /@types/webfontloader@1.6.35: - resolution: {integrity: sha512-IJlrsiDWq6KghQ7tPlL5tcwSUyOxLDceT+AFUY7Ylj0Fcv3/h3QkANqQxZ0B5mEpEKxhTw76vDmvrruSMV9n9Q==} + /@types/webfontloader@1.6.38: + resolution: {integrity: sha512-kUaF72Fv202suFx6yBrwXqeVRMx7hGtJTesyESZgn9sEPCUeDXm2p0SiyS1MTqW74nQP4p7JyrOCwZ7pNFns4w==} dev: true - /@vitejs/plugin-vue@4.0.0(vite@4.0.2)(vue@3.2.41): - resolution: {integrity: sha512-e0X4jErIxAB5oLtDqbHvHpJe/uWNkdpYV83AOG2xo2tEVSzCzewgJMtREZM30wXnM5ls90hxiOtAuVU6H5JgbA==} + /@vitejs/plugin-vue@4.6.2(vite@5.0.12)(vue@3.4.15): + resolution: {integrity: sha512-kqf7SGFoG+80aZG6Pf+gsZIVvGSCKE98JbiWqcCV9cThtg91Jav0yvYFC9Zb+jKetNGF6ZKeoaxgZfND21fWKw==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: - vite: ^4.0.0 + vite: ^4.0.0 || ^5.0.0 vue: ^3.2.25 dependencies: - vite: 4.0.2(sass@1.32.0) - vue: 3.2.41 + vite: 5.0.12(sass@1.32.0) + vue: 3.4.15(typescript@4.9.4) dev: true /@volar/code-gen@0.38.9: @@ -529,7 +572,7 @@ packages: '@vue/reactivity': 3.3.4 dev: true - /@vue/apollo-composable@4.0.0-alpha.18(@apollo/client@3.7.1)(graphql@15.7.2)(typescript@4.9.4)(vue@3.2.41): + /@vue/apollo-composable@4.0.0-alpha.18(@apollo/client@3.9.1)(graphql@16.8.1)(typescript@4.9.4)(vue@3.4.15): resolution: {integrity: sha512-AasMZnAOG9fH+vcnQu6C3eyBMWXCsjdF0Njh7gGzQYBdo/CG9g9OKtrmHizq5AbgR2KJe/0RHE9yLBj7SZrcdQ==} peerDependencies: '@apollo/client': ^3.4.13 @@ -540,24 +583,16 @@ packages: '@vue/composition-api': optional: true dependencies: - '@apollo/client': 3.7.1(graphql@15.7.2) - graphql: 15.7.2 + '@apollo/client': 3.9.1(graphql@16.8.1) + graphql: 16.8.1 throttle-debounce: 3.0.1 ts-essentials: 9.4.0(typescript@4.9.4) - vue: 3.2.41 - vue-demi: 0.13.11(vue@3.2.41) + vue: 3.4.15(typescript@4.9.4) + vue-demi: 0.13.11(vue@3.4.15) transitivePeerDependencies: - typescript dev: false - /@vue/compiler-core@3.2.41: - resolution: {integrity: sha512-oA4mH6SA78DT+96/nsi4p9DX97PHcNROxs51lYk7gb9Z4BPKQ3Mh+BLn6CQZBw857Iuhu28BfMSRHAlPvD4vlw==} - dependencies: - '@babel/parser': 7.23.0 - '@vue/shared': 3.2.41 - estree-walker: 2.0.2 - source-map: 0.6.1 - /@vue/compiler-core@3.3.4: resolution: {integrity: sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==} dependencies: @@ -567,11 +602,14 @@ packages: source-map-js: 1.0.2 dev: true - /@vue/compiler-dom@3.2.41: - resolution: {integrity: sha512-xe5TbbIsonjENxJsYRbDJvthzqxLNk+tb3d/c47zgREDa/PCp6/Y4gC/skM4H6PIuX5DAxm7fFJdbjjUH2QTMw==} + /@vue/compiler-core@3.4.15: + resolution: {integrity: sha512-XcJQVOaxTKCnth1vCxEChteGuwG6wqnUHxAm1DO3gCz0+uXKaJNx8/digSz4dLALCy8n2lKq24jSUs8segoqIw==} dependencies: - '@vue/compiler-core': 3.2.41 - '@vue/shared': 3.2.41 + '@babel/parser': 7.23.9 + '@vue/shared': 3.4.15 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.0.2 /@vue/compiler-dom@3.3.4: resolution: {integrity: sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==} @@ -580,19 +618,11 @@ packages: '@vue/shared': 3.3.4 dev: true - /@vue/compiler-sfc@3.2.41: - resolution: {integrity: sha512-+1P2m5kxOeaxVmJNXnBskAn3BenbTmbxBxWOtBq3mQTCokIreuMULFantBUclP0+KnzNCMOvcnKinqQZmiOF8w==} + /@vue/compiler-dom@3.4.15: + resolution: {integrity: sha512-wox0aasVV74zoXyblarOM3AZQz/Z+OunYcIHe1OsGclCHt8RsRm04DObjefaI82u6XDzv+qGWZ24tIsRAIi5MQ==} dependencies: - '@babel/parser': 7.23.0 - '@vue/compiler-core': 3.2.41 - '@vue/compiler-dom': 3.2.41 - '@vue/compiler-ssr': 3.2.41 - '@vue/reactivity-transform': 3.2.41 - '@vue/shared': 3.2.41 - estree-walker: 2.0.2 - magic-string: 0.25.9 - postcss: 8.4.31 - source-map: 0.6.1 + '@vue/compiler-core': 3.4.15 + '@vue/shared': 3.4.15 /@vue/compiler-sfc@3.3.4: resolution: {integrity: sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==} @@ -609,11 +639,18 @@ packages: source-map-js: 1.0.2 dev: true - /@vue/compiler-ssr@3.2.41: - resolution: {integrity: sha512-Y5wPiNIiaMz/sps8+DmhaKfDm1xgj6GrH99z4gq2LQenfVQcYXmHIOBcs5qPwl7jaW3SUQWjkAPKMfQemEQZwQ==} + /@vue/compiler-sfc@3.4.15: + resolution: {integrity: sha512-LCn5M6QpkpFsh3GQvs2mJUOAlBQcCco8D60Bcqmf3O3w5a+KWS5GvYbrrJBkgvL1BDnTp+e8q0lXCLgHhKguBA==} dependencies: - '@vue/compiler-dom': 3.2.41 - '@vue/shared': 3.2.41 + '@babel/parser': 7.23.9 + '@vue/compiler-core': 3.4.15 + '@vue/compiler-dom': 3.4.15 + '@vue/compiler-ssr': 3.4.15 + '@vue/shared': 3.4.15 + estree-walker: 2.0.2 + magic-string: 0.30.6 + postcss: 8.4.33 + source-map-js: 1.0.2 /@vue/compiler-ssr@3.3.4: resolution: {integrity: sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==} @@ -622,19 +659,16 @@ packages: '@vue/shared': 3.3.4 dev: true + /@vue/compiler-ssr@3.4.15: + resolution: {integrity: sha512-1jdeQyiGznr8gjFDadVmOJqZiLNSsMa5ZgqavkPZ8O2wjHv0tVuAEsw5hTdUoUW4232vpBbL/wJhzVW/JwY1Uw==} + dependencies: + '@vue/compiler-dom': 3.4.15 + '@vue/shared': 3.4.15 + /@vue/devtools-api@6.5.0: resolution: {integrity: sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==} dev: false - /@vue/reactivity-transform@3.2.41: - resolution: {integrity: sha512-mK5+BNMsL4hHi+IR3Ft/ho6Za+L3FA5j8WvreJ7XzHrqkPq8jtF/SMo7tuc9gHjLDwKZX1nP1JQOKo9IEAn54A==} - dependencies: - '@babel/parser': 7.23.0 - '@vue/compiler-core': 3.2.41 - '@vue/shared': 3.2.41 - estree-walker: 2.0.2 - magic-string: 0.25.9 - /@vue/reactivity-transform@3.3.4: resolution: {integrity: sha512-MXgwjako4nu5WFLAjpBnCj/ieqcjE2aJBINUNQzkZQfzIZA4xn+0fV1tIYBJvvva3N3OvKGofRLvQIwEQPpaXw==} dependencies: @@ -645,47 +679,47 @@ packages: magic-string: 0.30.4 dev: true - /@vue/reactivity@3.2.41: - resolution: {integrity: sha512-9JvCnlj8uc5xRiQGZ28MKGjuCoPhhTwcoAdv3o31+cfGgonwdPNuvqAXLhlzu4zwqavFEG5tvaoINQEfxz+l6g==} - dependencies: - '@vue/shared': 3.2.41 - /@vue/reactivity@3.3.4: resolution: {integrity: sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==} dependencies: '@vue/shared': 3.3.4 dev: true - /@vue/runtime-core@3.2.41: - resolution: {integrity: sha512-0LBBRwqnI0p4FgIkO9q2aJBBTKDSjzhnxrxHYengkAF6dMOjeAIZFDADAlcf2h3GDALWnblbeprYYpItiulSVQ==} + /@vue/reactivity@3.4.15: + resolution: {integrity: sha512-55yJh2bsff20K5O84MxSvXKPHHt17I2EomHznvFiJCAZpJTNW8IuLj1xZWMLELRhBK3kkFV/1ErZGHJfah7i7w==} dependencies: - '@vue/reactivity': 3.2.41 - '@vue/shared': 3.2.41 + '@vue/shared': 3.4.15 - /@vue/runtime-dom@3.2.41: - resolution: {integrity: sha512-U7zYuR1NVIP8BL6jmOqmapRAHovEFp7CSw4pR2FacqewXNGqZaRfHoNLQsqQvVQ8yuZNZtxSZy0FFyC70YXPpA==} + /@vue/runtime-core@3.4.15: + resolution: {integrity: sha512-6E3by5m6v1AkW0McCeAyhHTw+3y17YCOKG0U0HDKDscV4Hs0kgNT5G+GCHak16jKgcCDHpI9xe5NKb8sdLCLdw==} dependencies: - '@vue/runtime-core': 3.2.41 - '@vue/shared': 3.2.41 - csstype: 2.6.21 + '@vue/reactivity': 3.4.15 + '@vue/shared': 3.4.15 - /@vue/server-renderer@3.2.41(vue@3.2.41): - resolution: {integrity: sha512-7YHLkfJdTlsZTV0ae5sPwl9Gn/EGr2hrlbcS/8naXm2CDpnKUwC68i1wGlrYAfIgYWL7vUZwk2GkYLQH5CvFig==} - peerDependencies: - vue: 3.2.41 + /@vue/runtime-dom@3.4.15: + resolution: {integrity: sha512-EVW8D6vfFVq3V/yDKNPBFkZKGMFSvZrUQmx196o/v2tHKdwWdiZjYUBS+0Ez3+ohRyF8Njwy/6FH5gYJ75liUw==} dependencies: - '@vue/compiler-ssr': 3.2.41 - '@vue/shared': 3.2.41 - vue: 3.2.41 + '@vue/runtime-core': 3.4.15 + '@vue/shared': 3.4.15 + csstype: 3.1.3 - /@vue/shared@3.2.41: - resolution: {integrity: sha512-W9mfWLHmJhkfAmV+7gDjcHeAWALQtgGT3JErxULl0oz6R6+3ug91I7IErs93eCFhPCZPHBs4QJS7YWEV7A3sxw==} + /@vue/server-renderer@3.4.15(vue@3.4.15): + resolution: {integrity: sha512-3HYzaidu9cHjrT+qGUuDhFYvF/j643bHC6uUN9BgM11DVy+pM6ATsG6uPBLnkwOgs7BpJABReLmpL3ZPAsUaqw==} + peerDependencies: + vue: 3.4.15 + dependencies: + '@vue/compiler-ssr': 3.4.15 + '@vue/shared': 3.4.15 + vue: 3.4.15(typescript@4.9.4) /@vue/shared@3.3.4: resolution: {integrity: sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==} dev: true - /@vuetify/loader-shared@1.7.1(vue@3.2.41)(vuetify@3.0.0-beta.10): + /@vue/shared@3.4.15: + resolution: {integrity: sha512-KzfPTxVaWfB+eGcGdbSf4CWdaXcGDqckoeXUh7SB3fZdEtzPCK2Vq9B/lRRL3yutax/LWITz+SwvgyOxz5V75g==} + + /@vuetify/loader-shared@1.7.1(vue@3.4.15)(vuetify@3.0.0-beta.10): resolution: {integrity: sha512-kLUvuAed6RCvkeeTNJzuy14pqnkur8lTuner7v7pNE/kVhPR97TuyXwBSBMR1cJeiLiOfu6SF5XlCYbXByEx1g==} peerDependencies: vue: ^3.0.0 @@ -693,45 +727,40 @@ packages: dependencies: find-cache-dir: 3.3.2 upath: 2.0.1 - vue: 3.2.41 - vuetify: 3.0.0-beta.10(vite-plugin-vuetify@1.0.1)(vue@3.2.41) + vue: 3.4.15(typescript@4.9.4) + vuetify: 3.0.0-beta.10(vite-plugin-vuetify@1.0.2)(vue@3.4.15) dev: false - /@vueuse/core@8.9.4(vue@3.2.41): - resolution: {integrity: sha512-B/Mdj9TK1peFyWaPof+Zf/mP9XuGAngaJZBwPaXBvU3aCTZlx3ltlrFFFyMV4iGBwsjSCeUCgZrtkEj9dS2Y3Q==} - peerDependencies: - '@vue/composition-api': ^1.1.0 - vue: ^2.6.0 || ^3.2.0 - peerDependenciesMeta: - '@vue/composition-api': - optional: true - vue: - optional: true + /@vueuse/core@10.7.2(vue@3.4.15): + resolution: {integrity: sha512-AOyAL2rK0By62Hm+iqQn6Rbu8bfmbgaIMXcE3TSr7BdQ42wnSFlwIdPjInO62onYsEMK/yDMU8C6oGfDAtZ2qQ==} dependencies: - '@types/web-bluetooth': 0.0.14 - '@vueuse/metadata': 8.9.4 - '@vueuse/shared': 8.9.4(vue@3.2.41) - vue: 3.2.41 - vue-demi: 0.14.6(vue@3.2.41) + '@types/web-bluetooth': 0.0.20 + '@vueuse/metadata': 10.7.2 + '@vueuse/shared': 10.7.2(vue@3.4.15) + vue-demi: 0.14.6(vue@3.4.15) + transitivePeerDependencies: + - '@vue/composition-api' + - vue dev: false - /@vueuse/metadata@8.9.4: - resolution: {integrity: sha512-IwSfzH80bnJMzqhaapqJl9JRIiyQU0zsRGEgnxN6jhq7992cPUJIRfV+JHRIZXjYqbwt07E1gTEp0R0zPJ1aqw==} + /@vueuse/metadata@10.7.2: + resolution: {integrity: sha512-kCWPb4J2KGrwLtn1eJwaJD742u1k5h6v/St5wFe8Quih90+k2a0JP8BS4Zp34XUuJqS2AxFYMb1wjUL8HfhWsQ==} dev: false - /@vueuse/shared@8.9.4(vue@3.2.41): - resolution: {integrity: sha512-wt+T30c4K6dGRMVqPddexEVLa28YwxW5OFIPmzUHICjphfAuBFTTdDoyqREZNDOFJZ44ARH1WWQNCUK8koJ+Ag==} - peerDependencies: - '@vue/composition-api': ^1.1.0 - vue: ^2.6.0 || ^3.2.0 - peerDependenciesMeta: - '@vue/composition-api': - optional: true - vue: - optional: true + /@vueuse/shared@10.7.2(vue@3.4.15): + resolution: {integrity: sha512-qFbXoxS44pi2FkgFjPvF4h7c9oMDutpyBdcJdMYIMg9XyXli2meFMuaKn+UMgsClo//Th6+beeCgqweT/79BVA==} dependencies: - vue: 3.2.41 - vue-demi: 0.14.6(vue@3.2.41) + vue-demi: 0.14.6(vue@3.4.15) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + dev: false + + /@wry/caches@1.0.1: + resolution: {integrity: sha512-bXuaUNLVVkD20wcGBWRyo7j9N3TxePEWFZj2Y+r9OoUzfqmavM84+mFykRicNsBqatba5JLay1t48wxaXaWnlA==} + engines: {node: '>=8'} + dependencies: + tslib: 2.6.2 dev: false /@wry/context@0.7.3: @@ -748,39 +777,49 @@ packages: tslib: 2.6.2 dev: false - /@wry/trie@0.3.2: - resolution: {integrity: sha512-yRTyhWSls2OY/pYLfwff867r8ekooZ4UI+/gxot5Wj8EFwSf2rG+n+Mo/6LoLQm1TKA4GRj2+LCpbfS937dClQ==} + /@wry/trie@0.4.3: + resolution: {integrity: sha512-I6bHwH0fSf6RqQcnnXLJKhkSXG45MFral3GxPaY4uAl0LYDZM+YDVDAiU9bYwjTuysy1S0IeecWtmq1SZA3M1w==} engines: {node: '>=8'} dependencies: tslib: 2.6.2 dev: false - /@xstate/inspect@0.6.2(ws@8.14.2): - resolution: {integrity: sha512-ZDJ0NETucV7wyT2Tyr3VeEgVD45TUGMTwbzmU2JfzUOjJQMyqn/XjcXGa3wxzgSvz2I0L4xC5ahRZN85j7oh1Q==} + /@wry/trie@0.5.0: + resolution: {integrity: sha512-FNoYzHawTMk/6KMQoEG5O4PuioX19UbwdQKF44yw0nLfOypfQdjtfZzo/UIJWAJ23sNIFbD1Ug9lbaDGMwbqQA==} + engines: {node: '>=8'} + dependencies: + tslib: 2.6.2 + dev: false + + /@xstate/inspect@0.6.5(ws@8.14.2)(xstate@4.38.2): + resolution: {integrity: sha512-lUVb/XHaeOl9UP99yQK/rjS+WVx1ymaz0KX8nUsQ4VG/dxvjF0kRcAPCDMuQ7IhWbp0nER+KLE46UFXrqp20Sg==} peerDependencies: '@types/ws': ^8.0.0 ws: ^8.0.0 + xstate: ^4.31.0 peerDependenciesMeta: '@types/ws': optional: true dependencies: fast-safe-stringify: 2.1.1 ws: 8.14.2 + xstate: 4.38.2 dev: true - /@xstate/vue@1.0.0(vue@3.2.41): - resolution: {integrity: sha512-GnJ2WKmef3UvpOj7tMOGkFLF2fSjVFgX/2Ik/0ZttHJCQNXRBWDaaiqNnVVB0XynTUfRPrkOPNeGD4XLqrqeVg==} + /@xstate/vue@2.0.0(vue@3.4.15)(xstate@4.38.2): + resolution: {integrity: sha512-JlrJ3d+I6rZCcFBuu3O4GP+mGJfd11O9o69wRedzPMqZ+hxcMRBsih9L5kKnJHcU9CTmdJTT172oxTaYF7thzA==} peerDependencies: - '@xstate/fsm': ^1.6.5 + '@xstate/fsm': ^2.0.0 vue: ^3.0.0 - xstate: ^4.30.3 + xstate: ^4.31.0 peerDependenciesMeta: '@xstate/fsm': optional: true xstate: optional: true dependencies: - vue: 3.2.41 + vue: 3.4.15(typescript@4.9.4) + xstate: 4.38.2 dev: false /anymatch@3.1.3: @@ -794,66 +833,21 @@ packages: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} dev: false - /axios@0.21.4: - resolution: {integrity: sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==} - dependencies: - follow-redirects: 1.15.3 - transitivePeerDependencies: - - debug - dev: true - - /axios@0.25.0: - resolution: {integrity: sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==} - dependencies: - follow-redirects: 1.15.3 - transitivePeerDependencies: - - debug - dev: false - - /axios@0.27.2: - resolution: {integrity: sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==} - dependencies: - follow-redirects: 1.15.3 - form-data: 4.0.0 - transitivePeerDependencies: - - debug - dev: false - - /backo2@1.0.2: - resolution: {integrity: sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA==} - dev: false - - /balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + /attr-accept@2.2.2: + resolution: {integrity: sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==} + engines: {node: '>=4'} dev: false /binary-extensions@2.2.0: resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} engines: {node: '>=8'} - /brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - dev: false - /braces@3.0.2: resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} engines: {node: '>=8'} dependencies: fill-range: 7.0.1 - /broadcast-channel@4.20.2: - resolution: {integrity: sha512-v0lJgMzC+MX4e2KCFWYXChZ2mKTqm5mnJGId6tqJp3NfylggbNd8c2uKeP4MQxD2ucKOesY68aN98zwl9d6Tvg==} - dependencies: - '@babel/runtime': 7.20.7 - oblivious-set: 1.1.1 - p-queue: 6.6.2 - rimraf: 3.0.2 - unload: 2.4.1 - dev: false - /chokidar@3.5.3: resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} engines: {node: '>= 8.10.0'} @@ -879,12 +873,8 @@ packages: resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} dev: false - /concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - dev: false - - /csstype@2.6.21: - resolution: {integrity: sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==} + /csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} /debug@4.3.4: resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} @@ -898,69 +888,72 @@ packages: ms: 2.1.2 dev: false - /decode-uri-component@0.2.2: - resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} - engines: {node: '>=0.10'} - /delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} dev: false - /esbuild@0.16.17: - resolution: {integrity: sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==} + /entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + /esbuild@0.19.12: + resolution: {integrity: sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==} engines: {node: '>=12'} hasBin: true requiresBuild: true optionalDependencies: - '@esbuild/android-arm': 0.16.17 - '@esbuild/android-arm64': 0.16.17 - '@esbuild/android-x64': 0.16.17 - '@esbuild/darwin-arm64': 0.16.17 - '@esbuild/darwin-x64': 0.16.17 - '@esbuild/freebsd-arm64': 0.16.17 - '@esbuild/freebsd-x64': 0.16.17 - '@esbuild/linux-arm': 0.16.17 - '@esbuild/linux-arm64': 0.16.17 - '@esbuild/linux-ia32': 0.16.17 - '@esbuild/linux-loong64': 0.16.17 - '@esbuild/linux-mips64el': 0.16.17 - '@esbuild/linux-ppc64': 0.16.17 - '@esbuild/linux-riscv64': 0.16.17 - '@esbuild/linux-s390x': 0.16.17 - '@esbuild/linux-x64': 0.16.17 - '@esbuild/netbsd-x64': 0.16.17 - '@esbuild/openbsd-x64': 0.16.17 - '@esbuild/sunos-x64': 0.16.17 - '@esbuild/win32-arm64': 0.16.17 - '@esbuild/win32-ia32': 0.16.17 - '@esbuild/win32-x64': 0.16.17 + '@esbuild/aix-ppc64': 0.19.12 + '@esbuild/android-arm': 0.19.12 + '@esbuild/android-arm64': 0.19.12 + '@esbuild/android-x64': 0.19.12 + '@esbuild/darwin-arm64': 0.19.12 + '@esbuild/darwin-x64': 0.19.12 + '@esbuild/freebsd-arm64': 0.19.12 + '@esbuild/freebsd-x64': 0.19.12 + '@esbuild/linux-arm': 0.19.12 + '@esbuild/linux-arm64': 0.19.12 + '@esbuild/linux-ia32': 0.19.12 + '@esbuild/linux-loong64': 0.19.12 + '@esbuild/linux-mips64el': 0.19.12 + '@esbuild/linux-ppc64': 0.19.12 + '@esbuild/linux-riscv64': 0.19.12 + '@esbuild/linux-s390x': 0.19.12 + '@esbuild/linux-x64': 0.19.12 + '@esbuild/netbsd-x64': 0.19.12 + '@esbuild/openbsd-x64': 0.19.12 + '@esbuild/sunos-x64': 0.19.12 + '@esbuild/win32-arm64': 0.19.12 + '@esbuild/win32-ia32': 0.19.12 + '@esbuild/win32-x64': 0.19.12 /estree-walker@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} - /eventemitter3@3.1.2: - resolution: {integrity: sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==} - dev: false - - /eventemitter3@4.0.7: - resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} - dev: false - /fast-safe-stringify@2.1.1: resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} dev: true + /fetch-ponyfill@7.1.0: + resolution: {integrity: sha512-FhbbL55dj/qdVO3YNK7ZEkshvj3eQ7EuIGV2I6ic/2YiocvyWv+7jg2s4AyS0wdRU75s3tA8ZxI/xPigb0v5Aw==} + dependencies: + node-fetch: 2.6.13 + transitivePeerDependencies: + - encoding + + /file-selector@0.2.4: + resolution: {integrity: sha512-ZDsQNbrv6qRi1YTDOEWzf5J2KjZ9KMI1Q2SGeTkCJmNNW25Jg4TW4UMcmoqcg4WrAyKRcpBXdbWRxkfrOzVRbA==} + engines: {node: '>= 10'} + dependencies: + tslib: 2.6.2 + dev: false + /fill-range@7.0.1: resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} engines: {node: '>=8'} dependencies: to-regex-range: 5.0.1 - /filter-obj@1.1.0: - resolution: {integrity: sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==} - engines: {node: '>=0.10.0'} - /find-cache-dir@3.3.2: resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==} engines: {node: '>=8'} @@ -978,15 +971,6 @@ packages: path-exists: 4.0.0 dev: false - /follow-redirects@1.15.3: - resolution: {integrity: sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - /form-data@4.0.0: resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} engines: {node: '>= 6'} @@ -996,10 +980,6 @@ packages: mime-types: 2.1.35 dev: false - /fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - dev: false - /fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -1007,49 +987,29 @@ packages: requiresBuild: true optional: true - /function-bind@1.1.1: - resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} - /glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} dependencies: is-glob: 4.0.3 - /glob@7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 - dev: false - - /graphql-tag@2.12.6(graphql@15.7.2): + /graphql-tag@2.12.6(graphql@16.8.1): resolution: {integrity: sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==} engines: {node: '>=10'} peerDependencies: graphql: ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 dependencies: - graphql: 15.7.2 + graphql: 16.8.1 tslib: 2.6.2 dev: false - /graphql-tag@2.12.6(graphql@16.8.1): - resolution: {integrity: sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==} + /graphql-ws@5.14.3(graphql@16.8.1): + resolution: {integrity: sha512-F/i2xNIVbaEF2xWggID0X/UZQa2V8kqKDPO8hwmu53bVOcTL7uNkxnexeEgSCVxYBQUTUNEI8+e4LO1FOhKPKQ==} engines: {node: '>=10'} peerDependencies: - graphql: ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 + graphql: '>=0.11 <=16' dependencies: graphql: 16.8.1 - tslib: 2.6.2 - dev: false - - /graphql@15.7.2: - resolution: {integrity: sha512-AnnKk7hFQFmU/2I9YSQf3xw44ctnSFCfp3zE0N6W174gqe9fWG/2rKaKxROK7CcI3XtERpjEKFqts8o319Kf7A==} - engines: {node: '>= 10.x'} dev: false /graphql@16.8.1: @@ -1057,44 +1017,18 @@ packages: engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} dev: false - /has@1.0.3: - resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} - engines: {node: '>= 0.4.0'} - dependencies: - function-bind: 1.1.1 - /hoist-non-react-statics@3.3.2: resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} dependencies: react-is: 16.13.1 dev: false - /immer@9.0.21: - resolution: {integrity: sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==} - dev: false - - /inflight@1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - dependencies: - once: 1.4.0 - wrappy: 1.0.2 - dev: false - - /inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - dev: false - /is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} dependencies: binary-extensions: 2.2.0 - /is-core-module@2.13.0: - resolution: {integrity: sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==} - dependencies: - has: 1.0.3 - /is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -1109,26 +1043,25 @@ packages: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} - /iterall@1.3.0: - resolution: {integrity: sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==} + /isomorphic-unfetch@3.1.0: + resolution: {integrity: sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q==} + dependencies: + node-fetch: 2.7.0 + unfetch: 4.2.0 + transitivePeerDependencies: + - encoding dev: false /js-cookie@3.0.5: resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==} engines: {node: '>=14'} - dev: false /js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} dev: false - /jwt-decode@2.2.0: - resolution: {integrity: sha512-86GgN2vzfUu7m9Wcj63iUkuDzFNYFVmjeDm2GzWpUk+opB0pEpMsw6ePCMrhYkumz2C1ihqtZzOMAg7FiXcNoQ==} - dev: true - /jwt-decode@3.1.2: resolution: {integrity: sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==} - dev: false /locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} @@ -1144,11 +1077,6 @@ packages: js-tokens: 4.0.0 dev: false - /magic-string@0.25.9: - resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} - dependencies: - sourcemap-codec: 1.4.8 - /magic-string@0.30.4: resolution: {integrity: sha512-Q/TKtsC5BPm0kGqgBIF9oXAs/xEf2vRKiIB4wCRQTJOQIByZ1d+NnUOotvJOvNpi5RNIgVOMC3pOuaP1ZTDlVg==} engines: {node: '>=12'} @@ -1156,6 +1084,12 @@ packages: '@jridgewell/sourcemap-codec': 1.4.15 dev: true + /magic-string@0.30.6: + resolution: {integrity: sha512-n62qCLbPjNjyo+owKtveQxZFZTBm+Ms6YoGD23Wew6Vw337PElFNifQpknPruVRQV57kVShPnLGo9vWxVhpPvA==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + /make-dir@3.1.0: resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} engines: {node: '>=8'} @@ -1175,12 +1109,6 @@ packages: mime-db: 1.52.0 dev: false - /minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - dependencies: - brace-expansion: 1.1.11 - dev: false - /ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} dev: false @@ -1189,6 +1117,35 @@ packages: resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + dev: true + + /nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + /node-fetch@2.6.13: + resolution: {integrity: sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + + /node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: false /normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} @@ -1199,26 +1156,13 @@ packages: engines: {node: '>=0.10.0'} dev: false - /oblivious-set@1.1.1: - resolution: {integrity: sha512-Oh+8fK09mgGmAshFdH6hSVco6KZmd1tTwNFWj35OvzdmJTMZtAkbn05zar2iG3v6sDs1JLEtOiBGNb6BHwkb2w==} - dev: false - - /once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - dependencies: - wrappy: 1.0.2 - dev: false - - /optimism@0.16.2: - resolution: {integrity: sha512-zWNbgWj+3vLEjZNIh/okkY2EUfX+vB9TJopzIZwT1xxaMqC5hRLLraePod4c5n4He08xuXNH+zhKFFCu390wiQ==} + /optimism@0.18.0: + resolution: {integrity: sha512-tGn8+REwLRNFnb9WmcY5IfpOqeX2kpaYJ1s6Ae3mn12AeydLkR3j+jSCmVQFoXqU8D41PAJ1RG1rCRNWmNZVmQ==} dependencies: + '@wry/caches': 1.0.1 '@wry/context': 0.7.3 - '@wry/trie': 0.3.2 - dev: false - - /p-finally@1.0.0: - resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} - engines: {node: '>=4'} + '@wry/trie': 0.4.3 + tslib: 2.6.2 dev: false /p-limit@2.3.0: @@ -1235,21 +1179,6 @@ packages: p-limit: 2.3.0 dev: false - /p-queue@6.6.2: - resolution: {integrity: sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==} - engines: {node: '>=8'} - dependencies: - eventemitter3: 4.0.7 - p-timeout: 3.2.0 - dev: false - - /p-timeout@3.2.0: - resolution: {integrity: sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==} - engines: {node: '>=8'} - dependencies: - p-finally: 1.0.0 - dev: false - /p-try@2.2.0: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} @@ -1260,14 +1189,6 @@ packages: engines: {node: '>=8'} dev: false - /path-is-absolute@1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} - dev: false - - /path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - /picocolors@1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} @@ -1289,6 +1210,15 @@ packages: nanoid: 3.3.6 picocolors: 1.0.0 source-map-js: 1.0.2 + dev: true + + /postcss@8.4.33: + resolution: {integrity: sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.0 + source-map-js: 1.0.2 /prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} @@ -1298,26 +1228,6 @@ packages: react-is: 16.13.1 dev: false - /query-string@6.14.1: - resolution: {integrity: sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw==} - engines: {node: '>=6'} - dependencies: - decode-uri-component: 0.2.2 - filter-obj: 1.1.0 - split-on-first: 1.1.0 - strict-uri-encode: 2.0.0 - dev: true - - /query-string@7.1.3: - resolution: {integrity: sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==} - engines: {node: '>=6'} - dependencies: - decode-uri-component: 0.2.2 - filter-obj: 1.1.0 - split-on-first: 1.1.0 - strict-uri-encode: 2.0.0 - dev: false - /react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} dev: false @@ -1328,39 +1238,47 @@ packages: dependencies: picomatch: 2.3.1 - /regenerator-runtime@0.13.11: - resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} + /rehackt@0.0.3: + resolution: {integrity: sha512-aBRHudKhOWwsTvCbSoinzq+Lej/7R8e8UoPvLZo5HirZIIBLGAgdG7SL9QpdcBoQ7+3QYPi3lRLknAzXBlhZ7g==} + peerDependencies: + '@types/react': '*' + react: '*' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true dev: false - /resolve@1.22.6: - resolution: {integrity: sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw==} - hasBin: true - dependencies: - is-core-module: 2.13.0 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - /response-iterator@0.2.6: resolution: {integrity: sha512-pVzEEzrsg23Sh053rmDUvLSkGXluZio0qu8VT6ukrYuvtjVfCbDZH9d6PGXb8HZfzdNZt8feXv/jvUzlhRgLnw==} engines: {node: '>=0.8'} dev: false - /rimraf@3.0.2: - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - hasBin: true - dependencies: - glob: 7.2.3 - dev: false - - /roboto-fontface@0.4.1: - resolution: {integrity: sha512-6o8uOKM9EQUZz8O6qoezziPbsdNcEaDXZLXyMcmnDaeqwG1TMtHEROAS2kBWsi/GUxoLBeYdcNKyzDGcBG+QVQ==} + /roboto-fontface@0.10.0: + resolution: {integrity: sha512-OlwfYEgA2RdboZohpldlvJ1xngOins5d7ejqnIBWr9KaMxsnBqotpptRXTyfNRLnFpqzX6sTDt+X+a+6udnU8g==} dev: false - /rollup@3.29.4: - resolution: {integrity: sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==} - engines: {node: '>=14.18.0', npm: '>=8.0.0'} + /rollup@4.9.6: + resolution: {integrity: sha512-05lzkCS2uASX0CiLFybYfVkwNbKZG5NFQ6Go0VWyogFTXXbR039UVsegViTntkk4OglHBdF54ccApXRRuXRbsg==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + dependencies: + '@types/estree': 1.0.5 optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.9.6 + '@rollup/rollup-android-arm64': 4.9.6 + '@rollup/rollup-darwin-arm64': 4.9.6 + '@rollup/rollup-darwin-x64': 4.9.6 + '@rollup/rollup-linux-arm-gnueabihf': 4.9.6 + '@rollup/rollup-linux-arm64-gnu': 4.9.6 + '@rollup/rollup-linux-arm64-musl': 4.9.6 + '@rollup/rollup-linux-riscv64-gnu': 4.9.6 + '@rollup/rollup-linux-x64-gnu': 4.9.6 + '@rollup/rollup-linux-x64-musl': 4.9.6 + '@rollup/rollup-win32-arm64-msvc': 4.9.6 + '@rollup/rollup-win32-ia32-msvc': 4.9.6 + '@rollup/rollup-win32-x64-msvc': 4.9.6 fsevents: 2.3.3 /sass@1.32.0: @@ -1379,48 +1297,6 @@ packages: resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} engines: {node: '>=0.10.0'} - /source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} - - /sourcemap-codec@1.4.8: - resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} - deprecated: Please use @jridgewell/sourcemap-codec instead - - /split-on-first@1.1.0: - resolution: {integrity: sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==} - engines: {node: '>=6'} - - /strict-uri-encode@2.0.0: - resolution: {integrity: sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==} - engines: {node: '>=4'} - - /subscriptions-transport-ws@0.11.0(graphql@16.8.1): - resolution: {integrity: sha512-8D4C6DIH5tGiAIpp5I0wD/xRlNiZAPGHygzCe7VzyzUoxHtawzjNAY9SUTXU05/EY2NMY9/9GF0ycizkXr1CWQ==} - deprecated: The `subscriptions-transport-ws` package is no longer maintained. We recommend you use `graphql-ws` instead. For help migrating Apollo software to `graphql-ws`, see https://www.apollographql.com/docs/apollo-server/data/subscriptions/#switching-from-subscriptions-transport-ws For general help using `graphql-ws`, see https://github.com/enisdenjo/graphql-ws/blob/master/README.md - peerDependencies: - graphql: ^15.7.2 || ^16.0.0 - dependencies: - backo2: 1.0.2 - eventemitter3: 3.1.2 - graphql: 16.8.1 - iterall: 1.3.0 - symbol-observable: 1.2.0 - ws: 7.5.9 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - dev: false - - /supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - - /symbol-observable@1.2.0: - resolution: {integrity: sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==} - engines: {node: '>=0.10.0'} - dev: false - /symbol-observable@4.0.0: resolution: {integrity: sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==} engines: {node: '>=0.10'} @@ -1441,6 +1317,9 @@ packages: dependencies: is-number: 7.0.0 + /tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + /ts-essentials@9.4.0(typescript@4.9.4): resolution: {integrity: sha512-s4BzWZmTh926caZO7XF7MMbwCn1BioT3s3r9hT8ARnwW//30OD0XioEsMyq3ORAHP/deN4Zkst2ZvxXmL+tG6g==} peerDependencies: @@ -1468,8 +1347,8 @@ packages: engines: {node: '>=4.2.0'} hasBin: true - /unload@2.4.1: - resolution: {integrity: sha512-IViSAm8Z3sRBYA+9wc0fLQmU9Nrxb16rcDmIiR6Y9LJSZzI7QY5QsDhqPpKOjAn0O9/kfK1TfNEMMAGPTIraPw==} + /unfetch@4.2.0: + resolution: {integrity: sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==} dev: false /upath@2.0.1: @@ -1477,30 +1356,31 @@ packages: engines: {node: '>=4'} dev: false - /vite-plugin-vuetify@1.0.1(vite@4.0.2)(vue@3.2.41)(vuetify@3.0.0-beta.10): - resolution: {integrity: sha512-/xHsIDuHxq7f6fDqCBYxNascLhDi+X8dV3RzTwmo4mGPrSnGq9pHv8wJsXBIQIT3nY8s16V0lmd6sXMjm0F8wg==} + /vite-plugin-vuetify@1.0.2(vite@5.0.12)(vue@3.4.15)(vuetify@3.0.0-beta.10): + resolution: {integrity: sha512-MubIcKD33O8wtgQXlbEXE7ccTEpHZ8nPpe77y9Wy3my2MWw/PgehP9VqTp92BLqr0R1dSL970Lynvisx3UxBFw==} engines: {node: '>=12'} peerDependencies: vite: ^2.7.0 || ^3.0.0 || ^4.0.0 vuetify: ^3.0.0-beta.4 dependencies: - '@vuetify/loader-shared': 1.7.1(vue@3.2.41)(vuetify@3.0.0-beta.10) + '@vuetify/loader-shared': 1.7.1(vue@3.4.15)(vuetify@3.0.0-beta.10) debug: 4.3.4 upath: 2.0.1 - vite: 4.0.2(sass@1.32.0) - vuetify: 3.0.0-beta.10(vite-plugin-vuetify@1.0.1)(vue@3.2.41) + vite: 5.0.12(sass@1.32.0) + vuetify: 3.0.0-beta.10(vite-plugin-vuetify@1.0.2)(vue@3.4.15) transitivePeerDependencies: - supports-color - vue dev: false - /vite@4.0.2(sass@1.32.0): - resolution: {integrity: sha512-QJaY3R+tFlTagH0exVqbgkkw45B+/bXVBzF2ZD1KB5Z8RiAoiKo60vSUf6/r4c2Vh9jfGBKM4oBI9b4/1ZJYng==} - engines: {node: ^14.18.0 || >=16.0.0} + /vite@5.0.12(sass@1.32.0): + resolution: {integrity: sha512-4hsnEkG3q0N4Tzf1+t6NdN9dg/L3BM+q8SWgbSPnJvrgH2kgdyzfVJwbR1ic69/4uMJJ/3dqDZZE5/WwqW8U1w==} + engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: - '@types/node': '>= 14' + '@types/node': ^18.0.0 || >=20.0.0 less: '*' + lightningcss: ^1.21.0 sass: '*' stylus: '*' sugarss: '*' @@ -1510,6 +1390,8 @@ packages: optional: true less: optional: true + lightningcss: + optional: true sass: optional: true stylus: @@ -1519,15 +1401,14 @@ packages: terser: optional: true dependencies: - esbuild: 0.16.17 - postcss: 8.4.31 - resolve: 1.22.6 - rollup: 3.29.4 + esbuild: 0.19.12 + postcss: 8.4.33 + rollup: 4.9.6 sass: 1.32.0 optionalDependencies: fsevents: 2.3.3 - /vue-demi@0.13.11(vue@3.2.41): + /vue-demi@0.13.11(vue@3.4.15): resolution: {integrity: sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==} engines: {node: '>=12'} hasBin: true @@ -1539,10 +1420,10 @@ packages: '@vue/composition-api': optional: true dependencies: - vue: 3.2.41 + vue: 3.4.15(typescript@4.9.4) dev: false - /vue-demi@0.14.6(vue@3.2.41): + /vue-demi@0.14.6(vue@3.4.15): resolution: {integrity: sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==} engines: {node: '>=12'} hasBin: true @@ -1554,16 +1435,16 @@ packages: '@vue/composition-api': optional: true dependencies: - vue: 3.2.41 + vue: 3.4.15(typescript@4.9.4) dev: false - /vue-router@4.1.6(vue@3.2.41): - resolution: {integrity: sha512-DYWYwsG6xNPmLq/FmZn8Ip+qrhFEzA14EI12MsMgVxvHFDYvlr4NXpVF5hrRH1wVcDP8fGi5F4rxuJSl8/r+EQ==} + /vue-router@4.2.5(vue@3.4.15): + resolution: {integrity: sha512-DIUpKcyg4+PTQKfFPX88UWhlagBEBEfJ5A8XDXRJLUnZOvcpMF8o/dnL90vpVkGaPbjvXazV/rC1qBKrZlFugw==} peerDependencies: vue: ^3.2.0 dependencies: '@vue/devtools-api': 6.5.0 - vue: 3.2.41 + vue: 3.4.15(typescript@4.9.4) dev: false /vue-tsc@0.38.9(typescript@4.9.4): @@ -1576,16 +1457,32 @@ packages: typescript: 4.9.4 dev: true - /vue@3.2.41: - resolution: {integrity: sha512-uuuvnrDXEeZ9VUPljgHkqB5IaVO8SxhPpqF2eWOukVrBnRBx2THPSGQBnVRt0GrIG1gvCmFXMGbd7FqcT1ixNQ==} + /vue3-dropzone@2.2.1(vue@3.4.15): + resolution: {integrity: sha512-TWV/BWTMHePoAcHVn+S5a+a69S1Hwkpdn1LlcBkzvesGZTBqL0TDnKuXWMrF+aWlPLVBUfRJO0uIy9+n2jkDxA==} + peerDependencies: + vue: '>=3' + dependencies: + attr-accept: 2.2.2 + file-selector: 0.2.4 + vue: 3.4.15(typescript@4.9.4) + dev: false + + /vue@3.4.15(typescript@4.9.4): + resolution: {integrity: sha512-jC0GH4KkWLWJOEQjOpkqU1bQsBwf4R1rsFtw5GQJbjHVKWDzO6P0nWWBTmjp1xSemAioDFj1jdaK1qa3DnMQoQ==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true dependencies: - '@vue/compiler-dom': 3.2.41 - '@vue/compiler-sfc': 3.2.41 - '@vue/runtime-dom': 3.2.41 - '@vue/server-renderer': 3.2.41(vue@3.2.41) - '@vue/shared': 3.2.41 + '@vue/compiler-dom': 3.4.15 + '@vue/compiler-sfc': 3.4.15 + '@vue/runtime-dom': 3.4.15 + '@vue/server-renderer': 3.4.15(vue@3.4.15) + '@vue/shared': 3.4.15 + typescript: 4.9.4 - /vuetify@3.0.0-beta.10(vite-plugin-vuetify@1.0.1)(vue@3.2.41): + /vuetify@3.0.0-beta.10(vite-plugin-vuetify@1.0.2)(vue@3.4.15): resolution: {integrity: sha512-xs5wTbDiwqygalhoMyZl8x8NssLPoi6rjUIwQ9b+1g5OqZZAbLquHx7CnJj0dP0GapBucQsjxZIAno3Vq6V3sw==} engines: {node: ^12.20 || >=14.13} peerDependencies: @@ -1604,30 +1501,22 @@ packages: webpack-plugin-vuetify: optional: true dependencies: - vite-plugin-vuetify: 1.0.1(vite@4.0.2)(vue@3.2.41)(vuetify@3.0.0-beta.10) - vue: 3.2.41 + vite-plugin-vuetify: 1.0.2(vite@5.0.12)(vue@3.4.15)(vuetify@3.0.0-beta.10) + vue: 3.4.15(typescript@4.9.4) dev: false - /webfontloader@1.5.14: - resolution: {integrity: sha512-hsBc+7Ix0wq1K64AOP+lrqmDxj+tXDOpoBsIRMsp8OcA/6ZH+DHv9DxbogtoEY/vfl3aAsqzMc5I6ejAj0ucbw==} + /webfontloader@1.6.28: + resolution: {integrity: sha512-Egb0oFEga6f+nSgasH3E0M405Pzn6y3/9tOVanv/DLfa1YBIgcv90L18YyWnvXkRbIM17v5Kv6IT2N6g1x5tvQ==} dev: false - /wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - dev: false + /webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - /ws@7.5.9: - resolution: {integrity: sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==} - engines: {node: '>=8.3.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ^5.0.2 - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - dev: false + /whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 /ws@8.14.2: resolution: {integrity: sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==} @@ -1644,7 +1533,9 @@ packages: /xstate@4.38.2: resolution: {integrity: sha512-Fba/DwEPDLneHT3tbJ9F3zafbQXszOlyCJyQqqdzmtlY/cwE2th462KK48yaANf98jHlP6lJvxfNtN0LFKXPQg==} - dev: false + + /xstate@4.38.3: + resolution: {integrity: sha512-SH7nAaaPQx57dx6qvfcIgqKRXIh4L0A1iYEqim4s1u7c9VoCgzZc+63FY90AKU4ZzOC2cfJzTnpO4zK7fCUzzw==} /zen-observable-ts@1.2.5: resolution: {integrity: sha512-QZWQekv6iB72Naeake9hS1KxHlotfRpe+WGNbNx5/ta+R3DNjVO2bswf63gXlWDcs+EMd7XY8HfVQyP1X6T4Zg==} diff --git a/examples/vue-apollo/src/components/NavBar.vue b/examples/vue-apollo/src/components/NavBar.vue index bb6a1bb488..1bb2dd8a89 100644 --- a/examples/vue-apollo/src/components/NavBar.vue +++ b/examples/vue-apollo/src/components/NavBar.vue @@ -2,6 +2,12 @@ + diff --git a/examples/vue-apollo/src/pages/SecretNotesPage.vue b/examples/vue-apollo/src/pages/SecretNotesPage.vue new file mode 100644 index 0000000000..76dc5d6d5d --- /dev/null +++ b/examples/vue-apollo/src/pages/SecretNotesPage.vue @@ -0,0 +1,96 @@ + + + diff --git a/examples/vue-apollo/src/pages/sign-in/CommonActions.vue b/examples/vue-apollo/src/pages/sign-in/CommonActions.vue index 58fef11ad2..31b3071755 100644 --- a/examples/vue-apollo/src/pages/sign-in/CommonActions.vue +++ b/examples/vue-apollo/src/pages/sign-in/CommonActions.vue @@ -14,4 +14,7 @@ Continue with email + password + + Continue with security key + diff --git a/examples/vue-apollo/src/pages/sign-in/SecurityKey.vue b/examples/vue-apollo/src/pages/sign-in/SecurityKey.vue new file mode 100644 index 0000000000..131b2d92a6 --- /dev/null +++ b/examples/vue-apollo/src/pages/sign-in/SecurityKey.vue @@ -0,0 +1,44 @@ + + + diff --git a/examples/vue-apollo/src/pages/sign-up/CommonActions.vue b/examples/vue-apollo/src/pages/sign-up/CommonActions.vue index 1efc6e6c3a..d2bcf29e3e 100644 --- a/examples/vue-apollo/src/pages/sign-up/CommonActions.vue +++ b/examples/vue-apollo/src/pages/sign-up/CommonActions.vue @@ -14,4 +14,7 @@ Continue with email + password + + Continue with security key + diff --git a/examples/vue-apollo/src/pages/sign-up/SecurityKey.vue b/examples/vue-apollo/src/pages/sign-up/SecurityKey.vue new file mode 100644 index 0000000000..0288ded16d --- /dev/null +++ b/examples/vue-apollo/src/pages/sign-up/SecurityKey.vue @@ -0,0 +1,47 @@ + + + diff --git a/examples/vue-apollo/src/routes.ts b/examples/vue-apollo/src/routes.ts index bdaf6c0c6b..1088e0c0a1 100644 --- a/examples/vue-apollo/src/routes.ts +++ b/examples/vue-apollo/src/routes.ts @@ -2,6 +2,7 @@ import { RouteRecordRaw } from 'vue-router' import AboutPage from './pages/AboutPage.vue' import ApolloPage from './pages/ApolloPage.vue' +import SecretNotes from './pages/SecretNotesPage.vue' import Index from './pages/IndexPage.vue' import Profile from './pages/ProfilePage.vue' import SignInMain from './pages/sign-in/CommonActions.vue' @@ -11,6 +12,8 @@ import SignIn from './pages/sign-in/IndexPage.vue' import SignUpMain from './pages/sign-up/CommonActions.vue' import SignUpEmailPasword from './pages/sign-up/EmailPassword.vue' import SignUpEmailPaswordless from './pages/sign-up/EmailPasswordless.vue' +import SignUpEmailSecurityKey from './pages/sign-up/SecurityKey.vue' +import SignInEmailSecurityKey from './pages/sign-in/SecurityKey.vue' import SignUp from './pages/sign-up/IndexPage.vue' import Signout from './pages/SignoutPage.vue' import StoragePage from './pages/StoragePage.vue' @@ -32,6 +35,10 @@ export const routes: RouteRecordRaw[] = [ { path: 'email-password', component: SignInEmailPasword + }, + { + path: 'security-key', + component: SignInEmailSecurityKey } ] }, @@ -48,9 +55,14 @@ export const routes: RouteRecordRaw[] = [ { path: 'email-password', component: SignUpEmailPasword + }, + { + path: 'security-key', + component: SignUpEmailSecurityKey } ] }, { path: '/apollo', component: ApolloPage, meta: { auth: true } }, + { path: '/secret-notes', component: SecretNotes, meta: { auth: true } }, { path: '/storage', component: StoragePage, meta: { auth: true } } ] diff --git a/examples/vue-apollo/tsconfig.json b/examples/vue-apollo/tsconfig.json index 8301cf97d2..26260be181 100644 --- a/examples/vue-apollo/tsconfig.json +++ b/examples/vue-apollo/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../config/tsconfig.base.json", + // "extends": "../../config/tsconfig.base.json", "compilerOptions": { "target": "ESNext", "useDefineForClassFields": true, diff --git a/packages/hasura-auth-js/nhost/nhost.toml b/packages/hasura-auth-js/nhost/nhost.toml index aba9160af7..465882ff99 100644 --- a/packages/hasura-auth-js/nhost/nhost.toml +++ b/packages/hasura-auth-js/nhost/nhost.toml @@ -70,7 +70,7 @@ enabled = true [auth.method.emailPassword] hibpEnabled = false -emailVerificationRequired = true +emailVerificationRequired = false passwordMinLength = 8 [auth.method.smsPasswordless] diff --git a/packages/hasura-auth-js/src/hasura-auth-client.ts b/packages/hasura-auth-js/src/hasura-auth-client.ts index 25cc5be06a..e183f55659 100644 --- a/packages/hasura-auth-js/src/hasura-auth-client.ts +++ b/packages/hasura-auth-js/src/hasura-auth-client.ts @@ -31,7 +31,8 @@ import { signInSmsPasswordlessPromise, signOutPromise, signUpEmailPasswordPromise, - signUpEmailSecurityKeyPromise + signUpEmailSecurityKeyPromise, + elevateEmailSecurityKeyPromise } from './promises' import { createPATPromise } from './promises/createPAT' import { @@ -438,6 +439,24 @@ export class HasuraAuthClient { return { error, key } } + /** + * Use `nhost.auth.elevateWithSecurityKey` to get a temporary elevated auth permissions to run sensitive operations. + * @param email user email + * + * @docs https://docs.nhost.io/reference/javascript/auth/elevate-security-key + */ + async elevateWebAuthn( + email: string + ): Promise { + if (!email) { + throw Error('A user email is required') + } + + const res = await elevateEmailSecurityKeyPromise(this._client, email) + + return { ...getAuthenticationResult(res), mfa: null } + } + /** * Use `nhost.auth.createPAT` to create a personal access token for the user. * diff --git a/packages/hasura-auth-js/src/machines/index.typegen.ts b/packages/hasura-auth-js/src/machines/index.typegen.ts index 748879124a..274f0e2f2c 100644 --- a/packages/hasura-auth-js/src/machines/index.typegen.ts +++ b/packages/hasura-auth-js/src/machines/index.typegen.ts @@ -125,6 +125,7 @@ export interface Typegen0 { signUpEmailPassword: 'done.invoke.signUpEmailPassword' signUpSecurityKey: 'done.invoke.signUpSecurityKey' signout: 'done.invoke.signingOut' + elevateSecurityKeyEmail: 'done.invoke.elevateSecurityKeyEmail' } missingImplementations: { actions: never @@ -291,6 +292,7 @@ export interface Typegen0 { signUpEmailPassword: 'SIGNUP_EMAIL_PASSWORD' signUpSecurityKey: 'SIGNUP_SECURITY_KEY' signout: 'SIGNOUT' + elevateSecurityKeyEmail: 'ELEVATE_SECURITY_KEY_EMAIL' } eventsCausingGuards: { hasMfaTicket: 'done.invoke.authenticateUserWithPassword' diff --git a/packages/hasura-auth-js/src/promises/elevateEmailSecurityKey.ts b/packages/hasura-auth-js/src/promises/elevateEmailSecurityKey.ts new file mode 100644 index 0000000000..9492bbec1e --- /dev/null +++ b/packages/hasura-auth-js/src/promises/elevateEmailSecurityKey.ts @@ -0,0 +1,83 @@ +import { + AuthenticationCredentialJSON, + PublicKeyCredentialRequestOptionsJSON +} from '@simplewebauthn/typescript-types' +import { + AuthClient, + CodifiedError, + postFetch, + SessionActionHandlerResult, + SignInResponse +} from '..' +import { startAuthentication } from '@simplewebauthn/browser' + +export interface ElevateWithSecurityKeyHandlerResult extends SessionActionHandlerResult { + elevated: boolean +} + +export const elevateEmailSecurityKeyPromise = (authClient: AuthClient, email: string) => + new Promise(async (resolve) => { + const snapshot = authClient.interpreter?.getSnapshot() + const accessToken = snapshot?.context.accessToken.value + + const { data } = await postFetch( + `${authClient.backendUrl}/elevate/webauthn`, + { + email + }, + accessToken + ) + + let credential: AuthenticationCredentialJSON + + try { + credential = await startAuthentication(data) + } catch (e) { + throw new CodifiedError(e as Error) + } + + const { + data: { session }, + error: signInError + } = await postFetch( + `${authClient.backendUrl}/elevate/webauthn/verify`, + { + email, + credential + }, + accessToken + ) + + if (session && !signInError) { + authClient.interpreter?.send({ + type: 'SESSION_UPDATE', + data: { + session + } + }) + } + + authClient.interpreter?.onTransition((state) => { + if (state.matches({ authentication: 'signedIn' })) { + resolve({ + accessToken: state.context.accessToken.value, + refreshToken: state.context.refreshToken.value, + error: null, + isError: false, + isSuccess: true, + user: state.context.user, + elevated: true + }) + } else { + resolve({ + accessToken: state.context.accessToken.value, + refreshToken: state.context.refreshToken.value, + error: null, // TODO pass error + isError: true, + isSuccess: false, + user: state.context.user, + elevated: false + }) + } + }) + }) diff --git a/packages/hasura-auth-js/src/promises/index.ts b/packages/hasura-auth-js/src/promises/index.ts index 741fb10526..e974868fab 100644 --- a/packages/hasura-auth-js/src/promises/index.ts +++ b/packages/hasura-auth-js/src/promises/index.ts @@ -8,6 +8,7 @@ export * from './signInAnonymous' export * from './signInEmailPassword' export * from './signInEmailPasswordless' export * from './signInEmailSecurityKey' +export * from './elevateEmailSecurityKey' export * from './signInMfaTotp' export * from './signInPAT' export * from './signInSmsPasswordless' diff --git a/packages/hasura-auth-js/src/types/hasura-auth/common.ts b/packages/hasura-auth-js/src/types/hasura-auth/common.ts index fd146fb144..de7f562075 100644 --- a/packages/hasura-auth-js/src/types/hasura-auth/common.ts +++ b/packages/hasura-auth-js/src/types/hasura-auth/common.ts @@ -85,6 +85,7 @@ export interface JWTHasuraClaims { 'x-hasura-default-role': string 'x-hasura-user-id': string 'x-hasura-user-is-anonymous': string + 'x-hasura-auth-elevated': string } export interface Mfa { diff --git a/packages/hasura-storage-js/src/hasura-storage-api.ts b/packages/hasura-storage-js/src/hasura-storage-api.ts index 06ee333066..0d9d780d46 100644 --- a/packages/hasura-storage-js/src/hasura-storage-api.ts +++ b/packages/hasura-storage-js/src/hasura-storage-api.ts @@ -1,16 +1,20 @@ import fetchPonyfill from 'fetch-ponyfill' + import LegacyFormData from 'form-data' import { ApiDeleteParams, ApiDeleteResponse, ApiGetPresignedUrlParams, ApiGetPresignedUrlResponse, + StorageDownloadFileParams, + StorageDownloadFileResponse, StorageUploadFileParams, StorageUploadFileResponse, StorageUploadFormDataParams, StorageUploadFormDataResponse } from './utils/types' import { fetchUpload } from './utils/upload' +import { appendImageTransformationParameters } from './utils' let fetch: any @@ -92,6 +96,38 @@ export class HasuraStorageApi { return { fileMetadata, error: null } } + async downloadFile(params: StorageDownloadFileParams): Promise { + try { + const { fileId, headers: customHeaders = {}, ...imageTransformationParams } = params + const authHeaders = this.generateAuthHeaders() + + const headers = new Headers(customHeaders) + authHeaders.forEach((value, key) => { + headers?.append(key, value) + }) + + const urlWithParams = appendImageTransformationParameters( + `${this.url}/files/${fileId}`, + imageTransformationParams + ) + + const response = await fetch(urlWithParams, { + method: 'GET', + headers + }) + + if (!response.ok) { + throw new Error(await response.text()) + } + + const file = await response.blob() + + return { file, error: null } + } catch (error) { + return { file: null, error: error as Error } + } + } + async getPresignedUrl(params: ApiGetPresignedUrlParams): Promise { try { const { fileId } = params @@ -149,19 +185,16 @@ export class HasuraStorageApi { return this } - private generateAuthHeaders(): HeadersInit | undefined { - if (!this.adminSecret && !this.accessToken) { - return undefined - } + private generateAuthHeaders(): Headers { + const headers = new Headers() if (this.adminSecret) { - return { - 'x-hasura-admin-secret': this.adminSecret - } + headers.append('x-hasura-admin-secret', this.adminSecret) } - - return { - Authorization: `Bearer ${this.accessToken}` + if (this.accessToken) { + headers.append('Authorization', `Bearer ${this.accessToken}`) } + + return headers } } diff --git a/packages/hasura-storage-js/src/hasura-storage-client.ts b/packages/hasura-storage-js/src/hasura-storage-client.ts index f7ef1eb3e1..b6b9bda13b 100644 --- a/packages/hasura-storage-js/src/hasura-storage-client.ts +++ b/packages/hasura-storage-js/src/hasura-storage-client.ts @@ -11,7 +11,9 @@ import { StorageUploadFormDataParams, StorageUploadFormDataResponse, StorageUploadParams, - StorageUploadResponse + StorageUploadResponse, + StorageDownloadFileParams, + StorageDownloadFileResponse } from './utils' export interface NhostStorageConstructorParams { @@ -146,6 +148,33 @@ export class HasuraStorageClient { } } + /** + * Use `nhost.storage.download` to download a file. To download a file the user must have permission to select the file in the `storage.files` table. + * + * @example + * ```ts + * const { file, error} = await nhost.storage.download({ fileId: '' }) + * ``` + * + * @docs https://docs.nhost.io/reference/javascript/storage/download + */ + async download(params: StorageDownloadFileParams): Promise { + const { file, error } = await this.api.downloadFile(params) + + if (error) { + return { file: null, error } + } + + if (!file) { + return { file: null, error: new Error('File does not exist') } + } + + return { + file, + error: null + } + } + /** * 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. * diff --git a/packages/hasura-storage-js/src/utils/types.ts b/packages/hasura-storage-js/src/utils/types.ts index c4d6f9c369..d53e0eba2e 100644 --- a/packages/hasura-storage-js/src/utils/types.ts +++ b/packages/hasura-storage-js/src/utils/types.ts @@ -53,6 +53,16 @@ export type StorageUploadFormDataResponse = export type StorageUploadResponse = StorageUploadFileResponse | StorageUploadFormDataResponse +export interface StorageDownloadFileParams extends StorageImageTransformationParams { + fileId: string + /** + * Optional headers to be sent with the request + */ + headers?: Record +} + +export type StorageDownloadFileResponse = { file: Blob; error: null } | { file: null; error: Error } + export interface StorageImageTransformationParams { /** Image width, in pixels */ width?: number diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts index a18fe2bc09..59382e2332 100644 --- a/packages/react/src/index.ts +++ b/packages/react/src/index.ts @@ -23,6 +23,7 @@ export * from './useSignInAnonymous' export * from './useSignInEmailPassword' export * from './useSignInEmailPasswordless' export * from './useSignInEmailSecurityKey' +export * from './useElevateSecurityKeyEmail' export * from './useSignInPAT' export * from './useSignInSmsPasswordless' export * from './useSignOut' diff --git a/packages/react/src/useElevateSecurityKeyEmail.ts b/packages/react/src/useElevateSecurityKeyEmail.ts new file mode 100644 index 0000000000..84cffd16dd --- /dev/null +++ b/packages/react/src/useElevateSecurityKeyEmail.ts @@ -0,0 +1,51 @@ +import { + elevateEmailSecurityKeyPromise, + ElevateWithSecurityKeyHandlerResult +} from '@nhost/nhost-js' +import { useEffect, useState } from 'react' +import { useHasuraClaims } from './useHasuraClaims' +import { useNhostClient } from './useNhostClient' +import { useUserData } from './useUserData' + +interface ElevateWithSecurityKeyHandler { + (email: string): Promise +} + +interface ElevateWithSecurityKeyHook { + elevateEmailSecurityKey: ElevateWithSecurityKeyHandler + elevated: boolean +} + +/** + * Use the hook `useElevateSecurityKeyEmail` to elevate the user auth permission in order to perform sensitive operations + * + * @example + * ```tsx + * const { elevateEmailSecurityKey, elevated } = useElevateSecurityKeyEmail() + * + * console.log({ elevated }); + * + * await elevateEmailSecurityKey('joe@example.com') + * ``` + * + * @docs https://docs.nhost.io/reference/react/elevate-web-authn + */ +export const useElevateSecurityKeyEmail = (): ElevateWithSecurityKeyHook => { + const user = useUserData() + const nhost = useNhostClient() + const claims = useHasuraClaims() + + const [elevated, setElevated] = useState(claims?.['x-hasura-auth-elevated'] === user?.id) + + const elevateEmailSecurityKey: ElevateWithSecurityKeyHandler = (email: string) => + elevateEmailSecurityKeyPromise(nhost.auth.client, email) + + useEffect(() => { + setElevated(claims?.['x-hasura-auth-elevated'] === user?.id) + }, [claims, user]) + + return { + elevated, + elevateEmailSecurityKey + } +} diff --git a/packages/vue/src/index.ts b/packages/vue/src/index.ts index 501d272eb6..824a67d77b 100644 --- a/packages/vue/src/index.ts +++ b/packages/vue/src/index.ts @@ -31,3 +31,6 @@ export * from './useUserId' export * from './useUserIsAnonymous' export * from './useUserLocale' export * from './useUserRoles' +export * from './useElevateSecurityKeyEmail' +export * from './useSignUpEmailSecurityKey' +export * from './useSignInEmailSecurityKey' diff --git a/packages/vue/src/useElevateSecurityKeyEmail.ts b/packages/vue/src/useElevateSecurityKeyEmail.ts new file mode 100644 index 0000000000..6791e1da89 --- /dev/null +++ b/packages/vue/src/useElevateSecurityKeyEmail.ts @@ -0,0 +1,51 @@ +import { + elevateEmailSecurityKeyPromise, + ElevateWithSecurityKeyHandlerResult +} from '@nhost/nhost-js' +import { computed, ref, unref } from 'vue' +import { RefOrValue } from './helpers' +import { useHasuraClaims } from './useHasuraClaims' +import { useNhostClient } from './useNhostClient' +import { useUserData } from './useUserData' + +interface ElevateWithSecurityKeyHandler { + (email: RefOrValue): Promise +} + +interface ElevateWithSecurityKeyResult { + elevateEmailSecurityKey: ElevateWithSecurityKeyHandler + elevated: RefOrValue +} + +/** + * Use the composable `useSignInEmailPassword` to elevate the user auth permission in order to perform sensitive operations + * + * @example + * ```ts + * const { elevateEmailSecurityKey, elevated } = useElevateSecurityKeyEmail() + * + * watchEffect(() => { + * console.log(elevated); + * }) + * + * await elevateEmailSecurityKey('joe@example.com') + * + * ``` + * + * @docs https://docs.nhost.io/reference/vue/use-sign-in-email-password + */ +export const useElevateSecurityKeyEmail = (): ElevateWithSecurityKeyResult => { + const user = useUserData() + const claims = useHasuraClaims() + const { nhost } = useNhostClient() + + const elevated = computed(() => claims.value?.['x-hasura-auth-elevated'] === user.value?.id) + + const elevateEmailSecurityKey: ElevateWithSecurityKeyHandler = (email: RefOrValue) => + elevateEmailSecurityKeyPromise(nhost.auth.client, unref(email)) + + return { + elevateEmailSecurityKey, + elevated + } +} diff --git a/packages/vue/src/useSignInEmailSecurityKey.ts b/packages/vue/src/useSignInEmailSecurityKey.ts new file mode 100644 index 0000000000..4904e40fc1 --- /dev/null +++ b/packages/vue/src/useSignInEmailSecurityKey.ts @@ -0,0 +1,99 @@ +import { + signInEmailSecurityKeyPromise, + SignInSecurityKeyPasswordlessHandlerResult, + SignInSecurityKeyPasswordlessState +} from '@nhost/nhost-js' +import { useSelector } from '@xstate/vue' +import { ToRefs, unref } from 'vue' +import { RefOrValue } from './helpers' +import { useAuthInterpreter } from './useAuthInterpreter' + +interface SignInSecurityKeyPasswordlessHandler { + (email: RefOrValue): Promise +} + +export interface SignInSecurityKeyPasswordlessHookResult + extends ToRefs { + signInEmailSecurityKey: SignInSecurityKeyPasswordlessHandler +} + +interface SignInSecurityKeyPasswordlessResult { + (): SignInSecurityKeyPasswordlessHookResult +} + +/** + * Use the composable `useSignInEmailSecurityKey` to sign in a user using their email and a security key using the WebAuthn API. + * + * @example + * ```tsx + * const { signInEmailSecurityKey, needsEmailVerification, isLoading, isSuccess, isError, error } = useSignInEmailSecurityKey() + * + * console.log({ needsEmailVerification, isLoading, isSuccess, isError, error }); + * + * const handleFormSubmit = async (e) => { + * e.preventDefault(); + * + * await signInEmailSecurityKey('joe@example.com') + * } + * ``` + * + * @docs https://docs.nhost.io/reference/vue/use-sign-in-web-authn + */ +export const useSignInEmailSecurityKey: SignInSecurityKeyPasswordlessResult = () => { + const service = useAuthInterpreter() + const signInEmailSecurityKey: SignInSecurityKeyPasswordlessHandler = ( + email: RefOrValue + ) => signInEmailSecurityKeyPromise(service.value, unref(email)) + + const user = useSelector( + service.value, + (state) => state.context.user, + (a, b) => a?.id === b?.id + ) + const accessToken = useSelector(service.value, (state) => state.context.accessToken.value) + + const refreshToken = useSelector(service.value, (state) => state.context.refreshToken.value) + + const error = useSelector( + service.value, + (state) => state.context.errors.authentication || null, + (a, b) => a?.error === b?.error + ) + const isSuccess = useSelector(service.value, (state) => + state.matches({ + authentication: 'signedIn' + }) + ) + const isLoading = useSelector( + service.value, + (state) => state.matches({ authentication: { authenticating: 'securityKeyEmail' } }), + (a, b) => a === b + ) + + const needsEmailVerification = useSelector( + service.value, + (state) => + state.matches({ + authentication: { signedOut: 'noErrors' }, + registration: { incomplete: 'needsEmailVerification' } + }), + (a, b) => a === b + ) + const isError = useSelector( + service.value, + (state) => state.matches({ authentication: { signedOut: 'failed' } }), + (a, b) => a === b + ) + + return { + accessToken, + refreshToken, + error, + isError, + isLoading, + isSuccess, + needsEmailVerification, + signInEmailSecurityKey, + user + } +} diff --git a/packages/vue/src/useSignUpEmailSecurityKey.ts b/packages/vue/src/useSignUpEmailSecurityKey.ts new file mode 100644 index 0000000000..d0adebea99 --- /dev/null +++ b/packages/vue/src/useSignUpEmailSecurityKey.ts @@ -0,0 +1,95 @@ +import { + signUpEmailSecurityKeyPromise, + SignUpSecurityKeyOptions, + SignUpSecurityKeyState +} from '@nhost/nhost-js' +import { useSelector } from '@xstate/vue' +import { ToRefs, unref } from 'vue' +import { RefOrValue } from './helpers' +import { useAuthInterpreter } from './useAuthInterpreter' + +type SignUpSecurityKeyHandlerResult = Omit + +interface SignUpSecurityKeyHandler { + ( + email: RefOrValue, + options?: RefOrValue + ): Promise +} + +export interface SignUpSecurityKeyHookResult extends ToRefs { + /** Used for a new user to sign up with a security key. Returns a promise with the current context */ + signUpEmailSecurityKey: SignUpSecurityKeyHandler +} + +interface SignUpSecurityKeyResult { + (options?: SignUpSecurityKeyOptions): SignUpSecurityKeyHookResult +} + +/** + * Use the composable `useSignUpEmailSecurityKey` to sign up a user with security key and an email using the WebAuthn API. + * + * @example + * ```ts + * const { signUpEmailSecurityKey, needsEmailVerification, isLoading, isSuccess, isError, error } = useSignUpEmailSecurityKey() + * + * console.log({ needsEmailVerification, isLoading, isSuccess, isError, error }); + * + * const handleFormSubmit = async (e) => { + * e.preventDefault(); + * + * await signUpEmailSecurityKey('joe@example.com') + * } + * ``` + * + * @docs https://docs.nhost.io/reference/vue/use-sign-up-security-key + */ +export const useSignUpEmailSecurityKey: SignUpSecurityKeyResult = ( + hookOptions?: SignUpSecurityKeyOptions +) => { + const service = useAuthInterpreter() + const isError = useSelector(service.value, (state) => !!state.context.errors.registration) + + const error = useSelector( + service.value, + (state) => state.context.errors.registration || null, + (a, b) => a?.error === b?.error + ) + + const isLoading = useSelector(service.value, (state) => state.matches('registration.securityKey')) + + const needsEmailVerification = useSelector(service.value, (state) => + state.matches('registration.incomplete.needsEmailVerification') + ) + + const isSuccess = useSelector(service.value, (state) => + state.matches({ + authentication: 'signedIn', + registration: 'complete' + }) + ) + + const signUpEmailSecurityKey: SignUpSecurityKeyHandler = (email, options = hookOptions) => + signUpEmailSecurityKeyPromise(service.value, unref(email), unref(options)) + + const user = useSelector( + service.value, + (state) => state.context.user, + (a, b) => a?.id === b?.id + ) + const accessToken = useSelector(service.value, (state) => state.context.accessToken.value) + + const refreshToken = useSelector(service.value, (state) => state.context.refreshToken.value) + + return { + accessToken, + refreshToken, + error, + isError, + isLoading, + isSuccess, + needsEmailVerification, + signUpEmailSecurityKey, + user + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index da6fe7af16..4d59d25130 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1139,7 +1139,7 @@ importers: version: 0.6.5(ws@8.16.0)(xstate@4.38.3) dotenv: specifier: ^16.3.1 - version: 16.3.2 + version: 16.4.1 jsqr: specifier: ^1.4.0 version: 1.4.0 @@ -3617,6 +3617,13 @@ packages: dependencies: regenerator-runtime: 0.14.1 + /@babel/runtime@7.23.9: + resolution: {integrity: sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.14.1 + dev: false + /@babel/runtime@7.5.5: resolution: {integrity: sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ==} dependencies: @@ -5610,7 +5617,7 @@ packages: '@whatwg-node/fetch': 0.8.8 chalk: 4.1.2 debug: 4.3.4 - dotenv: 16.3.2 + dotenv: 16.4.1 graphql: 16.8.1 graphql-request: 6.1.0(encoding@0.1.13)(graphql@16.8.1) http-proxy-agent: 6.1.1 @@ -5642,7 +5649,7 @@ packages: '@whatwg-node/fetch': 0.8.8 chalk: 4.1.2 debug: 4.3.4 - dotenv: 16.3.2 + dotenv: 16.4.1 graphql: 16.8.1 graphql-request: 6.1.0(encoding@0.1.13)(graphql@16.8.1) http-proxy-agent: 6.1.1 @@ -7598,7 +7605,7 @@ packages: engines: {node: '>=14'} hasBin: true dependencies: - '@types/node': 20.5.6 + '@types/node': 20.11.10 playwright-core: 1.31.0 optionalDependencies: fsevents: 2.3.2 @@ -10567,7 +10574,7 @@ packages: /@types/cors@2.8.17: resolution: {integrity: sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==} dependencies: - '@types/node': 18.19.8 + '@types/node': 20.11.10 dev: true /@types/debug@4.1.12: @@ -10818,6 +10825,12 @@ packages: undici-types: 5.26.5 dev: true + /@types/node@20.11.10: + resolution: {integrity: sha512-rZEfe/hJSGYmdfX9tvcPMYeYPW2sNl50nsw4jZmRcaG0HIAb0WYEpsB05GOb53vjqpyE9GUhlDQ4jLSoB5q9kg==} + dependencies: + undici-types: 5.26.5 + dev: true + /@types/node@20.5.6: resolution: {integrity: sha512-Gi5wRGPbbyOTX+4Y2iULQ27oUPrefaB0PxGQJnfyWN3kvEDGM3mIB5M/gQLmitZf7A9FmLeaqxD3L1CXpm3VKQ==} @@ -10853,7 +10866,7 @@ packages: /@types/pngjs@6.0.4: resolution: {integrity: sha512-atAK9xLKOnxiuArxcHovmnOUUGBZOQ3f0vCf43FnoKs6XnqiambT1kkJWmdo71IR+BoXSh+CueeFR0GfH3dTlQ==} dependencies: - '@types/node': 20.5.6 + '@types/node': 20.11.10 dev: true /@types/prettier@2.7.3: @@ -10945,7 +10958,7 @@ packages: /@types/set-cookie-parser@2.4.7: resolution: {integrity: sha512-+ge/loa0oTozxip6zmhRIk8Z/boU51wl9Q6QdLZcokIGMzY5lFXYy/x7Htj2HTC6/KZP1hUbZ1ekx8DYXICvWg==} dependencies: - '@types/node': 20.5.6 + '@types/node': 16.18.74 dev: true /@types/shell-quote@1.7.5: @@ -11045,7 +11058,7 @@ packages: /@types/ws@8.5.10: resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==} dependencies: - '@types/node': 18.19.8 + '@types/node': 16.18.74 dev: true /@types/yargs-parser@21.0.3: @@ -15398,6 +15411,11 @@ packages: resolution: {integrity: sha512-HTlk5nmhkm8F6JcdXvHIzaorzCoziNQT9mGxLPVXW8wJF1TiGSL60ZGB4gHWabHOaMmWmhvk2/lPHfnBiT78AQ==} engines: {node: '>=12'} + /dotenv@16.4.1: + resolution: {integrity: sha512-CjA3y+Dr3FyFDOAMnxZEGtnW9KBR2M0JvvUtXNW+dYJL5ROWxP9DUHCwgFqpMk0OXCc0ljhaNTr2w/kutYIcHQ==} + engines: {node: '>=12'} + dev: true + /dotenv@8.6.0: resolution: {integrity: sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==} engines: {node: '>=10'} @@ -15529,7 +15547,7 @@ packages: dependencies: '@types/cookie': 0.4.1 '@types/cors': 2.8.17 - '@types/node': 18.19.8 + '@types/node': 20.11.10 accepts: 1.3.8 base64id: 2.0.0 cookie: 0.4.2 @@ -24706,7 +24724,7 @@ packages: peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: - '@babel/runtime': 7.23.8 + '@babel/runtime': 7.23.9 react: 18.2.0 use-composed-ref: 1.3.0(react@18.2.0) use-latest: 1.2.1(@types/react@18.2.47)(react@18.2.0)