From ef1531e56105c006bf1d7dfb9c5e31d1e7fadf16 Mon Sep 17 00:00:00 2001 From: Hayden <64056131+hay-kot@users.noreply.github.com> Date: Fri, 2 Jun 2023 14:56:40 -0700 Subject: [PATCH] feat: easily increment quantity (#473) * fix vue version issue * new patch API endpoint * doc-gen * new API class method for patch operations * add quantity patch UI support * fix typegen errors * fix ts errors --- backend/app/api/handlers/v1/v1_ctrl_items.go | 27 +++ backend/app/api/routes.go | 1 + backend/app/api/static/docs/docs.go | 53 ++++++ backend/app/api/static/docs/swagger.json | 53 ++++++ backend/app/api/static/docs/swagger.yaml | 34 ++++ backend/app/tools/typegen/main.go | 1 + backend/go.sum | 4 + backend/internal/data/repo/repo_items.go | 2 +- docs/docs/api/openapi-2.0.json | 53 ++++++ frontend/lib/api/classes/items.ts | 15 ++ frontend/lib/api/types/data-contracts.ts | 21 +- frontend/lib/requests/requests.ts | 7 +- frontend/package.json | 2 +- frontend/pages/item/[id]/index.vue | 41 +++- frontend/pages/item/[id]/index/edit.vue | 12 +- frontend/pnpm-lock.yaml | 190 +++++-------------- 16 files changed, 353 insertions(+), 163 deletions(-) diff --git a/backend/app/api/handlers/v1/v1_ctrl_items.go b/backend/app/api/handlers/v1/v1_ctrl_items.go index c6cd328..c6bb1f9 100644 --- a/backend/app/api/handlers/v1/v1_ctrl_items.go +++ b/backend/app/api/handlers/v1/v1_ctrl_items.go @@ -167,6 +167,33 @@ func (ctrl *V1Controller) HandleItemUpdate() errchain.HandlerFunc { return adapters.ActionID("id", fn, http.StatusOK) } + +// HandleItemPatch godocs +// +// @Summary Update Item +// @Tags Items +// @Produce json +// @Param id path string true "Item ID" +// @Param payload body repo.ItemPatch true "Item Data" +// @Success 200 {object} repo.ItemOut +// @Router /v1/items/{id} [Patch] +// @Security Bearer +func (ctrl *V1Controller) HandleItemPatch() errchain.HandlerFunc { + fn := func(r *http.Request, ID uuid.UUID, body repo.ItemPatch) (repo.ItemOut, error) { + auth := services.NewContext(r.Context()) + + body.ID = ID + err := ctrl.repo.Items.Patch(auth, auth.GID, ID, body) + if err != nil { + return repo.ItemOut{}, err + } + + return ctrl.repo.Items.GetOneByGroup(auth, auth.GID, ID) + } + + return adapters.ActionID("id", fn, http.StatusOK) +} + // HandleGetAllCustomFieldNames godocs // // @Summary Get All Custom Field Names diff --git a/backend/app/api/routes.go b/backend/app/api/routes.go index affc79f..abf14fd 100644 --- a/backend/app/api/routes.go +++ b/backend/app/api/routes.go @@ -113,6 +113,7 @@ func (a *app) mountRoutes(r *chi.Mux, chain *errchain.ErrChain, repos *repo.AllR r.Get(v1Base("/items/{id}"), chain.ToHandlerFunc(v1Ctrl.HandleItemGet(), userMW...)) r.Put(v1Base("/items/{id}"), chain.ToHandlerFunc(v1Ctrl.HandleItemUpdate(), userMW...)) + r.Patch(v1Base("/items/{id}"), chain.ToHandlerFunc(v1Ctrl.HandleItemPatch(), userMW...)) r.Delete(v1Base("/items/{id}"), chain.ToHandlerFunc(v1Ctrl.HandleItemDelete(), userMW...)) r.Post(v1Base("/items/{id}/attachments"), chain.ToHandlerFunc(v1Ctrl.HandleItemAttachmentCreate(), userMW...)) diff --git a/backend/app/api/static/docs/docs.go b/backend/app/api/static/docs/docs.go index 7c7da2d..30ee544 100644 --- a/backend/app/api/static/docs/docs.go +++ b/backend/app/api/static/docs/docs.go @@ -635,6 +635,46 @@ const docTemplate = `{ "description": "No Content" } } + }, + "patch": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Items" + ], + "summary": "Update Item", + "parameters": [ + { + "type": "string", + "description": "Item ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Item Data", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/repo.ItemPatch" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/repo.ItemOut" + } + } + } } }, "/v1/items/{id}/attachments": { @@ -2042,6 +2082,19 @@ const docTemplate = `{ } } }, + "repo.ItemPatch": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "quantity": { + "type": "integer", + "x-nullable": true, + "x-omitempty": true + } + } + }, "repo.ItemSummary": { "type": "object", "properties": { diff --git a/backend/app/api/static/docs/swagger.json b/backend/app/api/static/docs/swagger.json index 818dfe6..3c390f2 100644 --- a/backend/app/api/static/docs/swagger.json +++ b/backend/app/api/static/docs/swagger.json @@ -627,6 +627,46 @@ "description": "No Content" } } + }, + "patch": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Items" + ], + "summary": "Update Item", + "parameters": [ + { + "type": "string", + "description": "Item ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Item Data", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/repo.ItemPatch" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/repo.ItemOut" + } + } + } } }, "/v1/items/{id}/attachments": { @@ -2034,6 +2074,19 @@ } } }, + "repo.ItemPatch": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "quantity": { + "type": "integer", + "x-nullable": true, + "x-omitempty": true + } + } + }, "repo.ItemSummary": { "type": "object", "properties": { diff --git a/backend/app/api/static/docs/swagger.yaml b/backend/app/api/static/docs/swagger.yaml index cc6c467..e77257a 100644 --- a/backend/app/api/static/docs/swagger.yaml +++ b/backend/app/api/static/docs/swagger.yaml @@ -191,6 +191,15 @@ definitions: warrantyExpires: type: string type: object + repo.ItemPatch: + properties: + id: + type: string + quantity: + type: integer + x-nullable: true + x-omitempty: true + type: object repo.ItemSummary: properties: archived: @@ -992,6 +1001,31 @@ paths: summary: Get Item tags: - Items + patch: + parameters: + - description: Item ID + in: path + name: id + required: true + type: string + - description: Item Data + in: body + name: payload + required: true + schema: + $ref: '#/definitions/repo.ItemPatch' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/repo.ItemOut' + security: + - Bearer: [] + summary: Update Item + tags: + - Items put: parameters: - description: Item ID diff --git a/backend/app/tools/typegen/main.go b/backend/app/tools/typegen/main.go index bc04cc9..5f4d8da 100644 --- a/backend/app/tools/typegen/main.go +++ b/backend/app/tools/typegen/main.go @@ -54,6 +54,7 @@ func main() { NewReReplace(` Services`, " "), NewReReplace(` V1`, " "), NewReReplace(`\?:`, ":"), + NewReReplace(`(\w+):\s(.*null.*)`, "$1?: $2"), // make null union types optional NewReDate("createdAt"), NewReDate("updatedAt"), NewReDate("soldTime"), diff --git a/backend/go.sum b/backend/go.sum index 2746d2f..d35f134 100644 --- a/backend/go.sum +++ b/backend/go.sum @@ -506,6 +506,7 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -531,6 +532,7 @@ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRW github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= @@ -602,8 +604,10 @@ github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrf github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= +github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.14.0/go.mod h1:WT//axPky3FdvXHzGw33dNdXXXfFQqmEalje+egj8As= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= diff --git a/backend/internal/data/repo/repo_items.go b/backend/internal/data/repo/repo_items.go index 3e263cc..3f3c11b 100644 --- a/backend/internal/data/repo/repo_items.go +++ b/backend/internal/data/repo/repo_items.go @@ -104,7 +104,7 @@ type ( ItemPatch struct { ID uuid.UUID `json:"id"` Quantity *int `json:"quantity,omitempty" extensions:"x-nullable,x-omitempty"` - ImportRef *string `json:"importRef,omitempty" extensions:"x-nullable,x-omitempty"` + ImportRef *string `json:"-,omitempty" extensions:"x-nullable,x-omitempty"` } ItemSummary struct { diff --git a/docs/docs/api/openapi-2.0.json b/docs/docs/api/openapi-2.0.json index 818dfe6..3c390f2 100644 --- a/docs/docs/api/openapi-2.0.json +++ b/docs/docs/api/openapi-2.0.json @@ -627,6 +627,46 @@ "description": "No Content" } } + }, + "patch": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Items" + ], + "summary": "Update Item", + "parameters": [ + { + "type": "string", + "description": "Item ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Item Data", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/repo.ItemPatch" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/repo.ItemOut" + } + } + } } }, "/v1/items/{id}/attachments": { @@ -2034,6 +2074,19 @@ } } }, + "repo.ItemPatch": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "quantity": { + "type": "integer", + "x-nullable": true, + "x-omitempty": true + } + } + }, "repo.ItemSummary": { "type": "object", "properties": { diff --git a/frontend/lib/api/classes/items.ts b/frontend/lib/api/classes/items.ts index b7cc17d..1a49f26 100644 --- a/frontend/lib/api/classes/items.ts +++ b/frontend/lib/api/classes/items.ts @@ -4,6 +4,7 @@ import { ItemAttachmentUpdate, ItemCreate, ItemOut, + ItemPatch, ItemSummary, ItemUpdate, MaintenanceEntry, @@ -138,6 +139,20 @@ export class ItemsApi extends BaseAPI { return payload; } + async patch(id: string, item: ItemPatch) { + const resp = await this.http.patch({ + url: route(`/items/${id}`), + body: this.dropFields(item), + }); + + if (!resp.data) { + return resp; + } + + resp.data = parseDate(resp.data, ["purchaseTime", "soldTime", "warrantyExpires"]); + return resp; + } + import(file: File | Blob) { const formData = new FormData(); formData.append("csv", file); diff --git a/frontend/lib/api/types/data-contracts.ts b/frontend/lib/api/types/data-contracts.ts index 98fad70..a2d7209 100644 --- a/frontend/lib/api/types/data-contracts.ts +++ b/frontend/lib/api/types/data-contracts.ts @@ -67,7 +67,7 @@ export interface ItemCreate { * @maxLength 255 */ name: string; - parentId: string | null; + parentId?: string | null; } export interface ItemField { @@ -94,13 +94,13 @@ export interface ItemOut { /** Warranty */ lifetimeWarranty: boolean; /** Edges */ - location: LocationSummary | null; + location?: LocationSummary | null; manufacturer: string; modelNumber: string; name: string; /** Extras */ notes: string; - parent: ItemSummary | null; + parent?: ItemSummary | null; purchaseFrom: string; /** @example "0" */ purchasePrice: string; @@ -119,6 +119,11 @@ export interface ItemOut { warrantyExpires: Date | string; } +export interface ItemPatch { + id: string; + quantity?: number | null; +} + export interface ItemSummary { archived: boolean; createdAt: Date | string; @@ -127,7 +132,7 @@ export interface ItemSummary { insured: boolean; labels: LabelSummary[]; /** Edges */ - location: LocationSummary | null; + location?: LocationSummary | null; name: string; /** @example "0" */ purchasePrice: string; @@ -152,7 +157,7 @@ export interface ItemUpdate { name: string; /** Extras */ notes: string; - parentId: string | null; + parentId?: string | null; purchaseFrom: string; /** @example "0" */ purchasePrice: string; @@ -203,7 +208,7 @@ export interface LabelSummary { export interface LocationCreate { description: string; name: string; - parentId: string | null; + parentId?: string | null; } export interface LocationOut { @@ -238,7 +243,7 @@ export interface LocationUpdate { description: string; id: string; name: string; - parentId: string | null; + parentId?: string | null; } export interface MaintenanceEntry { @@ -309,7 +314,7 @@ export interface NotifierUpdate { * @maxLength 255 */ name: string; - url: string | null; + url?: string | null; } export interface PaginationResultItemSummary { diff --git a/frontend/lib/requests/requests.ts b/frontend/lib/requests/requests.ts index 32b79bc..8aecda1 100644 --- a/frontend/lib/requests/requests.ts +++ b/frontend/lib/requests/requests.ts @@ -3,6 +3,7 @@ export enum Method { POST = "POST", PUT = "PUT", DELETE = "DELETE", + PATCH = "PATCH", } export type ResponseInterceptor = (r: Response, rq?: RequestInit) => void; @@ -57,12 +58,16 @@ export class Requests { return this.do(Method.PUT, args); } + public patch(args: RequestArgs): Promise> { + return this.do(Method.PATCH, args); + } + public delete(args: RequestArgs): Promise> { return this.do(Method.DELETE, args); } private methodSupportsBody(method: Method): boolean { - return method === Method.POST || method === Method.PUT; + return method === Method.POST || method === Method.PUT || method === Method.PATCH; } private async do(method: Method, rargs: RequestArgs): Promise> { diff --git a/frontend/package.json b/frontend/package.json index e087868..1790450 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -50,7 +50,7 @@ "pinia": "^2.0.21", "postcss": "^8.4.16", "tailwindcss": "^3.1.8", - "vue": "^3.2.45", + "vue": "^3.3.1", "vue-chartjs": "^4.1.2", "vue-router": "4" } diff --git a/frontend/pages/item/[id]/index.vue b/frontend/pages/item/[id]/index.vue index e9fb281..9271675 100644 --- a/frontend/pages/item/[id]/index.vue +++ b/frontend/pages/item/[id]/index.vue @@ -39,6 +39,30 @@ lastRoute.value = route.fullPath; }); + async function adjustQuantity(amount: number) { + if (!item.value) { + return; + } + + const newQuantity = item.value.quantity + amount; + if (newQuantity < 0) { + toast.error("Quantity cannot be negative"); + return; + } + + const resp = await api.items.patch(item.value.id, { + id: item.value.id, + quantity: newQuantity, + }); + + if (resp.error) { + toast.error("Failed to adjust quantity"); + return; + } + + item.value.quantity = newQuantity; + } + type FilteredAttachments = { attachments: ItemAttachment[]; warranty: ItemAttachment[]; @@ -130,6 +154,7 @@ { name: "Quantity", text: item.value?.quantity, + slot: "quantity", }, { name: "Serial Number", @@ -475,7 +500,21 @@ - + + + diff --git a/frontend/pages/item/[id]/index/edit.vue b/frontend/pages/item/[id]/index/edit.vue index f40ce91..7479df7 100644 --- a/frontend/pages/item/[id]/index/edit.vue +++ b/frontend/pages/item/[id]/index/edit.vue @@ -75,6 +75,7 @@ toast.success("Item saved"); navigateTo("/item/" + itemId.value); } + type NoUndefinedField = { [P in keyof T]-?: NoUndefinedField> }; type StringKeys = { [k in keyof T]: T[k] extends string ? k : never }[keyof T]; type OnlyString = { [k in StringKeys]: string }; @@ -86,13 +87,13 @@ type: "text" | "textarea"; label: string; // key of ItemOut where the value is a string - ref: keyof OnlyString; + ref: keyof OnlyString>; }; type NumberFormField = { type: "number"; label: string; - ref: keyof OnlyNumber | keyof OnlyString; + ref: keyof OnlyNumber> | keyof OnlyString>; }; // https://stackoverflow.com/questions/50851263/how-do-i-require-a-keyof-to-be-for-a-property-of-a-specific-type @@ -103,7 +104,7 @@ interface BoolFormField { type: "checkbox"; label: string; - ref: keyof OnlyBoolean; + ref: keyof OnlyBoolean>; } type DateKeys = { [k in keyof T]: T[k] extends Date | string ? k : never }[keyof T]; @@ -112,7 +113,7 @@ type DateFormField = { type: "date"; label: string; - ref: keyof OnlyDate; + ref: keyof OnlyDate>; }; type FormField = TextFormField | BoolFormField | DateFormField | NumberFormField; @@ -184,6 +185,7 @@ { type: "date", label: "Purchase Date", + // @ts-expect-error - we know this is a date ref: "purchaseTime", }, ]; @@ -197,6 +199,7 @@ { type: "date", label: "Warranty Expires", + // @ts-expect-error - we know this is a date ref: "warrantyExpires", }, { @@ -220,6 +223,7 @@ { type: "date", label: "Sold At", + // @ts-expect-error - we know this is a date ref: "soldTime", }, ]; diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 57d729f..710c803 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -7,16 +7,16 @@ settings: dependencies: '@headlessui/vue': specifier: ^1.7.9 - version: 1.7.9(vue@3.2.47) + version: 1.7.9(vue@3.3.4) '@iconify/vue': specifier: ^3.2.1 - version: 3.2.1(vue@3.2.47) + version: 3.2.1(vue@3.3.4) '@nuxtjs/tailwindcss': specifier: ^6.1.3 version: 6.1.3(rollup@2.79.1)(webpack@5.77.0) '@pinia/nuxt': specifier: ^0.4.1 - version: 0.4.6(rollup@2.79.1)(typescript@5.0.2)(vue@3.2.47) + version: 0.4.6(rollup@2.79.1)(typescript@5.0.2)(vue@3.3.4) '@tailwindcss/aspect-ratio': specifier: ^0.4.0 version: 0.4.2(tailwindcss@3.2.4) @@ -28,10 +28,10 @@ dependencies: version: 0.5.8(tailwindcss@3.2.4) '@vueuse/nuxt': specifier: ^10.0.0 - version: 10.0.0(nuxt@3.5.1)(rollup@2.79.1)(vue@3.2.47) + version: 10.0.0(nuxt@3.5.1)(rollup@2.79.1)(vue@3.3.4) '@vueuse/router': specifier: ^10.0.0 - version: 10.0.0(vue-router@4.1.6)(vue@3.2.47) + version: 10.0.0(vue-router@4.1.6)(vue@3.3.4) autoprefixer: specifier: ^10.4.8 version: 10.4.13(postcss@8.4.19) @@ -49,7 +49,7 @@ dependencies: version: 13.0.1 pinia: specifier: ^2.0.21 - version: 2.0.28(typescript@5.0.2)(vue@3.2.47) + version: 2.0.28(typescript@5.0.2)(vue@3.3.4) postcss: specifier: ^8.4.16 version: 8.4.19 @@ -57,14 +57,14 @@ dependencies: specifier: ^3.1.8 version: 3.2.4(postcss@8.4.19) vue: - specifier: ^3.2.45 - version: 3.2.47 + specifier: ^3.3.1 + version: 3.3.4 vue-chartjs: specifier: ^4.1.2 - version: 4.1.2(chart.js@4.0.1)(vue@3.2.47) + version: 4.1.2(chart.js@4.0.1)(vue@3.3.4) vue-router: specifier: '4' - version: 4.1.6(vue@3.2.47) + version: 4.1.6(vue@3.3.4) devDependencies: '@faker-js/faker': @@ -457,14 +457,6 @@ packages: chalk: 2.4.2 js-tokens: 4.0.0 - /@babel/parser@7.20.13: - resolution: {integrity: sha512-gFDLKMfpiXCsjt4za2JA9oTMn70CeseCehb11kRZgvd7+F67Hih3OHOK24cRrWECJ/ljfPGac6ygXAs/C8kIvw==} - engines: {node: '>=6.0.0'} - hasBin: true - dependencies: - '@babel/types': 7.20.7 - dev: false - /@babel/parser@7.21.4: resolution: {integrity: sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw==} engines: {node: '>=6.0.0'} @@ -1830,13 +1822,13 @@ packages: engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0, npm: '>=6.14.13'} dev: true - /@headlessui/vue@1.7.9(vue@3.2.47): + /@headlessui/vue@1.7.9(vue@3.3.4): resolution: {integrity: sha512-vgLBKszj+m2ozaPOnjWMGnspoLJcU/06vygdEAyAS4nDjp72yA7AYbOIEgdaspUhaMs585ApyiSm3jPTuIxAzg==} engines: {node: '>=10'} peerDependencies: vue: ^3.2.0 dependencies: - vue: 3.2.47 + vue: 3.3.4 dev: false /@humanwhocodes/config-array@0.11.7: @@ -1856,12 +1848,12 @@ packages: /@humanwhocodes/object-schema@1.2.1: resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} - /@iconify/vue@3.2.1(vue@3.2.47): + /@iconify/vue@3.2.1(vue@3.3.4): resolution: {integrity: sha512-c4R6ZgFo1JrJ8aPMMgOPgfU7lBswihMGR+yWe/P4ZukC3kTkeT4+lkt9Pc/itVFMkwva/S/7u9YofmYv57fnNQ==} peerDependencies: vue: 3.x dependencies: - vue: 3.2.47 + vue: 3.3.4 dev: false /@ioredis/commands@1.2.0: @@ -2270,11 +2262,11 @@ packages: - webpack dev: false - /@pinia/nuxt@0.4.6(rollup@2.79.1)(typescript@5.0.2)(vue@3.2.47): + /@pinia/nuxt@0.4.6(rollup@2.79.1)(typescript@5.0.2)(vue@3.3.4): resolution: {integrity: sha512-HjrYEfLdFpmsjhicPJgL36jVhzHWukIQPFFHGTSF84Cplu+f2nY2XHKqe9ToHzE9rLee2RjLOwAzOnXa/I/u6A==} dependencies: '@nuxt/kit': 3.0.0(rollup@2.79.1) - pinia: 2.0.28(typescript@5.0.2)(vue@3.2.47) + pinia: 2.0.28(typescript@5.0.2)(vue@3.3.4) transitivePeerDependencies: - '@vue/composition-api' - rollup @@ -2942,55 +2934,24 @@ packages: - '@babel/core' - supports-color - /@vue/compiler-core@3.2.47: - resolution: {integrity: sha512-p4D7FDnQb7+YJmO2iPEv0SQNeNzcbHdGByJDsT4lynf63AFkOTFN07HsiRSvjGo0QrxR/o3d0hUyNCUnBU2Tig==} - dependencies: - '@babel/parser': 7.20.13 - '@vue/shared': 3.2.47 - estree-walker: 2.0.2 - source-map: 0.6.1 - dev: false - /@vue/compiler-core@3.3.4: resolution: {integrity: sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==} dependencies: - '@babel/parser': 7.21.4 + '@babel/parser': 7.22.3 '@vue/shared': 3.3.4 estree-walker: 2.0.2 source-map-js: 1.0.2 - /@vue/compiler-dom@3.2.47: - resolution: {integrity: sha512-dBBnEHEPoftUiS03a4ggEig74J2YBZ2UIeyfpcRM2tavgMWo4bsEfgCGsu+uJIL/vax9S+JztH8NmQerUo7shQ==} - dependencies: - '@vue/compiler-core': 3.2.47 - '@vue/shared': 3.2.47 - dev: false - /@vue/compiler-dom@3.3.4: resolution: {integrity: sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==} dependencies: '@vue/compiler-core': 3.3.4 '@vue/shared': 3.3.4 - /@vue/compiler-sfc@3.2.47: - resolution: {integrity: sha512-rog05W+2IFfxjMcFw10tM9+f7i/+FFpZJJ5XHX72NP9eC2uRD+42M3pYcQqDXVYoj74kHMSEdQ/WmCjt8JFksQ==} - dependencies: - '@babel/parser': 7.20.13 - '@vue/compiler-core': 3.2.47 - '@vue/compiler-dom': 3.2.47 - '@vue/compiler-ssr': 3.2.47 - '@vue/reactivity-transform': 3.2.47 - '@vue/shared': 3.2.47 - estree-walker: 2.0.2 - magic-string: 0.25.9 - postcss: 8.4.21 - source-map: 0.6.1 - dev: false - /@vue/compiler-sfc@3.3.4: resolution: {integrity: sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==} dependencies: - '@babel/parser': 7.21.4 + '@babel/parser': 7.22.3 '@vue/compiler-core': 3.3.4 '@vue/compiler-dom': 3.3.4 '@vue/compiler-ssr': 3.3.4 @@ -3001,13 +2962,6 @@ packages: postcss: 8.4.24 source-map-js: 1.0.2 - /@vue/compiler-ssr@3.2.47: - resolution: {integrity: sha512-wVXC+gszhulcMD8wpxMsqSOpvDZ6xKXSVWkf50Guf/S+28hTAXPDYRTbLQ3EDkOP5Xz/+SY37YiwDquKbJOgZw==} - dependencies: - '@vue/compiler-dom': 3.2.47 - '@vue/shared': 3.2.47 - dev: false - /@vue/compiler-ssr@3.3.4: resolution: {integrity: sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==} dependencies: @@ -3021,57 +2975,26 @@ packages: /@vue/devtools-api@6.5.0: resolution: {integrity: sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==} - /@vue/reactivity-transform@3.2.47: - resolution: {integrity: sha512-m8lGXw8rdnPVVIdIFhf0LeQ/ixyHkH5plYuS83yop5n7ggVJU+z5v0zecwEnX7fa7HNLBhh2qngJJkxpwEEmYA==} - dependencies: - '@babel/parser': 7.20.13 - '@vue/compiler-core': 3.2.47 - '@vue/shared': 3.2.47 - estree-walker: 2.0.2 - magic-string: 0.25.9 - dev: false - /@vue/reactivity-transform@3.3.4: resolution: {integrity: sha512-MXgwjako4nu5WFLAjpBnCj/ieqcjE2aJBINUNQzkZQfzIZA4xn+0fV1tIYBJvvva3N3OvKGofRLvQIwEQPpaXw==} dependencies: - '@babel/parser': 7.21.4 + '@babel/parser': 7.22.3 '@vue/compiler-core': 3.3.4 '@vue/shared': 3.3.4 estree-walker: 2.0.2 magic-string: 0.30.0 - /@vue/reactivity@3.2.47: - resolution: {integrity: sha512-7khqQ/75oyyg+N/e+iwV6lpy1f5wq759NdlS1fpAhFXa8VeAIKGgk2E/C4VF59lx5b+Ezs5fpp/5WsRYXQiKxQ==} - dependencies: - '@vue/shared': 3.2.47 - dev: false - /@vue/reactivity@3.3.4: resolution: {integrity: sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==} dependencies: '@vue/shared': 3.3.4 - /@vue/runtime-core@3.2.47: - resolution: {integrity: sha512-RZxbLQIRB/K0ev0K9FXhNbBzT32H9iRtYbaXb0ZIz2usLms/D55dJR2t6cIEUn6vyhS3ALNvNthI+Q95C+NOpA==} - dependencies: - '@vue/reactivity': 3.2.47 - '@vue/shared': 3.2.47 - dev: false - /@vue/runtime-core@3.3.4: resolution: {integrity: sha512-R+bqxMN6pWO7zGI4OMlmvePOdP2c93GsHFM/siJI7O2nxFRzj55pLwkpCedEY+bTMgp5miZ8CxfIZo3S+gFqvA==} dependencies: '@vue/reactivity': 3.3.4 '@vue/shared': 3.3.4 - /@vue/runtime-dom@3.2.47: - resolution: {integrity: sha512-ArXrFTjS6TsDei4qwNvgrdmHtD930KgSKGhS5M+j8QxXrDJYLqYw4RRcDy1bz1m1wMmb6j+zGLifdVHtkXA7gA==} - dependencies: - '@vue/runtime-core': 3.2.47 - '@vue/shared': 3.2.47 - csstype: 2.6.21 - dev: false - /@vue/runtime-dom@3.3.4: resolution: {integrity: sha512-Aj5bTJ3u5sFsUckRghsNjVTtxZQ1OyMWCr5dZRAPijF/0Vy4xEoRCwLyHXcj4D0UFbJ4lbx3gPTgg06K/GnPnQ==} dependencies: @@ -3079,16 +3002,6 @@ packages: '@vue/shared': 3.3.4 csstype: 3.1.2 - /@vue/server-renderer@3.2.47(vue@3.2.47): - resolution: {integrity: sha512-dN9gc1i8EvmP9RCzvneONXsKfBRgqFeFZLurmHOveL7oH6HiFXJw5OGu294n1nHc/HMgTy6LulU/tv5/A7f/LA==} - peerDependencies: - vue: 3.2.47 - dependencies: - '@vue/compiler-ssr': 3.2.47 - '@vue/shared': 3.2.47 - vue: 3.2.47 - dev: false - /@vue/server-renderer@3.3.4(vue@3.3.4): resolution: {integrity: sha512-Q6jDDzR23ViIb67v+vM1Dqntu+HUexQcsWKhhQa4ARVzxOY2HbC7QRW/ggkDBd5BU+uM1sV6XOAP0b216o34JQ==} peerDependencies: @@ -3098,20 +3011,16 @@ packages: '@vue/shared': 3.3.4 vue: 3.3.4 - /@vue/shared@3.2.47: - resolution: {integrity: sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ==} - dev: false - /@vue/shared@3.3.4: resolution: {integrity: sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==} - /@vueuse/core@10.0.0(vue@3.2.47): + /@vueuse/core@10.0.0(vue@3.3.4): resolution: {integrity: sha512-Q/p2xaGVFVrJ0E4ID1SM35WIa0Eo4AeKPSLKuLpYG09zgUWuwEaY4lBoNzLzkdLjzq5goIJ3DfYFI0wt8W4MkA==} dependencies: '@types/web-bluetooth': 0.0.16 '@vueuse/metadata': 10.0.0 - '@vueuse/shared': 10.0.0(vue@3.2.47) - vue-demi: 0.14.0(vue@3.2.47) + '@vueuse/shared': 10.0.0(vue@3.3.4) + vue-demi: 0.14.0(vue@3.3.4) transitivePeerDependencies: - '@vue/composition-api' - vue @@ -3121,17 +3030,17 @@ packages: resolution: {integrity: sha512-7Rh6tcs6aYLRLSdDHF+74wWP0Y1zLwpNJszKAIqlNBrmqdbkz8yh6NtjCYvXrrW6g+FU3ZWvR7F5ASNls+bHmw==} dev: false - /@vueuse/nuxt@10.0.0(nuxt@3.5.1)(rollup@2.79.1)(vue@3.2.47): + /@vueuse/nuxt@10.0.0(nuxt@3.5.1)(rollup@2.79.1)(vue@3.3.4): resolution: {integrity: sha512-u1MU9eNpDg7MsTgz1DlF2RaCw2E/KMG17Xb/2wnnK4G65d1xgQiF4mb28W4Qkz9rs56GCSpgJss0g4y5U8LG4g==} peerDependencies: nuxt: ^3.0.0 dependencies: '@nuxt/kit': 3.4.1(rollup@2.79.1) - '@vueuse/core': 10.0.0(vue@3.2.47) + '@vueuse/core': 10.0.0(vue@3.3.4) '@vueuse/metadata': 10.0.0 local-pkg: 0.4.3 nuxt: 3.5.1(@types/node@18.11.12)(eslint@8.29.0)(rollup@2.79.1)(typescript@5.0.2) - vue-demi: 0.14.0(vue@3.2.47) + vue-demi: 0.14.0(vue@3.3.4) transitivePeerDependencies: - '@vue/composition-api' - rollup @@ -3139,23 +3048,23 @@ packages: - vue dev: false - /@vueuse/router@10.0.0(vue-router@4.1.6)(vue@3.2.47): + /@vueuse/router@10.0.0(vue-router@4.1.6)(vue@3.3.4): resolution: {integrity: sha512-d8rasUUhJOzh/xpVmjHc3hmc6Nnn5yjtMio2oXVqwFGNCNDqACTCGERLBnwpgyTT+xz9oMoW37dQuseADOTIBA==} peerDependencies: vue-router: '>=4.0.0-rc.1' dependencies: - '@vueuse/shared': 10.0.0(vue@3.2.47) - vue-demi: 0.14.0(vue@3.2.47) - vue-router: 4.1.6(vue@3.2.47) + '@vueuse/shared': 10.0.0(vue@3.3.4) + vue-demi: 0.14.0(vue@3.3.4) + vue-router: 4.1.6(vue@3.3.4) transitivePeerDependencies: - '@vue/composition-api' - vue dev: false - /@vueuse/shared@10.0.0(vue@3.2.47): + /@vueuse/shared@10.0.0(vue@3.3.4): resolution: {integrity: sha512-Zh3LgJqvUBWVY3SiMvXanTcfAneGbt63QPczBRDNgQ6jd/ehodO9a1lCFzaA6SWJJoI+ugVTjHFYJdoR656DVQ==} dependencies: - vue-demi: 0.14.0(vue@3.2.47) + vue-demi: 0.14.0(vue@3.3.4) transitivePeerDependencies: - '@vue/composition-api' - vue @@ -4227,10 +4136,6 @@ packages: dependencies: css-tree: 2.2.1 - /csstype@2.6.21: - resolution: {integrity: sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==} - dev: false - /csstype@3.1.2: resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==} @@ -6285,6 +6190,7 @@ packages: resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} dependencies: sourcemap-codec: 1.4.8 + dev: true /magic-string@0.26.7: resolution: {integrity: sha512-hX9XH3ziStPoPhJxLq1syWuZMxbDvGNbVchfrdCtanC7D13888bMFow61x8axrx+GfHLtVeAx2kxL7tTGRl+Ow==} @@ -7067,7 +6973,7 @@ packages: resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} engines: {node: '>=0.10.0'} - /pinia@2.0.28(typescript@5.0.2)(vue@3.2.47): + /pinia@2.0.28(typescript@5.0.2)(vue@3.3.4): resolution: {integrity: sha512-YClq9DkqCblq9rlyUual7ezMu/iICWdBtfJrDt4oWU9Zxpijyz7xB2xTwx57DaBQ96UGvvTMORzALr+iO5PVMw==} peerDependencies: '@vue/composition-api': ^1.4.0 @@ -7081,8 +6987,8 @@ packages: dependencies: '@vue/devtools-api': 6.4.5 typescript: 5.0.2 - vue: 3.2.47 - vue-demi: 0.13.11(vue@3.2.47) + vue: 3.3.4 + vue-demi: 0.13.11(vue@3.3.4) dev: false /pkg-types@1.0.2: @@ -9273,17 +9179,17 @@ packages: dependencies: ufo: 1.1.2 - /vue-chartjs@4.1.2(chart.js@4.0.1)(vue@3.2.47): + /vue-chartjs@4.1.2(chart.js@4.0.1)(vue@3.3.4): resolution: {integrity: sha512-QSggYjeFv/L4jFSBQpX8NzrAvX0B+Ha6nDgxkTG8tEXxYOOTwKI4phRLe+B4f+REnkmg7hgPY24R0cixZJyXBg==} peerDependencies: chart.js: ^3.7.0 vue: ^3.0.0-0 || ^2.6.0 dependencies: chart.js: 4.0.1 - vue: 3.2.47 + vue: 3.3.4 dev: false - /vue-demi@0.13.11(vue@3.2.47): + /vue-demi@0.13.11(vue@3.3.4): resolution: {integrity: sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==} engines: {node: '>=12'} hasBin: true @@ -9295,10 +9201,10 @@ packages: '@vue/composition-api': optional: true dependencies: - vue: 3.2.47 + vue: 3.3.4 dev: false - /vue-demi@0.14.0(vue@3.2.47): + /vue-demi@0.14.0(vue@3.3.4): resolution: {integrity: sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg==} engines: {node: '>=12'} hasBin: true @@ -9310,7 +9216,7 @@ packages: '@vue/composition-api': optional: true dependencies: - vue: 3.2.47 + vue: 3.3.4 dev: false /vue-devtools-stub@0.1.0: @@ -9334,13 +9240,13 @@ packages: - supports-color dev: true - /vue-router@4.1.6(vue@3.2.47): + /vue-router@4.1.6(vue@3.3.4): resolution: {integrity: sha512-DYWYwsG6xNPmLq/FmZn8Ip+qrhFEzA14EI12MsMgVxvHFDYvlr4NXpVF5hrRH1wVcDP8fGi5F4rxuJSl8/r+EQ==} peerDependencies: vue: ^3.2.0 dependencies: '@vue/devtools-api': 6.4.5 - vue: 3.2.47 + vue: 3.3.4 dev: false /vue-router@4.2.1(vue@3.3.4): @@ -9351,16 +9257,6 @@ packages: '@vue/devtools-api': 6.5.0 vue: 3.3.4 - /vue@3.2.47: - resolution: {integrity: sha512-60188y/9Dc9WVrAZeUVSDxRQOZ+z+y5nO2ts9jWXSTkMvayiWxCWOWtBQoYjLeccfXkiiPZWAHcV+WTPhkqJHQ==} - dependencies: - '@vue/compiler-dom': 3.2.47 - '@vue/compiler-sfc': 3.2.47 - '@vue/runtime-dom': 3.2.47 - '@vue/server-renderer': 3.2.47(vue@3.2.47) - '@vue/shared': 3.2.47 - dev: false - /vue@3.3.4: resolution: {integrity: sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==} dependencies: