diff --git a/api/review_task.go b/api/review_task.go index 3aaf917a..3debaa52 100644 --- a/api/review_task.go +++ b/api/review_task.go @@ -27,7 +27,8 @@ type reviewTask struct { Reviewer *platform.User `json:"addressor"` } type reviewTaskPool struct { - Condition string `json:"condition"` + Condition string `json:"condition"` + Site types.Site `json:"site"` } type contentListReviewTask struct { Tasks []reviewTask `json:"tasks"` diff --git a/api/user.go b/api/user.go index 4b5f0cb7..0fc62f20 100644 --- a/api/user.go +++ b/api/user.go @@ -17,7 +17,7 @@ type contentURLAPI struct { ReviewTask string `json:"review_task"` Signal string `json:"signal"` Upload string `json:"upload"` - Users string `json:"users"` + User string `json:"users"` } type contentURLs struct { API contentURLAPI `json:"api"` @@ -51,7 +51,7 @@ func getUserSelf(ctx context.Context, r *http.Request, user platform.User, query ReviewTask: config.MakeURLNidus("/api/review-task"), Signal: config.MakeURLNidus("/api/signal"), Upload: config.MakeURLNidus("/api/upload"), - Users: config.MakeURLNidus("/api/user"), + User: config.MakeURLNidus("/api/user"), }, Tegola: urls.Tegola, Tile: config.MakeURLNidus("/api/tile/{z}/{y}/{x}"), @@ -96,6 +96,7 @@ func listUserSuggestion(ctx context.Context, r *http.Request, user platform.User }, nil } -func userPut(ctx context.Context, r *http.Request, user platform.User, updates platform.User) { +func userPut(ctx context.Context, r *http.Request, user platform.User, updates platform.User) (string, *nhttp.ErrorWithStatus) { //if updates.Avatar + return "", nil } diff --git a/db/dbinfo/user_.bob.go b/db/dbinfo/user_.bob.go index fcee24c3..9bbd0e95 100644 --- a/db/dbinfo/user_.bob.go +++ b/db/dbinfo/user_.bob.go @@ -132,6 +132,42 @@ var Users = Table[ Generated: false, AutoIncr: false, }, + IsActive: column{ + Name: "is_active", + DBType: "boolean", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + IsDronePilot: column{ + Name: "is_drone_pilot", + DBType: "boolean", + Default: "NULL", + Comment: "", + Nullable: true, + Generated: false, + AutoIncr: false, + }, + IsWarrant: column{ + Name: "is_warrant", + DBType: "boolean", + Default: "NULL", + Comment: "", + Nullable: true, + Generated: false, + AutoIncr: false, + }, + Avatar: column{ + Name: "avatar", + DBType: "uuid", + Default: "NULL", + Comment: "", + Nullable: true, + Generated: false, + AutoIncr: false, + }, }, Indexes: userIndexes{ UserPkey: index{ @@ -210,11 +246,15 @@ type userColumns struct { PasswordHashType column PasswordHash column Role column + IsActive column + IsDronePilot column + IsWarrant column + Avatar column } func (c userColumns) AsSlice() []column { return []column{ - c.ID, c.ArcgisAccessToken, c.ArcgisLicense, c.ArcgisRefreshToken, c.ArcgisRefreshTokenExpires, c.ArcgisRole, c.DisplayName, c.Email, c.OrganizationID, c.Username, c.PasswordHashType, c.PasswordHash, c.Role, + c.ID, c.ArcgisAccessToken, c.ArcgisLicense, c.ArcgisRefreshToken, c.ArcgisRefreshTokenExpires, c.ArcgisRole, c.DisplayName, c.Email, c.OrganizationID, c.Username, c.PasswordHashType, c.PasswordHash, c.Role, c.IsActive, c.IsDronePilot, c.IsWarrant, c.Avatar, } } diff --git a/db/models/user_.bob.go b/db/models/user_.bob.go index de084adf..a7fbf9ac 100644 --- a/db/models/user_.bob.go +++ b/db/models/user_.bob.go @@ -22,6 +22,7 @@ import ( "github.com/aarondl/opt/null" "github.com/aarondl/opt/omit" "github.com/aarondl/opt/omitnull" + "github.com/google/uuid" ) // User is an object representing the database table. @@ -39,6 +40,10 @@ type User struct { PasswordHashType enums.Hashtype `db:"password_hash_type" ` PasswordHash string `db:"password_hash" ` Role enums.Userrole `db:"role" ` + IsActive bool `db:"is_active" ` + IsDronePilot null.Val[bool] `db:"is_drone_pilot" ` + IsWarrant null.Val[bool] `db:"is_warrant" ` + Avatar null.Val[uuid.UUID] `db:"avatar" ` R userR `db:"-" ` } @@ -88,7 +93,7 @@ type userR struct { func buildUserColumns(alias string) userColumns { return userColumns{ ColumnsExpr: expr.NewColumnsExpr( - "id", "arcgis_access_token", "arcgis_license", "arcgis_refresh_token", "arcgis_refresh_token_expires", "arcgis_role", "display_name", "email", "organization_id", "username", "password_hash_type", "password_hash", "role", + "id", "arcgis_access_token", "arcgis_license", "arcgis_refresh_token", "arcgis_refresh_token_expires", "arcgis_role", "display_name", "email", "organization_id", "username", "password_hash_type", "password_hash", "role", "is_active", "is_drone_pilot", "is_warrant", "avatar", ).WithParent("user_"), tableAlias: alias, ID: psql.Quote(alias, "id"), @@ -104,6 +109,10 @@ func buildUserColumns(alias string) userColumns { PasswordHashType: psql.Quote(alias, "password_hash_type"), PasswordHash: psql.Quote(alias, "password_hash"), Role: psql.Quote(alias, "role"), + IsActive: psql.Quote(alias, "is_active"), + IsDronePilot: psql.Quote(alias, "is_drone_pilot"), + IsWarrant: psql.Quote(alias, "is_warrant"), + Avatar: psql.Quote(alias, "avatar"), } } @@ -123,6 +132,10 @@ type userColumns struct { PasswordHashType psql.Expression PasswordHash psql.Expression Role psql.Expression + IsActive psql.Expression + IsDronePilot psql.Expression + IsWarrant psql.Expression + Avatar psql.Expression } func (c userColumns) Alias() string { @@ -150,10 +163,14 @@ type UserSetter struct { PasswordHashType omit.Val[enums.Hashtype] `db:"password_hash_type" ` PasswordHash omit.Val[string] `db:"password_hash" ` Role omit.Val[enums.Userrole] `db:"role" ` + IsActive omit.Val[bool] `db:"is_active" ` + IsDronePilot omitnull.Val[bool] `db:"is_drone_pilot" ` + IsWarrant omitnull.Val[bool] `db:"is_warrant" ` + Avatar omitnull.Val[uuid.UUID] `db:"avatar" ` } func (s UserSetter) SetColumns() []string { - vals := make([]string, 0, 13) + vals := make([]string, 0, 17) if s.ID.IsValue() { vals = append(vals, "id") } @@ -193,6 +210,18 @@ func (s UserSetter) SetColumns() []string { if s.Role.IsValue() { vals = append(vals, "role") } + if s.IsActive.IsValue() { + vals = append(vals, "is_active") + } + if !s.IsDronePilot.IsUnset() { + vals = append(vals, "is_drone_pilot") + } + if !s.IsWarrant.IsUnset() { + vals = append(vals, "is_warrant") + } + if !s.Avatar.IsUnset() { + vals = append(vals, "avatar") + } return vals } @@ -236,6 +265,18 @@ func (s UserSetter) Overwrite(t *User) { if s.Role.IsValue() { t.Role = s.Role.MustGet() } + if s.IsActive.IsValue() { + t.IsActive = s.IsActive.MustGet() + } + if !s.IsDronePilot.IsUnset() { + t.IsDronePilot = s.IsDronePilot.MustGetNull() + } + if !s.IsWarrant.IsUnset() { + t.IsWarrant = s.IsWarrant.MustGetNull() + } + if !s.Avatar.IsUnset() { + t.Avatar = s.Avatar.MustGetNull() + } } func (s *UserSetter) Apply(q *dialect.InsertQuery) { @@ -244,7 +285,7 @@ func (s *UserSetter) Apply(q *dialect.InsertQuery) { }) q.AppendValues(bob.ExpressionFunc(func(ctx context.Context, w io.StringWriter, d bob.Dialect, start int) ([]any, error) { - vals := make([]bob.Expression, 13) + vals := make([]bob.Expression, 17) if s.ID.IsValue() { vals[0] = psql.Arg(s.ID.MustGet()) } else { @@ -323,6 +364,30 @@ func (s *UserSetter) Apply(q *dialect.InsertQuery) { vals[12] = psql.Raw("DEFAULT") } + if s.IsActive.IsValue() { + vals[13] = psql.Arg(s.IsActive.MustGet()) + } else { + vals[13] = psql.Raw("DEFAULT") + } + + if !s.IsDronePilot.IsUnset() { + vals[14] = psql.Arg(s.IsDronePilot.MustGetNull()) + } else { + vals[14] = psql.Raw("DEFAULT") + } + + if !s.IsWarrant.IsUnset() { + vals[15] = psql.Arg(s.IsWarrant.MustGetNull()) + } else { + vals[15] = psql.Raw("DEFAULT") + } + + if !s.Avatar.IsUnset() { + vals[16] = psql.Arg(s.Avatar.MustGetNull()) + } else { + vals[16] = psql.Raw("DEFAULT") + } + return bob.ExpressSlice(ctx, w, d, start, vals, "", ", ", "") })) } @@ -332,7 +397,7 @@ func (s UserSetter) UpdateMod() bob.Mod[*dialect.UpdateQuery] { } func (s UserSetter) Expressions(prefix ...string) []bob.Expression { - exprs := make([]bob.Expression, 0, 13) + exprs := make([]bob.Expression, 0, 17) if s.ID.IsValue() { exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ @@ -425,6 +490,34 @@ func (s UserSetter) Expressions(prefix ...string) []bob.Expression { }}) } + if s.IsActive.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "is_active")...), + psql.Arg(s.IsActive), + }}) + } + + if !s.IsDronePilot.IsUnset() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "is_drone_pilot")...), + psql.Arg(s.IsDronePilot), + }}) + } + + if !s.IsWarrant.IsUnset() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "is_warrant")...), + psql.Arg(s.IsWarrant), + }}) + } + + if !s.Avatar.IsUnset() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "avatar")...), + psql.Arg(s.Avatar), + }}) + } + return exprs } @@ -3221,6 +3314,10 @@ type userWhere[Q psql.Filterable] struct { PasswordHashType psql.WhereMod[Q, enums.Hashtype] PasswordHash psql.WhereMod[Q, string] Role psql.WhereMod[Q, enums.Userrole] + IsActive psql.WhereMod[Q, bool] + IsDronePilot psql.WhereNullMod[Q, bool] + IsWarrant psql.WhereNullMod[Q, bool] + Avatar psql.WhereNullMod[Q, uuid.UUID] } func (userWhere[Q]) AliasedAs(alias string) userWhere[Q] { @@ -3242,6 +3339,10 @@ func buildUserWhere[Q psql.Filterable](cols userColumns) userWhere[Q] { PasswordHashType: psql.Where[Q, enums.Hashtype](cols.PasswordHashType), PasswordHash: psql.Where[Q, string](cols.PasswordHash), Role: psql.Where[Q, enums.Userrole](cols.Role), + IsActive: psql.Where[Q, bool](cols.IsActive), + IsDronePilot: psql.WhereNull[Q, bool](cols.IsDronePilot), + IsWarrant: psql.WhereNull[Q, bool](cols.IsWarrant), + Avatar: psql.WhereNull[Q, uuid.UUID](cols.Avatar), } } diff --git a/package.json b/package.json index 070e2b4d..bfcee181 100644 --- a/package.json +++ b/package.json @@ -19,10 +19,11 @@ "sass": "^1.98.0", "typescript": "^5.9.3", "vite": "^8.0.1", + "vite-plugin-checker": "^0.12.0", "vue-tsc": "^3.2.6" }, "scripts": { - "build": "vite build", + "build": "vue-tsc && vite build", "dev": "vite", "generate-icons": "node generate-icons.js", "typecheck": "vue-tsc --noEmit", diff --git a/platform/organization.go b/platform/organization.go index 996d7875..bac16295 100644 --- a/platform/organization.go +++ b/platform/organization.go @@ -76,8 +76,8 @@ func (o Organization) FieldseekerSyncLatest(ctx context.Context) (*models.Fields } type ServiceArea struct { - Min Point - Max Point + Min Point `json:"min"` + Max Point `json:"max"` } func (o Organization) ServiceRequestRecent(ctx context.Context) ([]*models.FieldseekerServicerequest, error) { diff --git a/platform/pool.go b/platform/pool.go index 7b022b6c..a2d02dff 100644 --- a/platform/pool.go +++ b/platform/pool.go @@ -18,9 +18,9 @@ type Pool struct { ID int32 `db:"id" json:"-"` } type UploadPoolError struct { - Column uint - Line uint - Message string + Column uint `json:"column"` + Line uint `json:"line"` + Message string `json:"message"` } func errorsByLine(ctx context.Context, file *models.FileuploadFile) ([]UploadPoolError, map[int32][]UploadPoolError, error) { diff --git a/platform/site.go b/platform/site.go index e4bdf7ed..e54c2338 100644 --- a/platform/site.go +++ b/platform/site.go @@ -14,6 +14,7 @@ import ( "github.com/Gleipnir-Technology/nidus-sync/db/models" nhttp "github.com/Gleipnir-Technology/nidus-sync/http" "github.com/Gleipnir-Technology/nidus-sync/platform/geocode" + //"github.com/Gleipnir-Technology/nidus-sync/platform/types" "github.com/aarondl/opt/omit" "github.com/aarondl/opt/omitnull" "github.com/stephenafamo/scan" diff --git a/platform/types/report.go b/platform/types/report.go index 1a56b5c6..968660e9 100644 --- a/platform/types/report.go +++ b/platform/types/report.go @@ -5,13 +5,13 @@ import ( ) type Report struct { - Log []LogEntry `db:"-" json:"log"` Address Address `db:"address" json:"address"` AddressRaw string `db:"address_raw" json:"address_raw"` Created time.Time `db:"created" json:"created"` ID int32 `db:"id" json:"-"` Images []Image `db:"images" json:"images"` Location *Location `db:"location" json:"location"` + Log []LogEntry `db:"-" json:"log"` Nuisance *Nuisance `db:"nuisance" json:"nuisance"` PublicID string `db:"public_id" json:"public_id"` Reporter Contact `db:"reporter" json:"reporter"` diff --git a/platform/types/site.go b/platform/types/site.go new file mode 100644 index 00000000..8cbd7f0e --- /dev/null +++ b/platform/types/site.go @@ -0,0 +1,21 @@ +package types + +import ( + "time" +) + +type Site struct { + Address Address `json:"address"` + Created time.Time `json:"created"` + CreatorID int32 `json:"creator_id"` + FileID int32 `json:"file_id"` + ID int32 `json:"id"` + Notes string `json:"notes"` + OrganizationID int32 `json:"organization_id"` + Owner *Contact `json:"owner"` + ParcelID *int32 `json:"parcel_id"` + Resident *Contact `json:"resident"` + ResidentOwned bool `json:"resident_owned"` + Tags map[string]string `json:"tags"` + Version int32 `json:"version"` +} diff --git a/platform/user.go b/platform/user.go index 20c2bd3a..68807e61 100644 --- a/platform/user.go +++ b/platform/user.go @@ -15,6 +15,7 @@ import ( "github.com/Gleipnir-Technology/nidus-sync/db/models" "github.com/Gleipnir-Technology/nidus-sync/debug" "github.com/aarondl/opt/omit" + "github.com/google/uuid" "github.com/rs/zerolog/log" ) @@ -54,7 +55,7 @@ func (u User) HasRoot() bool { func newUser(ctx context.Context, org Organization, user *models.User) User { u := User{ Active: true, - Avatar: user.Avatar, + Avatar: user.Avatar.GetOr(uuid.UUID{}).String(), DisplayName: user.DisplayName, ID: int(user.ID), Initials: extractInitials(user.DisplayName), diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8f2ac48a..41eafac7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -48,12 +48,19 @@ importers: vite: specifier: ^8.0.1 version: 8.0.1(sass@1.98.0)(yaml@2.8.3) + vite-plugin-checker: + specifier: ^0.12.0 + version: 0.12.0(typescript@5.9.3)(vite@8.0.1(sass@1.98.0)(yaml@2.8.3))(vue-tsc@3.2.6(typescript@5.9.3)) vue-tsc: specifier: ^3.2.6 version: 3.2.6(typescript@5.9.3) packages: + '@babel/code-frame@7.29.0': + resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} + engines: {node: '>=6.9.0'} + '@babel/generator@7.29.1': resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} engines: {node: '>=6.9.0'} @@ -587,6 +594,9 @@ packages: resolution: {integrity: sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==} engines: {node: '>=18'} + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + jsesc@3.1.0: resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} engines: {node: '>=6'} @@ -723,9 +733,17 @@ packages: node-addon-api@7.1.1: resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} + npm-run-path@6.0.0: + resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==} + engines: {node: '>=18'} + path-browserify@1.0.1: resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} @@ -825,6 +843,9 @@ packages: resolution: {integrity: sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA==} engines: {node: '>=16'} + tiny-invariant@1.3.3: + resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + tinyglobby@0.2.15: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} @@ -843,6 +864,10 @@ packages: ufo@1.6.3: resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} + unicorn-magic@0.3.0: + resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} + engines: {node: '>=18'} + unplugin-utils@0.3.1: resolution: {integrity: sha512-5lWVjgi6vuHhJ526bI4nlCOmkCIF3nnfXkCMDeMJrtdvxTs6ZFCM8oNufGTsDbKv/tJ/xj8RpvXjRuPBZJuJog==} engines: {node: '>=20.19.0'} @@ -851,6 +876,43 @@ packages: resolution: {integrity: sha512-0Mqk3AT2TZCXWKdcoaufeXNukv2mTrEZExeXlHIOZXdqYoHHr4n51pymnwV8x2BOVxwXbK2HLlI7usrqMpycdg==} engines: {node: ^20.19.0 || >=22.12.0} + vite-plugin-checker@0.12.0: + resolution: {integrity: sha512-CmdZdDOGss7kdQwv73UyVgLPv0FVYe5czAgnmRX2oKljgEvSrODGuClaV3PDR2+3ou7N/OKGauDDBjy2MB07Rg==} + engines: {node: '>=16.11'} + peerDependencies: + '@biomejs/biome': '>=1.7' + eslint: '>=9.39.1' + meow: ^13.2.0 + optionator: ^0.9.4 + oxlint: '>=1' + stylelint: '>=16' + typescript: '*' + vite: '>=5.4.21' + vls: '*' + vti: '*' + vue-tsc: ~2.2.10 || ^3.0.0 + peerDependenciesMeta: + '@biomejs/biome': + optional: true + eslint: + optional: true + meow: + optional: true + optionator: + optional: true + oxlint: + optional: true + stylelint: + optional: true + typescript: + optional: true + vls: + optional: true + vti: + optional: true + vue-tsc: + optional: true + vite@8.0.1: resolution: {integrity: sha512-wt+Z2qIhfFt85uiyRt5LPU4oVEJBXj8hZNWKeqFG4gRG/0RaRGJ7njQCwzFVjO+v4+Ipmf5CY7VdmZRAYYBPHw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -936,6 +998,12 @@ packages: snapshots: + '@babel/code-frame@7.29.0': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + '@babel/generator@7.29.1': dependencies: '@babel/parser': 7.29.2 @@ -1456,6 +1524,8 @@ snapshots: is-what@5.5.0: {} + js-tokens@4.0.0: {} + jsesc@3.1.0: {} json-stringify-pretty-compact@4.0.0: {} @@ -1577,8 +1647,15 @@ snapshots: node-addon-api@7.1.1: optional: true + npm-run-path@6.0.0: + dependencies: + path-key: 4.0.0 + unicorn-magic: 0.3.0 + path-browserify@1.0.1: {} + path-key@4.0.0: {} + pathe@2.0.3: {} pbf@4.0.1: @@ -1683,6 +1760,8 @@ snapshots: dependencies: copy-anything: 4.0.5 + tiny-invariant@1.3.3: {} + tinyglobby@0.2.15: dependencies: fdir: 6.5.0(picomatch@4.0.3) @@ -1697,6 +1776,8 @@ snapshots: ufo@1.6.3: {} + unicorn-magic@0.3.0: {} + unplugin-utils@0.3.1: dependencies: pathe: 2.0.3 @@ -1708,6 +1789,21 @@ snapshots: picomatch: 4.0.3 webpack-virtual-modules: 0.6.2 + vite-plugin-checker@0.12.0(typescript@5.9.3)(vite@8.0.1(sass@1.98.0)(yaml@2.8.3))(vue-tsc@3.2.6(typescript@5.9.3)): + dependencies: + '@babel/code-frame': 7.29.0 + chokidar: 4.0.3 + npm-run-path: 6.0.0 + picocolors: 1.1.1 + picomatch: 4.0.3 + tiny-invariant: 1.3.3 + tinyglobby: 0.2.15 + vite: 8.0.1(sass@1.98.0)(yaml@2.8.3) + vscode-uri: 3.1.0 + optionalDependencies: + typescript: 5.9.3 + vue-tsc: 3.2.6(typescript@5.9.3) + vite@8.0.1(sass@1.98.0)(yaml@2.8.3): dependencies: lightningcss: 1.32.0 diff --git a/ts/App.vue b/ts/App.vue index a6e01d3a..cdfb8186 100644 --- a/ts/App.vue +++ b/ts/App.vue @@ -2,8 +2,8 @@