From fa78e86de69c56d4eb7177f8c8efa0cc9e3b8115 Mon Sep 17 00:00:00 2001 From: "Daniel J. Summers" Date: Mon, 2 Sep 2019 19:01:26 -0500 Subject: [PATCH] myPrayerJournal v2 (#27) App changes: * Move to Vue Material for UI components * Convert request cards to true material design cards, separating the "pray" button from the others and improved highlighting of the current request * Centralize Auth0 integration in one place; modify the Vuex store to rely on it entirely, and add a Vue mixin to make it accessible by any component API changes: * Change backing data store to RavenDB * Evolve domain models (using F# discriminated unions, and JSON converters for storage) to make invalid states unrepresentable * Incorporate the FunctionalCuid library * Create a functional pipeline for app configuration instead of chaining `IWebHostBuilder` calls Bug fixes: * Set showAfter to 0 for immediately recurring requests (#26) --- .gitignore | 12 +- src/MyPrayerJournal.Api/Data.fs | 184 +++ src/MyPrayerJournal.Api/Domain.fs | 169 ++ src/{api => }/MyPrayerJournal.Api/Handlers.fs | 255 +-- .../MyPrayerJournal.Api.fsproj | 12 +- src/MyPrayerJournal.Api/Program.fs | 144 ++ .../Properties/launchSettings.json | 0 .../MyPrayerJournal.Api/appsettings.json | 0 src/MyPrayerJournal.sln | 37 + src/api/MyPrayerJournal.Api/Data.fs | 275 ---- src/api/MyPrayerJournal.Api/Program.fs | 139 -- src/api/MyPrayerJournal.sln | 25 - src/app/package.json | 18 +- src/app/src/App.vue | 350 ++--- src/app/src/api/index.js | 4 +- src/app/src/auth/AuthService.js | 248 +-- src/app/src/components/Home.vue | 12 +- src/app/src/components/Journal.vue | 67 +- .../components/common/MaterialDesignIcon.vue | 15 - src/app/src/components/common/Navigation.vue | 101 +- src/app/src/components/common/PageTitle.vue | 11 +- .../src/components/legal/PrivacyPolicy.vue | 109 +- .../src/components/legal/TermsOfService.vue | 71 +- .../src/components/request/ActiveRequests.vue | 31 +- .../components/request/AnsweredRequests.vue | 41 +- .../src/components/request/EditRequest.vue | 168 +- .../src/components/request/FullRequest.vue | 45 +- src/app/src/components/request/NotesEdit.vue | 74 +- .../src/components/request/RequestCard.vue | 95 +- .../src/components/request/RequestList.vue | 40 + .../components/request/RequestListItem.vue | 77 +- .../src/components/request/SnoozeRequest.vue | 42 +- .../components/request/SnoozedRequests.vue | 29 +- src/app/src/components/user/LogOn.vue | 15 +- src/app/src/main.js | 72 +- src/app/src/plugins/auth.js | 22 + src/app/src/router.js | 38 +- src/app/src/store/action-types.js | 2 + src/app/src/store/index.js | 101 +- src/app/src/store/mutation-types.js | 2 + src/app/vue.config.js | 11 +- src/app/yarn.lock | 1372 +++++++++++------ src/migrate/Program.fs | 110 ++ src/migrate/migrate.fsproj | 23 + 44 files changed, 2729 insertions(+), 1939 deletions(-) create mode 100644 src/MyPrayerJournal.Api/Data.fs create mode 100644 src/MyPrayerJournal.Api/Domain.fs rename src/{api => }/MyPrayerJournal.Api/Handlers.fs (50%) rename src/{api => }/MyPrayerJournal.Api/MyPrayerJournal.Api.fsproj (67%) create mode 100644 src/MyPrayerJournal.Api/Program.fs rename src/{api => }/MyPrayerJournal.Api/Properties/launchSettings.json (100%) rename src/{api => }/MyPrayerJournal.Api/appsettings.json (100%) create mode 100644 src/MyPrayerJournal.sln delete mode 100644 src/api/MyPrayerJournal.Api/Data.fs delete mode 100644 src/api/MyPrayerJournal.Api/Program.fs delete mode 100644 src/api/MyPrayerJournal.sln delete mode 100644 src/app/src/components/common/MaterialDesignIcon.vue create mode 100644 src/app/src/components/request/RequestList.vue create mode 100644 src/app/src/plugins/auth.js create mode 100644 src/migrate/Program.fs create mode 100644 src/migrate/migrate.fsproj diff --git a/.gitignore b/.gitignore index 5c074f4..d4b2e22 100644 --- a/.gitignore +++ b/.gitignore @@ -256,11 +256,11 @@ paket-files/ .ionide # Compiled files / application -src/api/build -src/api/MyPrayerJournal.Api/wwwroot/favicon.ico -src/api/MyPrayerJournal.Api/wwwroot/index.html -src/api/MyPrayerJournal.Api/wwwroot/css -src/api/MyPrayerJournal.Api/wwwroot/js -src/api/MyPrayerJournal.Api/appsettings.development.json +src/build +src/MyPrayerJournal.Api/wwwroot/favicon.ico +src/MyPrayerJournal.Api/wwwroot/index.html +src/MyPrayerJournal.Api/wwwroot/css +src/MyPrayerJournal.Api/wwwroot/js +src/MyPrayerJournal.Api/appsettings.development.json /build src/*.exe diff --git a/src/MyPrayerJournal.Api/Data.fs b/src/MyPrayerJournal.Api/Data.fs new file mode 100644 index 0000000..9d2c112 --- /dev/null +++ b/src/MyPrayerJournal.Api/Data.fs @@ -0,0 +1,184 @@ +namespace MyPrayerJournal + +open System +open System.Collections.Generic + +/// JSON converters for various DUs +module Converters = + + open Microsoft.FSharpLu.Json + open Newtonsoft.Json + + /// JSON converter for request IDs + type RequestIdJsonConverter () = + inherit JsonConverter () + override __.WriteJson(writer : JsonWriter, value : RequestId, _ : JsonSerializer) = + (RequestId.toString >> writer.WriteValue) value + override __.ReadJson(reader: JsonReader, _ : Type, _ : RequestId, _ : bool, _ : JsonSerializer) = + (string >> RequestId.fromIdString) reader.Value + + /// JSON converter for user IDs + type UserIdJsonConverter () = + inherit JsonConverter () + override __.WriteJson(writer : JsonWriter, value : UserId, _ : JsonSerializer) = + (UserId.toString >> writer.WriteValue) value + override __.ReadJson(reader: JsonReader, _ : Type, _ : UserId, _ : bool, _ : JsonSerializer) = + (string >> UserId) reader.Value + + /// JSON converter for Ticks + type TicksJsonConverter () = + inherit JsonConverter () + override __.WriteJson(writer : JsonWriter, value : Ticks, _ : JsonSerializer) = + (Ticks.toLong >> writer.WriteValue) value + override __.ReadJson(reader: JsonReader, _ : Type, _ : Ticks, _ : bool, _ : JsonSerializer) = + (string >> int64 >> Ticks) reader.Value + + /// A sequence of all custom converters needed for myPrayerJournal + let all : JsonConverter seq = + seq { + yield RequestIdJsonConverter () + yield UserIdJsonConverter () + yield TicksJsonConverter () + yield CompactUnionJsonConverter true + } + + +/// RavenDB index declarations +module Indexes = + + open Raven.Client.Documents.Indexes + + /// Index requests for a journal view + type Requests_AsJournal () as this = + inherit AbstractJavaScriptIndexCreationTask () + do + this.Maps <- HashSet [ + """docs.Requests.Select(req => new { + requestId = req.Id.Replace("Requests/", ""), + userId = req.userId, + text = req.history.Where(hist => hist.text != null).OrderByDescending(hist => hist.asOf).First().text, + asOf = req.history.OrderByDescending(hist => hist.asOf).First().asOf, + lastStatus = req.history.OrderByDescending(hist => hist.asOf).First().status, + snoozedUntil = req.snoozedUntil, + showAfter = req.showAfter, + recurType = req.recurType, + recurCount = req.recurCount + })""" + ] + this.Fields <- + [ "requestId", IndexFieldOptions (Storage = Nullable FieldStorage.Yes) + "text", IndexFieldOptions (Storage = Nullable FieldStorage.Yes) + "asOf", IndexFieldOptions (Storage = Nullable FieldStorage.Yes) + "lastStatus", IndexFieldOptions (Storage = Nullable FieldStorage.Yes) + ] + |> dict + |> Dictionary + + +/// All data manipulations within myPrayerJournal +module Data = + + open FSharp.Control.Tasks.V2.ContextInsensitive + open Indexes + open Microsoft.FSharpLu + open Raven.Client.Documents + open Raven.Client.Documents.Linq + open Raven.Client.Documents.Session + + /// Add a history entry + let addHistory reqId (hist : History) (sess : IAsyncDocumentSession) = + sess.Advanced.Patch ( + RequestId.toString reqId, + (fun r -> r.history :> IEnumerable), + fun (h : JavaScriptArray) -> h.Add (hist) :> obj) + + /// Add a note + let addNote reqId (note : Note) (sess : IAsyncDocumentSession) = + sess.Advanced.Patch ( + RequestId.toString reqId, + (fun r -> r.notes :> IEnumerable), + fun (h : JavaScriptArray) -> h.Add (note) :> obj) + + /// Add a request + let addRequest req (sess : IAsyncDocumentSession) = + sess.StoreAsync (req, req.Id) + + /// Retrieve all answered requests for the given user + let answeredRequests userId (sess : IAsyncDocumentSession) = + task { + let! reqs = + sess.Query() + .Where(fun r -> r.userId = userId && r.lastStatus = "Answered") + .OrderByDescending(fun r -> r.asOf) + .ProjectInto() + .ToListAsync () + return List.ofSeq reqs + } + + /// Retrieve the user's current journal + let journalByUserId userId (sess : IAsyncDocumentSession) = + task { + let! jrnl = + sess.Query() + .Where(fun r -> r.userId = userId && r.lastStatus <> "Answered") + .OrderBy(fun r -> r.asOf) + .ProjectInto() + .ToListAsync() + return + jrnl + |> List.ofSeq + |> List.map (fun r -> r.history <- []; r.notes <- []; r) + } + + /// Save changes in the current document session + let saveChanges (sess : IAsyncDocumentSession) = + sess.SaveChangesAsync () + + /// Retrieve a request, including its history and notes, by its ID and user ID + let tryFullRequestById reqId userId (sess : IAsyncDocumentSession) = + task { + let! req = RequestId.toString reqId |> sess.LoadAsync + return match Option.fromObject req with Some r when r.userId = userId -> Some r | _ -> None + } + + + /// Retrieve a request by its ID and user ID (without notes and history) + let tryRequestById reqId userId (sess : IAsyncDocumentSession) = + task { + match! tryFullRequestById reqId userId sess with + | Some r -> return Some { r with history = []; notes = [] } + | _ -> return None + } + + /// Retrieve notes for a request by its ID and user ID + let notesById reqId userId (sess : IAsyncDocumentSession) = + task { + match! tryFullRequestById reqId userId sess with + | Some req -> return req.notes + | None -> return [] + } + + /// Retrieve a journal request by its ID and user ID + let tryJournalById reqId userId (sess : IAsyncDocumentSession) = + task { + let! req = + sess.Query() + .Where(fun x -> x.Id = (RequestId.toString reqId) && x.userId = userId) + .ProjectInto() + .FirstOrDefaultAsync () + return Option.fromObject req + } + + /// Update the recurrence for a request + let updateRecurrence reqId recurType recurCount (sess : IAsyncDocumentSession) = + sess.Advanced.Patch (RequestId.toString reqId, (fun r -> r.recurType), recurType) + sess.Advanced.Patch (RequestId.toString reqId, (fun r -> r.recurCount), recurCount) + + /// Update a snoozed request + let updateSnoozed reqId until (sess : IAsyncDocumentSession) = + sess.Advanced.Patch (RequestId.toString reqId, (fun r -> r.snoozedUntil), until) + sess.Advanced.Patch (RequestId.toString reqId, (fun r -> r.showAfter), until) + + /// Update the "show after" timestamp for a request + let updateShowAfter reqId showAfter (sess : IAsyncDocumentSession) = + sess.Advanced.Patch (RequestId.toString reqId, (fun r -> r.showAfter), showAfter) diff --git a/src/MyPrayerJournal.Api/Domain.fs b/src/MyPrayerJournal.Api/Domain.fs new file mode 100644 index 0000000..c13431a --- /dev/null +++ b/src/MyPrayerJournal.Api/Domain.fs @@ -0,0 +1,169 @@ +[] +/// The data model for myPrayerJournal +module MyPrayerJournal.Domain + +open Cuid + +/// Request ID is a CUID +type RequestId = + | RequestId of Cuid +module RequestId = + /// The string representation of the request ID + let toString x = match x with RequestId y -> (Cuid.toString >> sprintf "Requests/%s") y + /// Create a request ID from a string representation + let fromIdString (y : string) = (Cuid >> RequestId) <| y.Replace("Requests/", "") + + +/// User ID is a string (the "sub" part of the JWT) +type UserId = + | UserId of string +module UserId = + /// The string representation of the user ID + let toString x = match x with UserId y -> y + + +/// A long integer representing seconds since the epoch +type Ticks = + | Ticks of int64 +module Ticks = + /// The int64 (long) representation of ticks + let toLong x = match x with Ticks y -> y + + +/// How frequently a request should reappear after it is marked "Prayed" +type Recurrence = + | Immediate + | Hours + | Days + | Weeks +module Recurrence = + /// Create a recurrence value from a string + let fromString x = + match x with + | "Immediate" -> Immediate + | "Hours" -> Hours + | "Days" -> Days + | "Weeks" -> Weeks + | _ -> invalidOp (sprintf "%s is not a valid recurrence" x) + /// The duration of the recurrence + let duration x = + match x with + | Immediate -> 0L + | Hours -> 3600000L + | Days -> 86400000L + | Weeks -> 604800000L + + +/// The action taken on a request as part of a history entry +type RequestAction = + | Created + | Prayed + | Updated + | Answered +module RequestAction = + /// Create a RequestAction from a string + let fromString x = + match x with + | "Created" -> Created + | "Prayed" -> Prayed + | "Updated" -> Updated + | "Answered" -> Answered + | _ -> (sprintf "Bad request action %s" >> invalidOp) x + + +/// History is a record of action taken on a prayer request, including updates to its text +[] +type History = + { /// The time when this history entry was made + asOf : Ticks + /// The status for this history entry + status : RequestAction + /// The text of the update, if applicable + text : string option + } +with + /// An empty history entry + static member empty = + { asOf = Ticks 0L + status = Created + text = None + } + +/// Note is a note regarding a prayer request that does not result in an update to its text +[] +type Note = + { /// The time when this note was made + asOf : Ticks + /// The text of the notes + notes : string + } +with + /// An empty note + static member empty = + { asOf = Ticks 0L + notes = "" + } + +/// Request is the identifying record for a prayer request +[] +type Request = + { /// The ID of the request + Id : string + /// The time this request was initially entered + enteredOn : Ticks + /// The ID of the user to whom this request belongs ("sub" from the JWT) + userId : UserId + /// The time at which this request should reappear in the user's journal by manual user choice + snoozedUntil : Ticks + /// The time at which this request should reappear in the user's journal by recurrence + showAfter : Ticks + /// The type of recurrence for this request + recurType : Recurrence + /// How many of the recurrence intervals should occur between appearances in the journal + recurCount : int16 + /// The history entries for this request + history : History list + /// The notes for this request + notes : Note list + } +with + /// An empty request + static member empty = + { Id = "" + enteredOn = Ticks 0L + userId = UserId "" + snoozedUntil = Ticks 0L + showAfter = Ticks 0L + recurType = Immediate + recurCount = 0s + history = [] + notes = [] + } + +/// JournalRequest is the form of a prayer request returned for the request journal display. It also contains +/// properties that may be filled for history and notes. +// RavenDB doesn't like the "@"-suffixed properties from record types in a ProjectInto clause +[] +type JournalRequest () = + /// The ID of the request (just the CUID part) + [] val mutable requestId : string + /// The ID of the user to whom the request belongs + [] val mutable userId : UserId + /// The current text of the request + [] val mutable text : string + /// The last time action was taken on the request + [] val mutable asOf : Ticks + /// The last status for the request + [] val mutable lastStatus : string + /// The time that this request should reappear in the user's journal + [] val mutable snoozedUntil : Ticks + /// The time after which this request should reappear in the user's journal by configured recurrence + [] val mutable showAfter : Ticks + /// The type of recurrence for this request + [] val mutable recurType : Recurrence + /// How many of the recurrence intervals should occur between appearances in the journal + [] val mutable recurCount : int16 + /// History entries for the request + [] val mutable history : History list + /// Note entries for the request + [] val mutable notes : Note list diff --git a/src/api/MyPrayerJournal.Api/Handlers.fs b/src/MyPrayerJournal.Api/Handlers.fs similarity index 50% rename from src/api/MyPrayerJournal.Api/Handlers.fs rename to src/MyPrayerJournal.Api/Handlers.fs index 5f62b86..b07c59f 100644 --- a/src/api/MyPrayerJournal.Api/Handlers.fs +++ b/src/MyPrayerJournal.Api/Handlers.fs @@ -1,11 +1,8 @@ /// HTTP handlers for the myPrayerJournal API [] -module MyPrayerJournal.Api.Handlers +module MyPrayerJournal.Handlers -open FSharp.Control.Tasks.V2.ContextInsensitive open Giraffe -open MyPrayerJournal -open System /// Handler to return Vue files module Vue = @@ -13,6 +10,7 @@ module Vue = /// The application index page let app : HttpHandler = htmlFile "wwwroot/index.html" +open System /// Handlers for error conditions module Error = @@ -34,18 +32,22 @@ module Error = | 0 -> (setStatusCode 404 >=> json ([ "error", "not found" ] |> dict)) next ctx | _ -> Vue.app next ctx +open Cuid /// Handler helpers [] module private Helpers = open Microsoft.AspNetCore.Http + open Raven.Client.Documents open System.Threading.Tasks open System.Security.Claims - /// Get the database context from DI - let db (ctx : HttpContext) = - ctx.GetService () + /// Create a RavenDB session + let session (ctx : HttpContext) = + let sess = ctx.GetService().OpenAsyncSession () + sess.Advanced.WaitForIndexesAfterSaveChanges () + sess /// Get the user's "sub" claim let user (ctx : HttpContext) = @@ -54,15 +56,23 @@ module private Helpers = /// Get the current user's ID // NOTE: this may raise if you don't run the request through the authorize handler first let userId ctx = - ((user >> Option.get) ctx).Value + ((user >> Option.get) ctx).Value |> UserId + + /// Create a request ID from a string + let toReqId x = + let reqId = + match Cuid.ofString x with + | Ok cuid -> cuid + | Error msg -> invalidOp msg + RequestId reqId /// Return a 201 CREATED response let created next ctx = setStatusCode 201 next ctx - /// The "now" time in JavaScript + /// The "now" time in JavaScript as Ticks let jsNow () = - DateTime.UtcNow.Subtract(DateTime (1970, 1, 1, 0, 0, 0)).TotalSeconds |> int64 |> (*) 1000L + (int64 >> (*) 1000L >> Ticks) <| DateTime.UtcNow.Subtract(DateTime (1970, 1, 1, 0, 0, 0)).TotalSeconds /// Handler to return a 403 Not Authorized reponse let notAuthorized : HttpHandler = @@ -116,13 +126,6 @@ module Models = recurCount : int16 } - /// Reset the "showAfter" property on a request - [] - type Show = - { /// The time after which the request should appear - showAfter : int64 - } - /// The time until which a request should not appear in the journal [] type SnoozeUntil = @@ -130,6 +133,7 @@ module Models = until : int64 } +open FSharp.Control.Tasks.V2.ContextInsensitive /// /api/journal URLs module Journal = @@ -138,99 +142,92 @@ module Journal = let journal : HttpHandler = authorize >=> fun next ctx -> - userId ctx - |> (db ctx).JournalByUserId - |> asJson next ctx + task { + use sess = session ctx + let usrId = userId ctx + let! jrnl = Data.journalByUserId usrId sess + return! json jrnl next ctx + } /// /api/request URLs module Request = - open NCuid - - /// Ticks per recurrence - let private recurrence = - [ "immediate", 0L - "hours", 3600000L - "days", 86400000L - "weeks", 604800000L - ] - |> Map.ofList - /// POST /api/request let add : HttpHandler = authorize >=> fun next ctx -> task { let! r = ctx.BindJsonAsync () - let db = db ctx - let reqId = Cuid.Generate () + use sess = session ctx + let reqId = (Cuid.generate >> RequestId) () let usrId = userId ctx let now = jsNow () - { Request.empty with - requestId = reqId - userId = usrId - enteredOn = now - showAfter = now - recurType = r.recurType - recurCount = r.recurCount - } - |> db.AddEntry - { History.empty with - requestId = reqId - asOf = now - status = "Created" - text = Some r.requestText - } - |> db.AddEntry - let! _ = db.SaveChangesAsync () - match! db.TryJournalById reqId usrId with + do! Data.addRequest + { Request.empty with + Id = RequestId.toString reqId + userId = usrId + enteredOn = now + showAfter = Ticks 0L + recurType = Recurrence.fromString r.recurType + recurCount = r.recurCount + history = [ + { asOf = now + status = Created + text = Some r.requestText + } + ] + } sess + do! Data.saveChanges sess + match! Data.tryJournalById reqId usrId sess with | Some req -> return! (setStatusCode 201 >=> json req) next ctx | None -> return! Error.notFound next ctx } /// POST /api/request/[req-id]/history - let addHistory reqId : HttpHandler = + let addHistory requestId : HttpHandler = authorize >=> fun next ctx -> task { - let db = db ctx - match! db.TryRequestById reqId (userId ctx) with + use sess = session ctx + let usrId = userId ctx + let reqId = toReqId requestId + match! Data.tryRequestById reqId usrId sess with | Some req -> let! hist = ctx.BindJsonAsync () let now = jsNow () - { History.empty with - requestId = reqId - asOf = now - status = hist.status - text = match hist.updateText with null | "" -> None | x -> Some x - } - |> db.AddEntry - match hist.status with - | "Prayed" -> - db.UpdateEntry { req with showAfter = now + (recurrence.[req.recurType] * int64 req.recurCount) } + let act = RequestAction.fromString hist.status + Data.addHistory reqId + { asOf = now + status = act + text = match hist.updateText with null | "" -> None | x -> Some x + } sess + match act with + | Prayed -> + let nextShow = + match Recurrence.duration req.recurType with + | 0L -> 0L + | duration -> (Ticks.toLong now) + (duration * int64 req.recurCount) + Data.updateShowAfter reqId (Ticks nextShow) sess | _ -> () - let! _ = db.SaveChangesAsync () + do! Data.saveChanges sess return! created next ctx | None -> return! Error.notFound next ctx } /// POST /api/request/[req-id]/note - let addNote reqId : HttpHandler = + let addNote requestId : HttpHandler = authorize >=> fun next ctx -> task { - let db = db ctx - match! db.TryRequestById reqId (userId ctx) with + use sess = session ctx + let usrId = userId ctx + let reqId = toReqId requestId + match! Data.tryRequestById reqId usrId sess with | Some _ -> let! notes = ctx.BindJsonAsync () - { Note.empty with - requestId = reqId - asOf = jsNow () - notes = notes.notes - } - |> db.AddEntry - let! _ = db.SaveChangesAsync () + Data.addNote reqId { asOf = jsNow (); notes = notes.notes } sess + do! Data.saveChanges sess return! created next ctx | None -> return! Error.notFound next ctx } @@ -239,83 +236,129 @@ module Request = let answered : HttpHandler = authorize >=> fun next ctx -> - userId ctx - |> (db ctx).AnsweredRequests - |> asJson next ctx + task { + use sess = session ctx + let usrId = userId ctx + let! reqs = Data.answeredRequests usrId sess + return! json reqs next ctx + } /// GET /api/request/[req-id] - let get reqId : HttpHandler = + let get requestId : HttpHandler = authorize >=> fun next ctx -> task { - match! (db ctx).TryJournalById reqId (userId ctx) with + use sess = session ctx + let usrId = userId ctx + match! Data.tryJournalById (toReqId requestId) usrId sess with | Some req -> return! json req next ctx | None -> return! Error.notFound next ctx } /// GET /api/request/[req-id]/full - let getFull reqId : HttpHandler = + let getFull requestId : HttpHandler = authorize >=> fun next ctx -> task { - match! (db ctx).TryFullRequestById reqId (userId ctx) with + use sess = session ctx + let usrId = userId ctx + match! Data.tryFullRequestById (toReqId requestId) usrId sess with | Some req -> return! json req next ctx | None -> return! Error.notFound next ctx } /// GET /api/request/[req-id]/notes - let getNotes reqId : HttpHandler = + let getNotes requestId : HttpHandler = authorize >=> fun next ctx -> task { - let! notes = (db ctx).NotesById reqId (userId ctx) + use sess = session ctx + let usrId = userId ctx + let! notes = Data.notesById (toReqId requestId) usrId sess return! json notes next ctx } /// PATCH /api/request/[req-id]/show - let show reqId : HttpHandler = + let show requestId : HttpHandler = authorize >=> fun next ctx -> task { - let db = db ctx - match! db.TryRequestById reqId (userId ctx) with - | Some req -> - let! show = ctx.BindJsonAsync () - { req with showAfter = show.showAfter } - |> db.UpdateEntry - let! _ = db.SaveChangesAsync () + use sess = session ctx + let usrId = userId ctx + let reqId = toReqId requestId + match! Data.tryRequestById reqId usrId sess with + | Some _ -> + Data.updateShowAfter reqId (Ticks 0L) sess + do! Data.saveChanges sess return! setStatusCode 204 next ctx | None -> return! Error.notFound next ctx } /// PATCH /api/request/[req-id]/snooze - let snooze reqId : HttpHandler = + let snooze requestId : HttpHandler = authorize >=> fun next ctx -> task { - let db = db ctx - match! db.TryRequestById reqId (userId ctx) with - | Some req -> + use sess = session ctx + let usrId = userId ctx + let reqId = toReqId requestId + match! Data.tryRequestById reqId usrId sess with + | Some _ -> let! until = ctx.BindJsonAsync () - { req with snoozedUntil = until.until; showAfter = until.until } - |> db.UpdateEntry - let! _ = db.SaveChangesAsync () + Data.updateSnoozed reqId (Ticks until.until) sess + do! Data.saveChanges sess return! setStatusCode 204 next ctx | None -> return! Error.notFound next ctx } /// PATCH /api/request/[req-id]/recurrence - let updateRecurrence reqId : HttpHandler = + let updateRecurrence requestId : HttpHandler = authorize >=> fun next ctx -> task { - let db = db ctx - match! db.TryRequestById reqId (userId ctx) with - | Some req -> + use sess = session ctx + let usrId = userId ctx + let reqId = toReqId requestId + match! Data.tryRequestById reqId usrId sess with + | Some _ -> let! recur = ctx.BindJsonAsync () - { req with recurType = recur.recurType; recurCount = recur.recurCount } - |> db.UpdateEntry - let! _ = db.SaveChangesAsync () + let recurrence = Recurrence.fromString recur.recurType + Data.updateRecurrence reqId recurrence recur.recurCount sess + match recurrence with Immediate -> Data.updateShowAfter reqId (Ticks 0L) sess | _ -> () + do! Data.saveChanges sess return! setStatusCode 204 next ctx | None -> return! Error.notFound next ctx } + +open Giraffe.TokenRouter + +/// The routes for myPrayerJournal +let webApp : HttpHandler = + router Error.notFound [ + route "/" Vue.app + subRoute "/api/" [ + GET [ + route "journal" Journal.journal + subRoute "request" [ + route "s/answered" Request.answered + routef "/%s/full" Request.getFull + routef "/%s/notes" Request.getNotes + routef "/%s" Request.get + ] + ] + PATCH [ + subRoute "request" [ + routef "/%s/recurrence" Request.updateRecurrence + routef "/%s/show" Request.show + routef "/%s/snooze" Request.snooze + ] + ] + POST [ + subRoute "request" [ + route "" Request.add + routef "/%s/history" Request.addHistory + routef "/%s/note" Request.addNote + ] + ] + ] + ] diff --git a/src/api/MyPrayerJournal.Api/MyPrayerJournal.Api.fsproj b/src/MyPrayerJournal.Api/MyPrayerJournal.Api.fsproj similarity index 67% rename from src/api/MyPrayerJournal.Api/MyPrayerJournal.Api.fsproj rename to src/MyPrayerJournal.Api/MyPrayerJournal.Api.fsproj index a24f674..9ab996a 100644 --- a/src/api/MyPrayerJournal.Api/MyPrayerJournal.Api.fsproj +++ b/src/MyPrayerJournal.Api/MyPrayerJournal.Api.fsproj @@ -1,30 +1,30 @@ - + netcoreapp2.2 - 1.2.2.0 + 2.0.0.0 + - + - - + - + diff --git a/src/MyPrayerJournal.Api/Program.fs b/src/MyPrayerJournal.Api/Program.fs new file mode 100644 index 0000000..563fbb7 --- /dev/null +++ b/src/MyPrayerJournal.Api/Program.fs @@ -0,0 +1,144 @@ +module MyPrayerJournal.Api + +open Microsoft.AspNetCore.Builder +open Microsoft.AspNetCore.Hosting +open System.IO + +/// Configuration functions for the application +module Configure = + + /// Configure the content root + let contentRoot root (bldr : IWebHostBuilder) = + bldr.UseContentRoot root + + open Microsoft.Extensions.Configuration + + /// Configure the application configuration + let appConfiguration (bldr : IWebHostBuilder) = + let configuration (ctx : WebHostBuilderContext) (cfg : IConfigurationBuilder) = + cfg.SetBasePath(ctx.HostingEnvironment.ContentRootPath) + .AddJsonFile("appsettings.json", optional = true, reloadOnChange = true) + .AddJsonFile(sprintf "appsettings.%s.json" ctx.HostingEnvironment.EnvironmentName) + .AddEnvironmentVariables () + |> ignore + bldr.ConfigureAppConfiguration configuration + + open Microsoft.AspNetCore.Server.Kestrel.Core + + /// Configure Kestrel from appsettings.json + let kestrel (bldr : IWebHostBuilder) = + let kestrelOpts (ctx : WebHostBuilderContext) (opts : KestrelServerOptions) = + (ctx.Configuration.GetSection >> opts.Configure >> ignore) "Kestrel" + bldr.UseKestrel().ConfigureKestrel kestrelOpts + + /// Configure the web root directory + let webRoot pathSegments (bldr : IWebHostBuilder) = + (Path.Combine >> bldr.UseWebRoot) pathSegments + + open Giraffe + open Giraffe.Serialization + open Microsoft.AspNetCore.Authentication.JwtBearer + open Microsoft.Extensions.DependencyInjection + open MyPrayerJournal.Indexes + open Newtonsoft.Json + open Newtonsoft.Json.Serialization + open Raven.Client.Documents + open Raven.Client.Documents.Indexes + open System.Security.Cryptography.X509Certificates + + /// Configure dependency injection + let services (bldr : IWebHostBuilder) = + let svcs (sc : IServiceCollection) = + /// Custom settings for the JSON serializer (uses compact representation for options and DUs) + let jsonSettings = + let x = NewtonsoftJsonSerializer.DefaultSettings + Converters.all |> List.ofSeq |> List.iter x.Converters.Add + x.NullValueHandling <- NullValueHandling.Ignore + x.MissingMemberHandling <- MissingMemberHandling.Error + x.Formatting <- Formatting.Indented + x.ContractResolver <- DefaultContractResolver () + x + + use sp = sc.BuildServiceProvider () + let cfg = sp.GetRequiredService () + sc.AddGiraffe() + .AddAuthentication( + /// Use HTTP "Bearer" authentication with JWTs + fun opts -> + opts.DefaultAuthenticateScheme <- JwtBearerDefaults.AuthenticationScheme + opts.DefaultChallengeScheme <- JwtBearerDefaults.AuthenticationScheme) + .AddJwtBearer( + /// Configure JWT options with Auth0 options from configuration + fun opts -> + let jwtCfg = cfg.GetSection "Auth0" + opts.Authority <- sprintf "https://%s/" jwtCfg.["Domain"] + opts.Audience <- jwtCfg.["Id"] + ) + |> ignore + sc.AddSingleton (NewtonsoftJsonSerializer jsonSettings) + |> ignore + let config = sc.BuildServiceProvider().GetRequiredService().GetSection "RavenDB" + let store = new DocumentStore () + store.Urls <- [| config.["URL"] |] + store.Database <- config.["Database"] + match isNull config.["Certificate"] with + | true -> () + | false -> store.Certificate <- new X509Certificate2 (config.["Certificate"], config.["Password"]) + store.Conventions.CustomizeJsonSerializer <- fun x -> Converters.all |> List.ofSeq |> List.iter x.Converters.Add + store.Initialize () |> (sc.AddSingleton >> ignore) + IndexCreation.CreateIndexes (typeof.Assembly, store) + bldr.ConfigureServices svcs + + open Microsoft.Extensions.Logging + + /// Configure logging + let logging (bldr : IWebHostBuilder) = + let logz (log : ILoggingBuilder) = + let env = log.Services.BuildServiceProvider().GetService () + match env.IsDevelopment () with + | true -> log + | false -> log.AddFilter(fun l -> l > LogLevel.Information) + |> function l -> l.AddConsole().AddDebug() + |> ignore + bldr.ConfigureLogging logz + + open System + + /// Configure the web application + let application (bldr : IWebHostBuilder) = + let appConfig = + Action ( + fun (app : IApplicationBuilder) -> + let env = app.ApplicationServices.GetService () + match env.IsDevelopment () with + | true -> app.UseDeveloperExceptionPage () + | false -> app.UseGiraffeErrorHandler Handlers.Error.error + |> function + | a -> + a.UseAuthentication() + .UseStaticFiles() + .UseGiraffe Handlers.webApp + |> ignore) + bldr.Configure appConfig + + /// Compose all the configurations into one + let webHost appRoot pathSegments = + contentRoot appRoot + >> appConfiguration + >> kestrel + >> webRoot (Array.concat [ [| appRoot |]; pathSegments ]) + >> services + >> logging + >> application + + /// Build the web host from the given configuration + let buildHost (bldr : IWebHostBuilder) = bldr.Build () + +let exitCode = 0 + +[] +let main _ = + let appRoot = Directory.GetCurrentDirectory () + use host = WebHostBuilder() |> (Configure.webHost appRoot [| "wwwroot" |] >> Configure.buildHost) + host.Run () + exitCode diff --git a/src/api/MyPrayerJournal.Api/Properties/launchSettings.json b/src/MyPrayerJournal.Api/Properties/launchSettings.json similarity index 100% rename from src/api/MyPrayerJournal.Api/Properties/launchSettings.json rename to src/MyPrayerJournal.Api/Properties/launchSettings.json diff --git a/src/api/MyPrayerJournal.Api/appsettings.json b/src/MyPrayerJournal.Api/appsettings.json similarity index 100% rename from src/api/MyPrayerJournal.Api/appsettings.json rename to src/MyPrayerJournal.Api/appsettings.json diff --git a/src/MyPrayerJournal.sln b/src/MyPrayerJournal.sln new file mode 100644 index 0000000..9253d74 --- /dev/null +++ b/src/MyPrayerJournal.sln @@ -0,0 +1,37 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.28721.148 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "MyPrayerJournal.Api", "MyPrayerJournal.Api\MyPrayerJournal.Api.fsproj", "{1887D1E1-544A-4F54-B266-38E7867DC842}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|iPhone = Debug|iPhone + Debug|iPhoneSimulator = Debug|iPhoneSimulator + Release|Any CPU = Release|Any CPU + Release|iPhone = Release|iPhone + Release|iPhoneSimulator = Release|iPhoneSimulator + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1887D1E1-544A-4F54-B266-38E7867DC842}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1887D1E1-544A-4F54-B266-38E7867DC842}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1887D1E1-544A-4F54-B266-38E7867DC842}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {1887D1E1-544A-4F54-B266-38E7867DC842}.Debug|iPhone.Build.0 = Debug|Any CPU + {1887D1E1-544A-4F54-B266-38E7867DC842}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {1887D1E1-544A-4F54-B266-38E7867DC842}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {1887D1E1-544A-4F54-B266-38E7867DC842}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1887D1E1-544A-4F54-B266-38E7867DC842}.Release|Any CPU.Build.0 = Release|Any CPU + {1887D1E1-544A-4F54-B266-38E7867DC842}.Release|iPhone.ActiveCfg = Release|Any CPU + {1887D1E1-544A-4F54-B266-38E7867DC842}.Release|iPhone.Build.0 = Release|Any CPU + {1887D1E1-544A-4F54-B266-38E7867DC842}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {1887D1E1-544A-4F54-B266-38E7867DC842}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {8E2447D9-52F0-4A0D-BB61-A83C19353D7C} + EndGlobalSection +EndGlobal diff --git a/src/api/MyPrayerJournal.Api/Data.fs b/src/api/MyPrayerJournal.Api/Data.fs deleted file mode 100644 index bbfecc2..0000000 --- a/src/api/MyPrayerJournal.Api/Data.fs +++ /dev/null @@ -1,275 +0,0 @@ -namespace MyPrayerJournal - -open FSharp.Control.Tasks.V2.ContextInsensitive -open Microsoft.EntityFrameworkCore -open Microsoft.FSharpLu - -/// Entities for use in the data model for myPrayerJournal -[] -module Entities = - - open FSharp.EFCore.OptionConverter - open System.Collections.Generic - - /// Type alias for a Collision-resistant Unique IDentifier - type Cuid = string - - /// Request ID is a CUID - type RequestId = Cuid - - /// User ID is a string (the "sub" part of the JWT) - type UserId = string - - /// History is a record of action taken on a prayer request, including updates to its text - type [] History = - { /// The ID of the request to which this history entry applies - requestId : RequestId - /// The time when this history entry was made - asOf : int64 - /// The status for this history entry - status : string - /// The text of the update, if applicable - text : string option - } - with - /// An empty history entry - static member empty = - { requestId = "" - asOf = 0L - status = "" - text = None - } - - static member configureEF (mb : ModelBuilder) = - mb.Entity ( - fun m -> - m.ToTable "history" |> ignore - m.HasKey ("requestId", "asOf") |> ignore - m.Property(fun e -> e.requestId).IsRequired () |> ignore - m.Property(fun e -> e.asOf).IsRequired () |> ignore - m.Property(fun e -> e.status).IsRequired() |> ignore - m.Property(fun e -> e.text) |> ignore) - |> ignore - let typ = mb.Model.FindEntityType(typeof) - let prop = typ.FindProperty("text") - mb.Model.FindEntityType(typeof).FindProperty("text").SetValueConverter (OptionConverter ()) - - /// Note is a note regarding a prayer request that does not result in an update to its text - and [] Note = - { /// The ID of the request to which this note applies - requestId : RequestId - /// The time when this note was made - asOf : int64 - /// The text of the notes - notes : string - } - with - /// An empty note - static member empty = - { requestId = "" - asOf = 0L - notes = "" - } - - static member configureEF (mb : ModelBuilder) = - mb.Entity ( - fun m -> - m.ToTable "note" |> ignore - m.HasKey ("requestId", "asOf") |> ignore - m.Property(fun e -> e.requestId).IsRequired () |> ignore - m.Property(fun e -> e.asOf).IsRequired () |> ignore - m.Property(fun e -> e.notes).IsRequired () |> ignore) - |> ignore - - /// Request is the identifying record for a prayer request - and [] Request = - { /// The ID of the request - requestId : RequestId - /// The time this request was initially entered - enteredOn : int64 - /// The ID of the user to whom this request belongs ("sub" from the JWT) - userId : string - /// The time at which this request should reappear in the user's journal by manual user choice - snoozedUntil : int64 - /// The time at which this request should reappear in the user's journal by recurrence - showAfter : int64 - /// The type of recurrence for this request - recurType : string - /// How many of the recurrence intervals should occur between appearances in the journal - recurCount : int16 - /// The history entries for this request - history : ICollection - /// The notes for this request - notes : ICollection - } - with - /// An empty request - static member empty = - { requestId = "" - enteredOn = 0L - userId = "" - snoozedUntil = 0L - showAfter = 0L - recurType = "immediate" - recurCount = 0s - history = List () - notes = List () - } - - static member configureEF (mb : ModelBuilder) = - mb.Entity ( - fun m -> - m.ToTable "request" |> ignore - m.HasKey(fun e -> e.requestId :> obj) |> ignore - m.Property(fun e -> e.requestId).IsRequired () |> ignore - m.Property(fun e -> e.enteredOn).IsRequired () |> ignore - m.Property(fun e -> e.userId).IsRequired () |> ignore - m.Property(fun e -> e.snoozedUntil).IsRequired () |> ignore - m.Property(fun e -> e.showAfter).IsRequired () |> ignore - m.Property(fun e -> e.recurType).IsRequired() |> ignore - m.Property(fun e -> e.recurCount).IsRequired() |> ignore - m.HasMany(fun e -> e.history :> IEnumerable) - .WithOne() - .HasForeignKey(fun e -> e.requestId :> obj) - |> ignore - m.HasMany(fun e -> e.notes :> IEnumerable) - .WithOne() - .HasForeignKey(fun e -> e.requestId :> obj) - |> ignore) - |> ignore - - /// JournalRequest is the form of a prayer request returned for the request journal display. It also contains - /// properties that may be filled for history and notes - [] - type JournalRequest = - { /// The ID of the request - requestId : RequestId - /// The ID of the user to whom the request belongs - userId : string - /// The current text of the request - text : string - /// The last time action was taken on the request - asOf : int64 - /// The last status for the request - lastStatus : string - /// The time that this request should reappear in the user's journal - snoozedUntil : int64 - /// The time after which this request should reappear in the user's journal by configured recurrence - showAfter : int64 - /// The type of recurrence for this request - recurType : string - /// How many of the recurrence intervals should occur between appearances in the journal - recurCount : int16 - /// History entries for the request - history : History list - /// Note entries for the request - notes : Note list - } - with - static member configureEF (mb : ModelBuilder) = - mb.Query ( - fun m -> - m.ToView "journal" |> ignore - m.Ignore(fun e -> e.history :> obj) |> ignore - m.Ignore(fun e -> e.notes :> obj) |> ignore) - |> ignore - - -open System.Linq - -/// Data context -type AppDbContext (opts : DbContextOptions) = - inherit DbContext (opts) - - [] - val mutable private history : DbSet - [] - val mutable private notes : DbSet - [] - val mutable private requests : DbSet - [] - val mutable private journal : DbQuery - - member this.History - with get () = this.history - and set v = this.history <- v - member this.Notes - with get () = this.notes - and set v = this.notes <- v - member this.Requests - with get () = this.requests - and set v = this.requests <- v - member this.Journal - with get () = this.journal - and set v = this.journal <- v - - override __.OnModelCreating (mb : ModelBuilder) = - base.OnModelCreating mb - [ History.configureEF - Note.configureEF - Request.configureEF - JournalRequest.configureEF - ] - |> List.iter (fun x -> x mb) - - /// Register a disconnected entity with the context, having the given state - member private this.RegisterAs<'TEntity when 'TEntity : not struct> state e = - this.Entry<'TEntity>(e).State <- state - - /// Add an entity instance to the context - member this.AddEntry e = - this.RegisterAs EntityState.Added e - - /// Update the entity instance's values - member this.UpdateEntry e = - this.RegisterAs EntityState.Modified e - - /// Retrieve all answered requests for the given user - member this.AnsweredRequests userId : JournalRequest seq = - upcast this.Journal - .Where(fun r -> r.userId = userId && r.lastStatus = "Answered") - .OrderByDescending(fun r -> r.asOf) - - /// Retrieve the user's current journal - member this.JournalByUserId userId : JournalRequest seq = - upcast this.Journal - .Where(fun r -> r.userId = userId && r.lastStatus <> "Answered") - .OrderBy(fun r -> r.showAfter) - - /// Retrieve a request by its ID and user ID - member this.TryRequestById reqId userId = - task { - let! req = this.Requests.AsNoTracking().FirstOrDefaultAsync(fun r -> r.requestId = reqId && r.userId = userId) - return Option.fromObject req - } - - /// Retrieve notes for a request by its ID and user ID - member this.NotesById reqId userId = - task { - match! this.TryRequestById reqId userId with - | Some _ -> return this.Notes.AsNoTracking().Where(fun n -> n.requestId = reqId) |> List.ofSeq - | None -> return [] - } - - /// Retrieve a journal request by its ID and user ID - member this.TryJournalById reqId userId = - task { - let! req = this.Journal.FirstOrDefaultAsync(fun r -> r.requestId = reqId && r.userId = userId) - return Option.fromObject req - } - - /// Retrieve a request, including its history and notes, by its ID and user ID - member this.TryFullRequestById requestId userId = - task { - match! this.TryJournalById requestId userId with - | Some req -> - let! fullReq = - this.Requests.AsNoTracking() - .Include(fun r -> r.history) - .Include(fun r -> r.notes) - .FirstOrDefaultAsync(fun r -> r.requestId = requestId && r.userId = userId) - match Option.fromObject fullReq with - | Some _ -> return Some { req with history = List.ofSeq fullReq.history; notes = List.ofSeq fullReq.notes } - | None -> return None - | None -> return None - } diff --git a/src/api/MyPrayerJournal.Api/Program.fs b/src/api/MyPrayerJournal.Api/Program.fs deleted file mode 100644 index 3a118d3..0000000 --- a/src/api/MyPrayerJournal.Api/Program.fs +++ /dev/null @@ -1,139 +0,0 @@ -namespace MyPrayerJournal.Api - -open Microsoft.AspNetCore.Builder -open Microsoft.AspNetCore.Hosting -open System - -/// Configuration functions for the application -module Configure = - - open Giraffe - open Giraffe.Serialization - open Giraffe.TokenRouter - open Microsoft.AspNetCore.Authentication.JwtBearer - open Microsoft.AspNetCore.Server.Kestrel.Core - open Microsoft.EntityFrameworkCore - open Microsoft.Extensions.Configuration - open Microsoft.Extensions.DependencyInjection - open Microsoft.Extensions.Logging - open Microsoft.FSharpLu.Json - open MyPrayerJournal - open Newtonsoft.Json - - /// Set up the configuration for the app - let configuration (ctx : WebHostBuilderContext) (cfg : IConfigurationBuilder) = - cfg.SetBasePath(ctx.HostingEnvironment.ContentRootPath) - .AddJsonFile("appsettings.json", optional = true, reloadOnChange = true) - .AddJsonFile(sprintf "appsettings.%s.json" ctx.HostingEnvironment.EnvironmentName) - .AddEnvironmentVariables() - |> ignore - - /// Configure Kestrel from appsettings.json - let kestrel (ctx : WebHostBuilderContext) (opts : KestrelServerOptions) = - (ctx.Configuration.GetSection >> opts.Configure >> ignore) "Kestrel" - - /// Custom settings for the JSON serializer (uses compact representation for options and DUs) - let jsonSettings = - let x = NewtonsoftJsonSerializer.DefaultSettings - x.Converters.Add (CompactUnionJsonConverter (true)) - x.NullValueHandling <- NullValueHandling.Ignore - x.MissingMemberHandling <- MissingMemberHandling.Error - x.Formatting <- Formatting.Indented - x - - /// Configure dependency injection - let services (sc : IServiceCollection) = - use sp = sc.BuildServiceProvider() - let cfg = sp.GetRequiredService () - sc.AddGiraffe() - .AddAuthentication( - /// Use HTTP "Bearer" authentication with JWTs - fun opts -> - opts.DefaultAuthenticateScheme <- JwtBearerDefaults.AuthenticationScheme - opts.DefaultChallengeScheme <- JwtBearerDefaults.AuthenticationScheme) - .AddJwtBearer( - /// Configure JWT options with Auth0 options from configuration - fun opts -> - let jwtCfg = cfg.GetSection "Auth0" - opts.Authority <- sprintf "https://%s/" jwtCfg.["Domain"] - opts.Audience <- jwtCfg.["Id"]) - |> ignore - sc.AddDbContext(fun opts -> opts.UseNpgsql(cfg.GetConnectionString "mpj") |> ignore) - .AddSingleton(NewtonsoftJsonSerializer jsonSettings) - |> ignore - - /// Routes for the available URLs within myPrayerJournal - let webApp = - router Handlers.Error.notFound [ - route "/" Handlers.Vue.app - subRoute "/api/" [ - GET [ - route "journal" Handlers.Journal.journal - subRoute "request" [ - route "s/answered" Handlers.Request.answered - routef "/%s/full" Handlers.Request.getFull - routef "/%s/notes" Handlers.Request.getNotes - routef "/%s" Handlers.Request.get - ] - ] - PATCH [ - subRoute "request" [ - routef "/%s/recurrence" Handlers.Request.updateRecurrence - routef "/%s/show" Handlers.Request.show - routef "/%s/snooze" Handlers.Request.snooze - ] - ] - POST [ - subRoute "request" [ - route "" Handlers.Request.add - routef "/%s/history" Handlers.Request.addHistory - routef "/%s/note" Handlers.Request.addNote - ] - ] - ] - ] - - /// Configure the web application - let application (app : IApplicationBuilder) = - let env = app.ApplicationServices.GetService () - match env.IsDevelopment () with - | true -> app.UseDeveloperExceptionPage () - | false -> app.UseGiraffeErrorHandler Handlers.Error.error - |> function - | a -> - a.UseAuthentication() - .UseStaticFiles() - .UseGiraffe webApp - |> ignore - - /// Configure logging - let logging (log : ILoggingBuilder) = - let env = log.Services.BuildServiceProvider().GetService () - match env.IsDevelopment () with - | true -> log - | false -> log.AddFilter(fun l -> l > LogLevel.Information) - |> function l -> l.AddConsole().AddDebug() - |> ignore - - -module Program = - - open System.IO - - let exitCode = 0 - - let CreateWebHostBuilder _ = - let contentRoot = Directory.GetCurrentDirectory () - WebHostBuilder() - .UseContentRoot(contentRoot) - .ConfigureAppConfiguration(Configure.configuration) - .UseKestrel(Configure.kestrel) - .UseWebRoot(Path.Combine (contentRoot, "wwwroot")) - .ConfigureServices(Configure.services) - .ConfigureLogging(Configure.logging) - .Configure(Action Configure.application) - - [] - let main args = - CreateWebHostBuilder(args).Build().Run() - exitCode diff --git a/src/api/MyPrayerJournal.sln b/src/api/MyPrayerJournal.sln deleted file mode 100644 index 959b629..0000000 --- a/src/api/MyPrayerJournal.sln +++ /dev/null @@ -1,25 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.27703.2035 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "MyPrayerJournal.Api", "MyPrayerJournal.Api\MyPrayerJournal.Api.fsproj", "{E0E5240C-00DC-428A-899A-DA4F06625B8A}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {E0E5240C-00DC-428A-899A-DA4F06625B8A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E0E5240C-00DC-428A-899A-DA4F06625B8A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E0E5240C-00DC-428A-899A-DA4F06625B8A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E0E5240C-00DC-428A-899A-DA4F06625B8A}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {7EAB6243-94B3-49A5-BA64-7F01B8BE7CB9} - EndGlobalSection -EndGlobal diff --git a/src/app/package.json b/src/app/package.json index 1cf6264..a2053d7 100644 --- a/src/app/package.json +++ b/src/app/package.json @@ -1,25 +1,24 @@ { "name": "my-prayer-journal", - "version": "1.2.2", + "version": "2.0.0", "description": "myPrayerJournal - Front End", "author": "Daniel J. Summers ", "private": true, "scripts": { - "serve": "vue-cli-service serve", + "serve": "vue-cli-service serve --port 8081", "build": "vue-cli-service build --modern", "lint": "vue-cli-service lint", - "apistart": "cd ../api/MyPrayerJournal.Api && dotnet run", - "vue": "vue-cli-service build --modern && cd ../api/MyPrayerJournal.Api && dotnet run", - "publish": "vue-cli-service build --modern && cd ../api/MyPrayerJournal.Api && dotnet publish -c Release" + "apistart": "cd ../MyPrayerJournal.Api && dotnet run", + "vue": "vue-cli-service build --modern && cd ../MyPrayerJournal.Api && dotnet run", + "publish": "vue-cli-service build --modern && cd ../MyPrayerJournal.Api && dotnet publish -c Release" }, "dependencies": { "auth0-js": "^9.7.3", "axios": "^0.19.0", "moment": "^2.18.1", "vue": "^2.5.15", - "vue-progressbar": "^0.7.3", + "vue-material": "^1.0.0-beta-11", "vue-router": "^3.0.0", - "vue-toast": "^3.1.0", "vuex": "^3.0.1" }, "devDependencies": { @@ -27,8 +26,11 @@ "@vue/cli-plugin-eslint": "^3.0.0", "@vue/cli-service": "^3.0.0", "@vue/eslint-config-standard": "^4.0.0", + "node-sass": "^4.12.0", "pug": "^2.0.1", "pug-plain-loader": "^1.0.0", - "vue-template-compiler": "^2.5.17" + "sass-loader": "^7.3.1", + "vue-template-compiler": "^2.5.17", + "webpack-bundle-analyzer": "^3.4.1" } } diff --git a/src/app/src/App.vue b/src/app/src/App.vue index c28a592..ec693bd 100644 --- a/src/app/src/App.vue +++ b/src/app/src/App.vue @@ -1,26 +1,41 @@ - diff --git a/src/app/src/api/index.js b/src/app/src/api/index.js index ac1046a..bb431fc 100644 --- a/src/app/src/api/index.js +++ b/src/app/src/api/index.js @@ -15,12 +15,12 @@ export default { * Set the bearer token for all future requests * @param {string} token The token to use to identify the user to the server */ - setBearer: token => { http.defaults.headers.common['authorization'] = `Bearer ${token}` }, + setBearer: token => { http.defaults.headers.common['Authorization'] = `Bearer ${token}` }, /** * Remove the bearer token */ - removeBearer: () => delete http.defaults.headers.common['authorization'], + removeBearer: () => delete http.defaults.headers.common['Authorization'], /** * Add a note for a prayer request diff --git a/src/app/src/auth/AuthService.js b/src/app/src/auth/AuthService.js index 85e7f5c..2a22bc5 100644 --- a/src/app/src/auth/AuthService.js +++ b/src/app/src/auth/AuthService.js @@ -1,31 +1,45 @@ 'use strict' - -import auth0 from 'auth0-js' +/* eslint-disable */ +import auth0 from 'auth0-js' +import EventEmitter from 'events' import AUTH_CONFIG from './auth0-variables' -import mutations from '@/store/mutation-types' +import mutations from '@/store/mutation-types' +/* es-lint-enable*/ -var tokenRenewalTimeout +// Auth0 web authentication instance to use for our calls +const webAuth = new auth0.WebAuth({ + domain: AUTH_CONFIG.domain, + clientID: AUTH_CONFIG.clientId, + redirectUri: AUTH_CONFIG.appDomain + AUTH_CONFIG.callbackUrl, + audience: `https://${AUTH_CONFIG.domain}/userinfo`, + responseType: 'token id_token', + scope: 'openid profile email' +}) -export default class AuthService { - constructor () { - this.login = this.login.bind(this) - this.setSession = this.setSession.bind(this) - this.logout = this.logout.bind(this) - this.isAuthenticated = this.isAuthenticated.bind(this) +/** + * A class to handle all authentication calls and determinations + */ +class AuthService extends EventEmitter { + + // Local storage key for our session data + AUTH_SESSION = 'auth-session' + + // Received and calculated values for our ssesion (initially loaded from local storage if present) + session = {} + + constructor() { + super() + this.refreshSession() } - auth0 = new auth0.WebAuth({ - domain: AUTH_CONFIG.domain, - clientID: AUTH_CONFIG.clientId, - redirectUri: AUTH_CONFIG.appDomain + AUTH_CONFIG.callbackUrl, - audience: `https://${AUTH_CONFIG.domain}/userinfo`, - responseType: 'token id_token', - scope: 'openid profile email' - }) - - login () { - this.auth0.authorize() + /** + * Starts the user log in flow + */ + login (customState) { + webAuth.authorize({ + appState: customState + }) } /** @@ -33,7 +47,7 @@ export default class AuthService { */ parseHash () { return new Promise((resolve, reject) => { - this.auth0.parseHash((err, authResult) => { + webAuth.parseHash((err, authResult) => { if (err) { reject(err) } else { @@ -44,95 +58,137 @@ export default class AuthService { } /** - * Promisified userInfo function - * - * @param token The auth token from the login result + * Handle authentication replies from Auth0 + * + * @param store The Vuex store */ - userInfo (token) { - return new Promise((resolve, reject) => { - this.auth0.client.userInfo(token, (err, user) => { - if (err) { - reject(err) - } else { - resolve(user) - } - }) - }) - } - - handleAuthentication (store, router) { - this.parseHash() - .then(authResult => { - if (authResult && authResult.accessToken && authResult.idToken) { - this.setSession(authResult) - this.userInfo(authResult.accessToken) - .then(user => { - store.commit(mutations.USER_LOGGED_ON, user) - router.replace('/journal') - }) - } - }) - .catch(err => { - router.replace('/') - console.log(err) - alert(`Error: ${err.error}. Check the console for further details.`) - }) - } - - scheduleRenewal () { - let expiresAt = JSON.parse(localStorage.getItem('expires_at')) - let delay = expiresAt - Date.now() - if (delay > 0) { - tokenRenewalTimeout = setTimeout(() => { - this.renewToken() - }, delay) + async handleAuthentication (store) { + try { + const authResult = await this.parseHash() + if (authResult && authResult.accessToken && authResult.idToken) { + this.setSession(authResult) + store.commit(mutations.USER_LOGGED_ON, this.session.profile) + } + } catch(err) { + console.error(err) + alert(`Error: ${err.error}. Check the console for further details.`) } } + /** + * Set up the session and commit it to local storage + * + * @param authResult The authorization result + */ setSession (authResult) { - // Set the time that the access token will expire at - let expiresAt = JSON.stringify( - authResult.expiresIn * 1000 + new Date().getTime() - ) - localStorage.setItem('access_token', authResult.accessToken) - localStorage.setItem('id_token', authResult.idToken) - localStorage.setItem('expires_at', expiresAt) - this.scheduleRenewal() + this.session.profile = authResult.idTokenPayload + this.session.id.token = authResult.idToken + this.session.id.expiry = this.session.profile.exp * 1000 + this.session.access.token = authResult.accessToken + this.session.access.expiry = authResult.expiresIn * 1000 + Date.now() + + localStorage.setItem(this.AUTH_SESSION, JSON.stringify(this.session)) + + this.emit('loginEvent', { + loggedIn: true, + profile: authResult.idTokenPayload, + state: authResult.appState || {} + }) } - renewToken () { - console.log('attempting renewal...') - this.auth0.renewAuth( - { - audience: `https://${AUTH_CONFIG.domain}/userinfo`, - redirectUri: `${AUTH_CONFIG.appDomain}/static/silent.html`, - usePostMessage: true - }, - (err, result) => { - if (err) { - console.log(err) - } else { - this.setSession(result) + /** + * Refresh this instance's session from the one in local storage + */ + refreshSession () { + this.session = + localStorage.getItem(this.AUTH_SESSION) + ? JSON.parse(localStorage.getItem(this.AUTH_SESSION)) + : { profile: {}, + id: { + token: null, + expiry: null + }, + access: { + token: null, + expiry: null + } } + } + + /** + * Renew authorzation tokens with Auth0 + */ + renewTokens () { + return new Promise((resolve, reject) => { + this.refreshSession() + if (this.session.id.token !== null) { + webAuth.checkSession({}, (err, authResult) => { + if (err) { + reject(err) + } else { + this.setSession(authResult) + resolve(authResult) + } + }) + } else { + reject('Not logged in') } - ) + }) } - logout (store, router) { + /** + * Log out of myPrayerJournal + * + * @param store The Vuex store + */ + logout (store) { // Clear access token and ID token from local storage - clearTimeout(tokenRenewalTimeout) - localStorage.removeItem('access_token') - localStorage.removeItem('id_token') - localStorage.removeItem('expires_at') - localStorage.setItem('user_profile', JSON.stringify({})) - // navigate to the home route + localStorage.removeItem(this.AUTH_SESSION) + this.refreshSession() + store.commit(mutations.USER_LOGGED_OFF) - router.replace('/') + + webAuth.logout({ + returnTo: `${AUTH_CONFIG.appDomain}/`, + clientID: AUTH_CONFIG.clientId + }) + this.emit('loginEvent', { loggedIn: false }) } + /** + * Check expiration for a token (the way it's stored in the session) + */ + checkExpiry = (it) => it.token && it.expiry && Date.now() < it.expiry + + /** + * Is there a user authenticated? + */ isAuthenticated () { - // Check whether the current time is past the access token's expiry time - let expiresAt = JSON.parse(localStorage.getItem('expires_at')) - return new Date().getTime() < expiresAt + return this.checkExpiry(this.session.id) + } + + /** + * Is the current access token valid? + */ + isAccessTokenValid () { + return this.checkExpiry(this.session.access) + } + + /** + * Get the user's access token, renewing it if required + */ + async getAccessToken () { + if (this.isAccessTokenValid()) { + return this.session.access.token + } else { + try { + const authResult = await this.renewTokens() + return authResult.accessToken + } catch (reject) { + throw reject + } + } } } + +export default new AuthService() diff --git a/src/app/src/components/Home.vue b/src/app/src/components/Home.vue index 41a7e68..c764a6b 100644 --- a/src/app/src/components/Home.vue +++ b/src/app/src/components/Home.vue @@ -1,16 +1,16 @@ - diff --git a/src/app/src/components/common/MaterialDesignIcon.vue b/src/app/src/components/common/MaterialDesignIcon.vue deleted file mode 100644 index e4ebce0..0000000 --- a/src/app/src/components/common/MaterialDesignIcon.vue +++ /dev/null @@ -1,15 +0,0 @@ - - - diff --git a/src/app/src/components/common/Navigation.vue b/src/app/src/components/common/Navigation.vue index ea9abc9..fdf251f 100644 --- a/src/app/src/components/common/Navigation.vue +++ b/src/app/src/components/common/Navigation.vue @@ -1,34 +1,29 @@ - - diff --git a/src/app/src/components/common/PageTitle.vue b/src/app/src/components/common/PageTitle.vue index cf17685..7f5c04b 100644 --- a/src/app/src/components/common/PageTitle.vue +++ b/src/app/src/components/common/PageTitle.vue @@ -1,6 +1,6 @@ - - diff --git a/src/app/src/components/legal/PrivacyPolicy.vue b/src/app/src/components/legal/PrivacyPolicy.vue index 9d338f1..5bf1099 100644 --- a/src/app/src/components/legal/PrivacyPolicy.vue +++ b/src/app/src/components/legal/PrivacyPolicy.vue @@ -1,54 +1,59 @@ diff --git a/src/app/src/components/legal/TermsOfService.vue b/src/app/src/components/legal/TermsOfService.vue index 6b90d04..960a0e6 100644 --- a/src/app/src/components/legal/TermsOfService.vue +++ b/src/app/src/components/legal/TermsOfService.vue @@ -1,35 +1,40 @@ diff --git a/src/app/src/components/request/ActiveRequests.vue b/src/app/src/components/request/ActiveRequests.vue index a5d67b7..5353488 100644 --- a/src/app/src/components/request/ActiveRequests.vue +++ b/src/app/src/components/request/ActiveRequests.vue @@ -1,13 +1,16 @@ @@ -16,14 +19,15 @@ article.mpj-main-content(role='main') import { mapState } from 'vuex' -import RequestListItem from '@/components/request/RequestListItem' +import RequestList from '@/components/request/RequestList' import actions from '@/store/action-types' export default { name: 'active-requests', + inject: ['progress'], components: { - RequestListItem + RequestList }, data () { return { @@ -32,9 +36,6 @@ export default { } }, computed: { - toast () { - return this.$parent.$refs.toast - }, ...mapState(['journal', 'isLoadingJournal']) }, created () { @@ -45,7 +46,7 @@ export default { async ensureJournal () { if (!Array.isArray(this.journal)) { this.loaded = false - await this.$store.dispatch(actions.LOAD_JOURNAL, this.$Progress) + await this.$store.dispatch(actions.LOAD_JOURNAL, this.progress) } this.requests = this.journal .sort((a, b) => a.showAfter - b.showAfter) diff --git a/src/app/src/components/request/AnsweredRequests.vue b/src/app/src/components/request/AnsweredRequests.vue index 260ffb9..065ace8 100644 --- a/src/app/src/components/request/AnsweredRequests.vue +++ b/src/app/src/components/request/AnsweredRequests.vue @@ -1,13 +1,15 @@ @@ -16,12 +18,16 @@ article.mpj-main-content(role='main') import api from '@/api' -import RequestListItem from '@/components/request/RequestListItem' +import RequestList from '@/components/request/RequestList' export default { name: 'answered-requests', + inject: [ + 'messages', + 'progress' + ], components: { - RequestListItem + RequestList }, data () { return { @@ -29,21 +35,16 @@ export default { loaded: false } }, - computed: { - toast () { - return this.$parent.$refs.toast - } - }, async mounted () { - this.$Progress.start() + this.progress.$emit('show', 'query') try { const reqs = await api.getAnsweredRequests() this.requests = reqs.data - this.$Progress.finish() + this.progress.$emit('done') } catch (err) { console.error(err) - this.toast.showToast('Error loading requests; check console for details', { theme: 'danger' }) - this.$Progress.fail() + this.messages.$emit('error', 'Error loading requests; check console for details') + this.progress.$emit('done') } finally { this.loaded = true } diff --git a/src/app/src/components/request/EditRequest.vue b/src/app/src/components/request/EditRequest.vue index 9221e26..8c578ac 100644 --- a/src/app/src/components/request/EditRequest.vue +++ b/src/app/src/components/request/EditRequest.vue @@ -1,71 +1,52 @@ - - diff --git a/src/app/src/components/request/FullRequest.vue b/src/app/src/components/request/FullRequest.vue index 99bb6a7..e54556f 100644 --- a/src/app/src/components/request/FullRequest.vue +++ b/src/app/src/components/request/FullRequest.vue @@ -1,22 +1,24 @@ @@ -31,6 +33,7 @@ const asOfDesc = (a, b) => b.asOf - a.asOf export default { name: 'full-request', + inject: ['progress'], props: { id: { type: String, @@ -72,14 +75,14 @@ export default { } }, async mounted () { - this.$Progress.start() + this.progress.$emit('show', 'indeterminate') try { const req = await api.getFullRequest(this.id) this.request = req.data - this.$Progress.finish() + this.progress.$emit('done') } catch (e) { console.log(e) - this.$Progress.fail() + this.progress.$emit('done') } }, methods: { diff --git a/src/app/src/components/request/NotesEdit.vue b/src/app/src/components/request/NotesEdit.vue index 85c28e1..6f964bf 100644 --- a/src/app/src/components/request/NotesEdit.vue +++ b/src/app/src/components/request/NotesEdit.vue @@ -1,21 +1,16 @@ - diff --git a/src/app/src/components/request/RequestCard.vue b/src/app/src/components/request/RequestCard.vue index e287784..a3b5fbf 100644 --- a/src/app/src/components/request/RequestCard.vue +++ b/src/app/src/components/request/RequestCard.vue @@ -1,17 +1,27 @@ - diff --git a/src/app/src/components/request/RequestList.vue b/src/app/src/components/request/RequestList.vue new file mode 100644 index 0000000..9529245 --- /dev/null +++ b/src/app/src/components/request/RequestList.vue @@ -0,0 +1,40 @@ + + + diff --git a/src/app/src/components/request/RequestListItem.vue b/src/app/src/components/request/RequestListItem.vue index b855ebe..9edbcce 100644 --- a/src/app/src/components/request/RequestListItem.vue +++ b/src/app/src/components/request/RequestListItem.vue @@ -1,31 +1,31 @@ + + diff --git a/src/app/src/components/request/SnoozeRequest.vue b/src/app/src/components/request/SnoozeRequest.vue index 0fb1cb1..472894e 100644 --- a/src/app/src/components/request/SnoozeRequest.vue +++ b/src/app/src/components/request/SnoozeRequest.vue @@ -1,22 +1,15 @@ diff --git a/src/app/src/main.js b/src/app/src/main.js index 6ef0f0d..f86c531 100644 --- a/src/app/src/main.js +++ b/src/app/src/main.js @@ -1,33 +1,61 @@ +/* eslint-disable */ + +// Vue packages and components import Vue from 'vue' -import VueProgressBar from 'vue-progressbar' -import VueToast from 'vue-toast' +import { MdApp, + MdButton, + MdCard, + MdContent, + MdDatepicker, + MdDialog, + MdEmptyState, + MdField, + MdIcon, + MdLayout, + MdProgress, + MdRadio, + MdSnackbar, + MdTable, + MdTabs, + MdToolbar, + MdTooltip } from 'vue-material/dist/components' -import 'vue-toast/dist/vue-toast.min.css' - -import App from './App' -import router from './router' -import store from './store' +// myPrayerJournal components +import App from './App' +import router from './router' +import store from './store' import DateFromNow from './components/common/DateFromNow' -import MaterialDesignIcon from './components/common/MaterialDesignIcon' -import PageTitle from './components/common/PageTitle' +import PageTitle from './components/common/PageTitle' +import AuthPlugin from './plugins/auth' + +/* eslint-enable */ + +// Styles +import 'vue-material/dist/vue-material.min.css' +import 'vue-material/dist/theme/default.css' Vue.config.productionTip = false -Vue.use(VueProgressBar, { - color: 'yellow', - failedColor: 'red', - height: '5px', - transition: { - speed: '0.2s', - opacity: '0.6s', - termination: 1000 - } -}) - +Vue.use(MdApp) +Vue.use(MdButton) +Vue.use(MdCard) +Vue.use(MdContent) +Vue.use(MdDatepicker) +Vue.use(MdDialog) +Vue.use(MdEmptyState) +Vue.use(MdField) +Vue.use(MdIcon) +Vue.use(MdLayout) +Vue.use(MdProgress) +Vue.use(MdRadio) +Vue.use(MdSnackbar) +Vue.use(MdTable) +Vue.use(MdTabs) +Vue.use(MdToolbar) +Vue.use(MdTooltip) +Vue.use(AuthPlugin) Vue.component('date-from-now', DateFromNow) -Vue.component('md-icon', MaterialDesignIcon) Vue.component('page-title', PageTitle) -Vue.component('toast', VueToast) new Vue({ router, diff --git a/src/app/src/plugins/auth.js b/src/app/src/plugins/auth.js new file mode 100644 index 0000000..003dd50 --- /dev/null +++ b/src/app/src/plugins/auth.js @@ -0,0 +1,22 @@ +'use strict' + +import authService from '../auth/AuthService' + +export default { + install (Vue) { + Vue.prototype.$auth = authService + + Vue.mixin({ + created () { + if (this.handleLoginEvent) { + authService.addListener('loginEvent', this.handleLoginEvent) + } + }, + destroyed () { + if (this.handleLoginEvent) { + authService.removeListener('loginEvent', this.handleLoginEvent) + } + } + }) + } +} diff --git a/src/app/src/router.js b/src/app/src/router.js index a30db29..b22a227 100644 --- a/src/app/src/router.js +++ b/src/app/src/router.js @@ -1,18 +1,12 @@ 'use strict' -import Vue from 'vue' +/* eslint-disable */ +import Vue from 'vue' import Router from 'vue-router' -import ActiveRequests from '@/components/request/ActiveRequests' -import AnsweredRequests from '@/components/request/AnsweredRequests' -import EditRequest from '@/components/request/EditRequest' -import FullRequest from '@/components/request/FullRequest' +import auth from './auth/AuthService' import Home from '@/components/Home' -import Journal from '@/components/Journal' -import LogOn from '@/components/user/LogOn' -import PrivacyPolicy from '@/components/legal/PrivacyPolicy' -import SnoozedRequests from '@/components/request/SnoozedRequests' -import TermsOfService from '@/components/legal/TermsOfService' +/* eslint-enable */ Vue.use(Router) @@ -26,6 +20,12 @@ export default new Router({ return { x: 0, y: 0 } } }, + beforeEach (to, from, next) { + if (to.path === '/' || to.path === '/user/log-on' || auth.isAuthenticated()) { + return next() + } + auth.login({ target: to.path }) + }, routes: [ { path: '/', @@ -35,49 +35,49 @@ export default new Router({ { path: '/journal', name: 'Journal', - component: Journal + component: () => import('@/components/Journal') }, { path: '/legal/privacy-policy', name: 'PrivacyPolicy', - component: PrivacyPolicy + component: () => import('@/components/legal/PrivacyPolicy') }, { path: '/legal/terms-of-service', name: 'TermsOfService', - component: TermsOfService + component: () => import('@/components/legal/TermsOfService') }, { path: '/request/:id/edit', name: 'EditRequest', - component: EditRequest, + component: () => import('@/components/request/EditRequest'), props: true }, { path: '/request/:id/full', name: 'FullRequest', - component: FullRequest, + component: () => import('@/components/request/FullRequest'), props: true }, { path: '/requests/active', name: 'ActiveRequests', - component: ActiveRequests + component: () => import('@/components/request/ActiveRequests') }, { path: '/requests/answered', name: 'AnsweredRequests', - component: AnsweredRequests + component: () => import('@/components/request/AnsweredRequests') }, { path: '/requests/snoozed', name: 'SnoozedRequests', - component: SnoozedRequests + component: () => import('@/components/request/SnoozedRequests') }, { path: '/user/log-on', name: 'LogOn', - component: LogOn + component: () => import('@/components/user/LogOn') } ] }) diff --git a/src/app/src/store/action-types.js b/src/app/src/store/action-types.js index 958bba8..9b20443 100644 --- a/src/app/src/store/action-types.js +++ b/src/app/src/store/action-types.js @@ -3,6 +3,8 @@ export default { /** Action to add a prayer request (pass request text) */ ADD_REQUEST: 'add-request', + /** Action to check if a user is authenticated, refreshing the session first if it exists */ + CHECK_AUTHENTICATION: 'check-authentication', /** Action to load the user's prayer journal */ LOAD_JOURNAL: 'load-journal', /** Action to update a request */ diff --git a/src/app/src/store/index.js b/src/app/src/store/index.js index b7d0e6b..9b06795 100644 --- a/src/app/src/store/index.js +++ b/src/app/src/store/index.js @@ -1,47 +1,59 @@ 'use strict' -import Vue from 'vue' +/* eslint-disable no-multi-spaces */ +import Vue from 'vue' import Vuex from 'vuex' -import api from '@/api' -import AuthService from '@/auth/AuthService' +import api from '@/api' +import auth from '@/auth/AuthService' import mutations from './mutation-types' -import actions from './action-types' +import actions from './action-types' +/* eslint-enable no-multi-spaces */ Vue.use(Vuex) -const auth0 = new AuthService() - +/* eslint-disable no-console */ const logError = function (error) { if (error.response) { // The request was made and the server responded with a status code // that falls out of the range of 2xx - console.log(error.response.data) - console.log(error.response.status) - console.log(error.response.headers) + console.error(error.response.data) + console.error(error.response.status) + console.error(error.response.headers) } else if (error.request) { // The request was made but no response was received // `error.request` is an instance of XMLHttpRequest in the browser and an instance of // http.ClientRequest in node.js - console.log(error.request) + console.error(error.request) } else { // Something happened in setting up the request that triggered an Error - console.log('Error', error.message) + console.error('Error', error.message) } - console.log(error.config) + console.error(`config: ${error.config}`) } +/** + * Set the "Bearer" authorization header with the current access token + */ +const setBearer = async function () { + try { + await auth.getAccessToken() + api.setBearer(auth.session.id.token) + } catch (err) { + if (err === 'Not logged in') { + console.warn('API request attempted when user was not logged in') + } else { + console.error(err) + } + } +} +/* eslint-enable no-console */ + export default new Vuex.Store({ state: { - user: JSON.parse(localStorage.getItem('user_profile') || '{}'), - isAuthenticated: (() => { - auth0.scheduleRenewal() - if (auth0.isAuthenticated()) { - api.setBearer(localStorage.getItem('id_token')) - } - return auth0.isAuthenticated() - })(), + user: auth.session.profile, + isAuthenticated: auth.isAuthenticated(), journal: {}, isLoadingJournal: false }, @@ -60,49 +72,60 @@ export default new Vuex.Store({ if (request.lastStatus !== 'Answered') jrnl.push(request) state.journal = jrnl }, + [mutations.SET_AUTHENTICATION] (state, value) { + state.isAuthenticated = value + }, [mutations.USER_LOGGED_OFF] (state) { state.user = {} api.removeBearer() state.isAuthenticated = false }, [mutations.USER_LOGGED_ON] (state, user) { - localStorage.setItem('user_profile', JSON.stringify(user)) state.user = user - api.setBearer(localStorage.getItem('id_token')) state.isAuthenticated = true } }, actions: { async [actions.ADD_REQUEST] ({ commit }, { progress, requestText, recurType, recurCount }) { - progress.start() + progress.$emit('show', 'indeterminate') try { + await setBearer() const newRequest = await api.addRequest(requestText, recurType, recurCount) commit(mutations.REQUEST_ADDED, newRequest.data) - progress.finish() + progress.$emit('done') } catch (err) { logError(err) - progress.fail() + progress.$emit('done') + } + }, + async [actions.CHECK_AUTHENTICATION] ({ commit }) { + try { + await auth.getAccessToken() + commit(mutations.SET_AUTHENTICATION, auth.isAuthenticated()) + } catch (_) { + commit(mutations.SET_AUTHENTICATION, false) } }, async [actions.LOAD_JOURNAL] ({ commit }, progress) { commit(mutations.LOADED_JOURNAL, {}) - progress.start() + progress.$emit('show', 'query') commit(mutations.LOADING_JOURNAL, true) - api.setBearer(localStorage.getItem('id_token')) + await setBearer() try { const jrnl = await api.journal() commit(mutations.LOADED_JOURNAL, jrnl.data) - progress.finish() + progress.$emit('done') } catch (err) { logError(err) - progress.fail() + progress.$emit('done') } finally { commit(mutations.LOADING_JOURNAL, false) } }, async [actions.UPDATE_REQUEST] ({ commit, state }, { progress, requestId, status, updateText, recurType, recurCount }) { - progress.start() + progress.$emit('show', 'indeterminate') try { + await setBearer() let oldReq = (state.journal.filter(req => req.requestId === requestId) || [])[0] || {} if (!(status === 'Prayed' && updateText === '')) { if (status !== 'Answered' && (oldReq.recurType !== recurType || oldReq.recurCount !== recurCount)) { @@ -114,34 +137,36 @@ export default new Vuex.Store({ } const request = await api.getRequest(requestId) commit(mutations.REQUEST_UPDATED, request.data) - progress.finish() + progress.$emit('done') } catch (err) { logError(err) - progress.fail() + progress.$emit('done') } }, async [actions.SHOW_REQUEST_NOW] ({ commit }, { progress, requestId, showAfter }) { - progress.start() + progress.$emit('show', 'indeterminate') try { + await setBearer() await api.showRequest(requestId, showAfter) const request = await api.getRequest(requestId) commit(mutations.REQUEST_UPDATED, request.data) - progress.finish() + progress.$emit('done') } catch (err) { logError(err) - progress.fail() + progress.$emit('done') } }, async [actions.SNOOZE_REQUEST] ({ commit }, { progress, requestId, until }) { - progress.start() + progress.$emit('show', 'indeterminate') try { + await setBearer() await api.snoozeRequest(requestId, until) const request = await api.getRequest(requestId) commit(mutations.REQUEST_UPDATED, request.data) - progress.finish() + progress.$emit('done') } catch (err) { logError(err) - progress.fail() + progress.$emit('done') } } }, diff --git a/src/app/src/store/mutation-types.js b/src/app/src/store/mutation-types.js index a356d20..b59c3c5 100644 --- a/src/app/src/store/mutation-types.js +++ b/src/app/src/store/mutation-types.js @@ -9,6 +9,8 @@ export default { REQUEST_ADDED: 'request-added', /** Mutation to replace a prayer request at the top of the current journal */ REQUEST_UPDATED: 'request-updated', + /** Mutation for setting the authentication state */ + SET_AUTHENTICATION: 'set-authentication', /** Mutation for logging a user off */ USER_LOGGED_OFF: 'user-logged-off', /** Mutation for logging a user on (pass user) */ diff --git a/src/app/vue.config.js b/src/app/vue.config.js index 63fc1a7..95d966f 100644 --- a/src/app/vue.config.js +++ b/src/app/vue.config.js @@ -1,9 +1,16 @@ const webpack = require('webpack') +// const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; module.exports = { - outputDir: '../api/MyPrayerJournal.Api/wwwroot', + outputDir: '../MyPrayerJournal.Api/wwwroot', configureWebpack: { plugins: [ + // new BundleAnalyzerPlugin(), new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/) - ] + ], + optimization: { + splitChunks: { + chunks: 'all' + } + } } } diff --git a/src/app/yarn.lock b/src/app/yarn.lock index bbd1f7c..f3eb97e 100644 --- a/src/app/yarn.lock +++ b/src/app/yarn.lock @@ -2,41 +2,41 @@ # yarn lockfile v1 -"@babel/code-frame@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8" - integrity sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.5.5.tgz#bc0782f6d69f7b7d49531219699b988f669a8f9d" + integrity sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw== dependencies: "@babel/highlight" "^7.0.0" "@babel/core@^7.0.0": - version "7.5.4" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.5.4.tgz#4c32df7ad5a58e9ea27ad025c11276324e0b4ddd" - integrity sha512-+DaeBEpYq6b2+ZmHx3tHspC+ZRflrvLqwfv8E3hNr5LVQoyBnL8RPKSBCg+rK2W2My9PWlujBiqd0ZPsR9Q6zQ== + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.5.5.tgz#17b2686ef0d6bc58f963dddd68ab669755582c30" + integrity sha512-i4qoSr2KTtce0DmkuuQBV4AuQgGPUcPXMr9L5MyYAtk06z068lQ10a4O009fe5OB/DfNV+h+qqT7ddNV8UnRjg== dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/generator" "^7.5.0" - "@babel/helpers" "^7.5.4" - "@babel/parser" "^7.5.0" + "@babel/code-frame" "^7.5.5" + "@babel/generator" "^7.5.5" + "@babel/helpers" "^7.5.5" + "@babel/parser" "^7.5.5" "@babel/template" "^7.4.4" - "@babel/traverse" "^7.5.0" - "@babel/types" "^7.5.0" + "@babel/traverse" "^7.5.5" + "@babel/types" "^7.5.5" convert-source-map "^1.1.0" debug "^4.1.0" json5 "^2.1.0" - lodash "^4.17.11" + lodash "^4.17.13" resolve "^1.3.2" semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.5.0.tgz#f20e4b7a91750ee8b63656073d843d2a736dca4a" - integrity sha512-1TTVrt7J9rcG5PMjvO7VEG3FrEoEJNHxumRq66GemPmzboLWtIjjcJgk8rokuAS7IiRSpgVSu5Vb9lc99iJkOA== +"@babel/generator@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.5.5.tgz#873a7f936a3c89491b43536d12245b626664e3cf" + integrity sha512-ETI/4vyTSxTzGnU2c49XHv2zhExkv9JHLTwDAFz85kmcwuShvYG2H08FwgIguQf4JC75CBnXAUM5PqeF4fj0nQ== dependencies: - "@babel/types" "^7.5.0" + "@babel/types" "^7.5.5" jsesc "^2.5.1" - lodash "^4.17.11" + lodash "^4.17.13" source-map "^0.5.0" trim-right "^1.0.1" @@ -64,26 +64,26 @@ "@babel/traverse" "^7.4.4" "@babel/types" "^7.4.4" -"@babel/helper-create-class-features-plugin@^7.4.4", "@babel/helper-create-class-features-plugin@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.5.0.tgz#02edb97f512d44ba23b3227f1bf2ed43454edac5" - integrity sha512-EAoMc3hE5vE5LNhMqDOwB1usHvmRjCDAnH8CD4PVkX9/Yr3W/tcz8xE8QvdZxfsFBDICwZnF2UTHIqslRpvxmA== +"@babel/helper-create-class-features-plugin@^7.4.4", "@babel/helper-create-class-features-plugin@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.5.5.tgz#401f302c8ddbc0edd36f7c6b2887d8fa1122e5a4" + integrity sha512-ZsxkyYiRA7Bg+ZTRpPvB6AbOFKTFFK4LrvTet8lInm0V468MWCaSYJE+I7v2z2r8KNLtYiV+K5kTCnR7dvyZjg== dependencies: "@babel/helper-function-name" "^7.1.0" - "@babel/helper-member-expression-to-functions" "^7.0.0" + "@babel/helper-member-expression-to-functions" "^7.5.5" "@babel/helper-optimise-call-expression" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.4.4" + "@babel/helper-replace-supers" "^7.5.5" "@babel/helper-split-export-declaration" "^7.4.4" -"@babel/helper-define-map@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.4.4.tgz#6969d1f570b46bdc900d1eba8e5d59c48ba2c12a" - integrity sha512-IX3Ln8gLhZpSuqHJSnTNBWGDE9kdkTEWl21A/K7PQ00tseBwbqCHTvNLHSBd9M0R5rER4h5Rsvj9vw0R5SieBg== +"@babel/helper-define-map@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.5.5.tgz#3dec32c2046f37e09b28c93eb0b103fd2a25d369" + integrity sha512-fTfxx7i0B5NJqvUOBBGREnrqbTxRh7zinBANpZXAVDlsZxYdclDp467G1sQ8VZYMnAURY3RpBUAgOYT9GfzHBg== dependencies: "@babel/helper-function-name" "^7.1.0" - "@babel/types" "^7.4.4" - lodash "^4.17.11" + "@babel/types" "^7.5.5" + lodash "^4.17.13" "@babel/helper-explode-assignable-expression@^7.1.0": version "7.1.0" @@ -116,12 +116,12 @@ dependencies: "@babel/types" "^7.4.4" -"@babel/helper-member-expression-to-functions@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0.tgz#8cd14b0a0df7ff00f009e7d7a436945f47c7a16f" - integrity sha512-avo+lm/QmZlv27Zsi0xEor2fKcqWG56D5ae9dzklpIaY7cQMK5N8VSpaNVPPagiqmy7LrEjK1IWdGMOqPu5csg== +"@babel/helper-member-expression-to-functions@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.5.5.tgz#1fb5b8ec4453a93c439ee9fe3aeea4a84b76b590" + integrity sha512-5qZ3D1uMclSNqYcXqiHoA0meVdv+xUEex9em2fqMnrk/scphGlGgg66zjMrPJESPwrFJ6sbfFQYUSa0Mz7FabA== dependencies: - "@babel/types" "^7.0.0" + "@babel/types" "^7.5.5" "@babel/helper-module-imports@^7.0.0": version "7.0.0" @@ -131,16 +131,16 @@ "@babel/types" "^7.0.0" "@babel/helper-module-transforms@^7.1.0", "@babel/helper-module-transforms@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.4.4.tgz#96115ea42a2f139e619e98ed46df6019b94414b8" - integrity sha512-3Z1yp8TVQf+B4ynN7WoHPKS8EkdTbgAEy0nU0rs/1Kw4pDgmvYH3rz3aI11KgxKCba2cn7N+tqzV1mY2HMN96w== + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.5.5.tgz#f84ff8a09038dcbca1fd4355661a500937165b4a" + integrity sha512-jBeCvETKuJqeiaCdyaheF40aXnnU1+wkSiUs/IQg3tB85up1LyL8x77ClY8qJpuRJUcXQo+ZtdNESmZl4j56Pw== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-simple-access" "^7.1.0" "@babel/helper-split-export-declaration" "^7.4.4" "@babel/template" "^7.4.4" - "@babel/types" "^7.4.4" - lodash "^4.17.11" + "@babel/types" "^7.5.5" + lodash "^4.17.13" "@babel/helper-optimise-call-expression@^7.0.0": version "7.0.0" @@ -155,11 +155,11 @@ integrity sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA== "@babel/helper-regex@^7.0.0", "@babel/helper-regex@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.4.4.tgz#a47e02bc91fb259d2e6727c2a30013e3ac13c4a2" - integrity sha512-Y5nuB/kESmR3tKjU8Nkn1wMGEx1tjJX076HBMeL3XLQCu6vA/YRzuTW0bbb+qRnXvQGn+d6Rx953yffl8vEy7Q== + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.5.5.tgz#0aa6824f7100a2e0e89c1527c23936c152cab351" + integrity sha512-CkCYQLkfkiugbRDO8eZn6lRuR8kzZoGXCg3149iTk5se7g6qykSpy3+hELSwquhu+TgHn8nkLiBwHvNX8Hofcw== dependencies: - lodash "^4.17.11" + lodash "^4.17.13" "@babel/helper-remap-async-to-generator@^7.1.0": version "7.1.0" @@ -172,15 +172,15 @@ "@babel/traverse" "^7.1.0" "@babel/types" "^7.0.0" -"@babel/helper-replace-supers@^7.1.0", "@babel/helper-replace-supers@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.4.4.tgz#aee41783ebe4f2d3ab3ae775e1cc6f1a90cefa27" - integrity sha512-04xGEnd+s01nY1l15EuMS1rfKktNF+1CkKmHoErDppjAAZL+IUBZpzT748x262HF7fibaQPhbvWUl5HeSt1EXg== +"@babel/helper-replace-supers@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.5.5.tgz#f84ce43df031222d2bad068d2626cb5799c34bc2" + integrity sha512-XvRFWrNnlsow2u7jXDuH4jDDctkxbS7gXssrP4q2nUD606ukXHRvydj346wmNg+zAgpFx4MWf4+usfC93bElJg== dependencies: - "@babel/helper-member-expression-to-functions" "^7.0.0" + "@babel/helper-member-expression-to-functions" "^7.5.5" "@babel/helper-optimise-call-expression" "^7.0.0" - "@babel/traverse" "^7.4.4" - "@babel/types" "^7.4.4" + "@babel/traverse" "^7.5.5" + "@babel/types" "^7.5.5" "@babel/helper-simple-access@^7.1.0": version "7.1.0" @@ -207,14 +207,14 @@ "@babel/traverse" "^7.1.0" "@babel/types" "^7.2.0" -"@babel/helpers@^7.5.4": - version "7.5.4" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.5.4.tgz#2f00608aa10d460bde0ccf665d6dcf8477357cf0" - integrity sha512-6LJ6xwUEJP51w0sIgKyfvFMJvIb9mWAfohJp0+m6eHJigkFdcH8duZ1sfhn0ltJRzwUIT/yqqhdSfRpCpL7oow== +"@babel/helpers@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.5.5.tgz#63908d2a73942229d1e6685bc2a0e730dde3b75e" + integrity sha512-nRq2BUhxZFnfEn/ciJuhklHvFOqjJUD5wpx+1bxUF2axL9C+v4DE/dmp5sT2dKnpOs4orZWzpAZqlCy8QqE/7g== dependencies: "@babel/template" "^7.4.4" - "@babel/traverse" "^7.5.0" - "@babel/types" "^7.5.0" + "@babel/traverse" "^7.5.5" + "@babel/types" "^7.5.5" "@babel/highlight@^7.0.0": version "7.5.0" @@ -225,10 +225,10 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/parser@^7.0.0", "@babel/parser@^7.4.4", "@babel/parser@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.5.0.tgz#3e0713dff89ad6ae37faec3b29dcfc5c979770b7" - integrity sha512-I5nW8AhGpOXGCCNYGc+p7ExQIBxRFnS2fd/d862bNOKvmoEPjYPcfIjsfdy0ujagYOIYPczKgD9l3FsgTkAzKA== +"@babel/parser@^7.0.0", "@babel/parser@^7.4.4", "@babel/parser@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.5.5.tgz#02f077ac8817d3df4a832ef59de67565e71cca4b" + integrity sha512-E5BN68cqR7dhKan1SfqgPGhQ178bkVKpXTPEXnFJBrEt8/DKRZlybmy+IgYLTeN7tp1R5Ccmbm2rBk17sHYU3g== "@babel/plugin-proposal-async-generator-functions@^7.2.0": version "7.2.0" @@ -240,11 +240,11 @@ "@babel/plugin-syntax-async-generators" "^7.2.0" "@babel/plugin-proposal-class-properties@^7.0.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.5.0.tgz#5bc6a0537d286fcb4fd4e89975adbca334987007" - integrity sha512-9L/JfPCT+kShiiTTzcnBJ8cOwdKVmlC1RcCf9F0F9tERVrM4iWtWnXtjWCRqNm2la2BxO1MPArWNsU9zsSJWSQ== + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.5.5.tgz#a974cfae1e37c3110e71f3c6a2e48b8e71958cd4" + integrity sha512-AF79FsnWFxjlaosgdi421vmYG6/jg79bVD0dpD44QdgobzHKuLZ6S3vl8la9qIeSwGi8i1fS0O1mfuDAAdo1/A== dependencies: - "@babel/helper-create-class-features-plugin" "^7.5.0" + "@babel/helper-create-class-features-plugin" "^7.5.5" "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-proposal-decorators@^7.1.0": @@ -265,9 +265,9 @@ "@babel/plugin-syntax-json-strings" "^7.2.0" "@babel/plugin-proposal-object-rest-spread@^7.3.4": - version "7.5.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.4.tgz#250de35d867ce8260a31b1fdac6c4fc1baa99331" - integrity sha512-KCx0z3y7y8ipZUMAEEJOyNi11lMb/FOPUjjB113tfowgw0c16EGYos7worCKBcUAh2oG+OBnoUhsnTSoLpV9uA== + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.5.tgz#61939744f71ba76a3ae46b5eea18a54c16d22e58" + integrity sha512-F2DxJJSQ7f64FyTVl5cw/9MWn6naXGdk3Q3UhDbFEEHv+EilCPoeRD3Zh/Utx1CJz4uyKlQ4uH+bJPbEhMV7Zw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-object-rest-spread" "^7.2.0" @@ -362,24 +362,24 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-block-scoping@^7.3.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.4.4.tgz#c13279fabf6b916661531841a23c4b7dae29646d" - integrity sha512-jkTUyWZcTrwxu5DD4rWz6rDB5Cjdmgz6z7M7RLXOJyCUkFBawssDGcGh8M/0FTSB87avyJI1HsTwUXp9nKA1PA== + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.5.5.tgz#a35f395e5402822f10d2119f6f8e045e3639a2ce" + integrity sha512-82A3CLRRdYubkG85lKwhZB0WZoHxLGsJdux/cOVaJCJpvYFl1LVzAIFyRsa7CvXqW8rBM4Zf3Bfn8PHt5DP0Sg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - lodash "^4.17.11" + lodash "^4.17.13" "@babel/plugin-transform-classes@^7.3.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.4.4.tgz#0ce4094cdafd709721076d3b9c38ad31ca715eb6" - integrity sha512-/e44eFLImEGIpL9qPxSRat13I5QNRgBLu2hOQJCF7VLy/otSM/sypV1+XaIw5+502RX/+6YaSAPmldk+nhHDPw== + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.5.5.tgz#d094299d9bd680a14a2a0edae38305ad60fb4de9" + integrity sha512-U2htCNK/6e9K7jGyJ++1p5XRU+LJjrwtoiVn9SzRlDT2KubcZ11OOwy3s24TjHxPgxNwonCYP7U2K51uVYCMDg== dependencies: "@babel/helper-annotate-as-pure" "^7.0.0" - "@babel/helper-define-map" "^7.4.4" + "@babel/helper-define-map" "^7.5.5" "@babel/helper-function-name" "^7.1.0" "@babel/helper-optimise-call-expression" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.4.4" + "@babel/helper-replace-supers" "^7.5.5" "@babel/helper-split-export-declaration" "^7.4.4" globals "^11.1.0" @@ -494,12 +494,12 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-object-super@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.2.0.tgz#b35d4c10f56bab5d650047dad0f1d8e8814b6598" - integrity sha512-VMyhPYZISFZAqAPVkiYb7dUe2AsVi2/wCT5+wZdsNO31FojQJa9ns40hzZ6U9f50Jlq4w6qwzdBB2uwqZ00ebg== + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.5.5.tgz#c70021df834073c65eb613b8679cc4a381d1a9f9" + integrity sha512-un1zJQAhSosGFBduPgN/YFNvWVpRuHKU7IHBglLoLZsGmruJPOo6pbInneflUdmq7YvSVqhpPs5zdBvLnteltQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.1.0" + "@babel/helper-replace-supers" "^7.5.5" "@babel/plugin-transform-parameters@^7.2.0": version "7.4.4" @@ -518,9 +518,9 @@ regenerator-transform "^0.14.0" "@babel/plugin-transform-runtime@^7.4.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.5.0.tgz#45242c2c9281158c5f06d25beebac63e498a284e" - integrity sha512-LmPIZOAgTLl+86gR9KjLXex6P/lRz1fWEjTz6V6QZMmKie51ja3tvzdwORqhHc4RWR8TcZ5pClpRWs0mlaA2ng== + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.5.5.tgz#a6331afbfc59189d2135b2e09474457a8e3d28bc" + integrity sha512-6Xmeidsun5rkwnGfMOp6/z9nSzWpHFNVr2Jx7kwoq4mVatQfQx5S56drBgEHF+XQbKOdIaOiMIINvp/kAwMN+w== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" @@ -623,17 +623,17 @@ semver "^5.3.0" "@babel/runtime-corejs2@^7.2.0": - version "7.5.4" - resolved "https://registry.yarnpkg.com/@babel/runtime-corejs2/-/runtime-corejs2-7.5.4.tgz#7111dbb344acce1f7dd601786cff40d516b27a96" - integrity sha512-sHv74OzyZ18d6tjHU0HmlVES3+l+lydkOMTiKsJSTGWcTBpIMfXLEgduahlJrQjknW9RCQAqLIEdLOHjBmq/hg== + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/runtime-corejs2/-/runtime-corejs2-7.5.5.tgz#c3214c08ef20341af4187f1c9fbdc357fbec96b2" + integrity sha512-FYATQVR00NSNi7mUfpPDp7E8RYMXDuO8gaix7u/w3GekfUinKgX1AcTxs7SoiEmoEW9mbpjrwqWSW6zCmw5h8A== dependencies: core-js "^2.6.5" regenerator-runtime "^0.13.2" "@babel/runtime@^7.0.0": - version "7.5.4" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.4.tgz#cb7d1ad7c6d65676e66b47186577930465b5271b" - integrity sha512-Na84uwyImZZc3FKf4aUF1tysApzwf3p2yuFBIyBfbzT5glzKTdvYI4KVW4kcgjrzoGUjC7w3YyCHcJKaRxsr2Q== + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132" + integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ== dependencies: regenerator-runtime "^0.13.2" @@ -646,28 +646,28 @@ "@babel/parser" "^7.4.4" "@babel/types" "^7.4.4" -"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.4", "@babel/traverse@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.5.0.tgz#4216d6586854ef5c3c4592dab56ec7eb78485485" - integrity sha512-SnA9aLbyOCcnnbQEGwdfBggnc142h/rbqqsXcaATj2hZcegCl903pUD/lfpsNBlBSuWow/YDfRyJuWi2EPR5cg== +"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.4", "@babel/traverse@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.5.5.tgz#f664f8f368ed32988cd648da9f72d5ca70f165bb" + integrity sha512-MqB0782whsfffYfSjH4TM+LMjrJnhCNEDMDIjeTpl+ASaUvxcjoiVCo/sM1GhS1pHOXYfWVCYneLjMckuUxDaQ== dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/generator" "^7.5.0" + "@babel/code-frame" "^7.5.5" + "@babel/generator" "^7.5.5" "@babel/helper-function-name" "^7.1.0" "@babel/helper-split-export-declaration" "^7.4.4" - "@babel/parser" "^7.5.0" - "@babel/types" "^7.5.0" + "@babel/parser" "^7.5.5" + "@babel/types" "^7.5.5" debug "^4.1.0" globals "^11.1.0" - lodash "^4.17.11" + lodash "^4.17.13" -"@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.4.4", "@babel/types@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.5.0.tgz#e47d43840c2e7f9105bc4d3a2c371b4d0c7832ab" - integrity sha512-UFpDVqRABKsW01bvw7/wSUe56uy6RXM5+VJibVVAybDGxEW25jdwiFJEf7ASvSaC7sN7rbE/l3cLp2izav+CtQ== +"@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.5.5.tgz#97b9f728e182785909aa4ab56264f090a028d18a" + integrity sha512-s63F9nJioLqOlW3UkyMd+BYhXt44YuaFm/VV0VwuteqjYwRrObkU7ra9pY4wAJR3oXi8hJrMcrcJdO/HH33vtw== dependencies: esutils "^2.0.2" - lodash "^4.17.11" + lodash "^4.17.13" to-fast-properties "^2.0.0" "@hapi/address@2.x.x": @@ -675,35 +675,30 @@ resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.0.0.tgz#9f05469c88cb2fd3dcd624776b54ee95c312126a" integrity sha512-mV6T0IYqb0xL1UALPFplXYQmR0twnXG0M6jUswpquqT2sD12BOiCiLy3EvMp/Fy7s3DZElC4/aPjEjo2jeZpvw== -"@hapi/hoek@6.x.x": - version "6.2.4" - resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-6.2.4.tgz#4b95fbaccbfba90185690890bdf1a2fbbda10595" - integrity sha512-HOJ20Kc93DkDVvjwHyHawPwPkX44sIrbXazAUDiUXaY2R9JwQGo2PhFfnQtdrsIe4igjG2fPgMra7NYw7qhy0A== +"@hapi/bourne@1.x.x": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@hapi/bourne/-/bourne-1.3.2.tgz#0a7095adea067243ce3283e1b56b8a8f453b242a" + integrity sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA== "@hapi/hoek@8.x.x": - version "8.0.2" - resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.0.2.tgz#f63a5ff00e891a4e7aa98f11119f9515c6672032" - integrity sha512-O6o6mrV4P65vVccxymuruucb+GhP2zl9NLCG8OdoFRS8BEGw3vwpPp20wpAtpbQQxz1CEUtmxJGgWhjq1XA3qw== + version "8.2.1" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.2.1.tgz#924af04cbb22e17359c620d2a9c946e63f58eb77" + integrity sha512-JPiBy+oSmsq3St7XlipfN5pNA6bDJ1kpa73PrK/zR29CVClDVqy04AanM/M/qx5bSF+I61DdCfAvRrujau+zRg== "@hapi/joi@^15.0.1": - version "15.1.0" - resolved "https://registry.yarnpkg.com/@hapi/joi/-/joi-15.1.0.tgz#940cb749b5c55c26ab3b34ce362e82b6162c8e7a" - integrity sha512-n6kaRQO8S+kepUTbXL9O/UOL788Odqs38/VOfoCrATDtTvyfiO3fgjlSRaNkHabpTLgM7qru9ifqXlXbXk8SeQ== + version "15.1.1" + resolved "https://registry.yarnpkg.com/@hapi/joi/-/joi-15.1.1.tgz#c675b8a71296f02833f8d6d243b34c57b8ce19d7" + integrity sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ== dependencies: "@hapi/address" "2.x.x" - "@hapi/hoek" "6.x.x" - "@hapi/marker" "1.x.x" + "@hapi/bourne" "1.x.x" + "@hapi/hoek" "8.x.x" "@hapi/topo" "3.x.x" -"@hapi/marker@1.x.x": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@hapi/marker/-/marker-1.0.0.tgz#65b0b2b01d1be06304886ce9b4b77b1bfb21a769" - integrity sha512-JOfdekTXnJexfE8PyhZFyHvHjt81rBFSAbTIRAhF2vv/2Y1JzoKsGqxH/GpZJoF7aEfYok8JVcAHmSz1gkBieA== - "@hapi/topo@3.x.x": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-3.1.2.tgz#57cc1317be1a8c5f47c124f9b0e3c49cd78424d2" - integrity sha512-r+aumOqJ5QbD6aLPJWqVjMAPsx5pZKz+F5yPqXZ/WWG9JTtHbQqlzrJoknJ0iJxLj9vlXtmpSdjlkszseeG8OA== + version "3.1.3" + resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-3.1.3.tgz#c7a02e0d936596d29f184e6d7fdc07e8b5efce11" + integrity sha512-JmS9/vQK6dcUYn7wc2YZTqzIKubAQcJKu2KCKAru6es482U5RT5fP1EXCPtlXpiK7PR0On/kpQKI4fRKkzpZBQ== dependencies: "@hapi/hoek" "8.x.x" @@ -770,9 +765,9 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*": - version "12.6.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.6.2.tgz#a5ccec6abb6060d5f20d256fb03ed743e9774999" - integrity sha512-gojym4tX0FWeV2gsW4Xmzo5wxGjXGm550oVUII7f7G5o4BV6c7DBdiG1RRQd+y1bvqRyYtPfMK85UM95vsapqQ== + version "12.7.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.2.tgz#c4e63af5e8823ce9cc3f0b34f7b998c2171f0c44" + integrity sha512-dyYO+f6ihZEtNPDcWNR1fkoTDf3zAK3lAABDze3mz6POyIercH0lEUawUFXlG8xaQZmm1yEBON/4TsYv/laDYg== "@types/normalize-package-data@^2.4.0": version "2.4.0" @@ -801,10 +796,10 @@ lodash.kebabcase "^4.1.1" svg-tags "^1.0.0" -"@vue/babel-preset-app@^3.9.2": - version "3.9.2" - resolved "https://registry.yarnpkg.com/@vue/babel-preset-app/-/babel-preset-app-3.9.2.tgz#b72a9b06abbe3f8f272783be13951271277be338" - integrity sha512-0suuCbu4jkVcVYBjPmuKxeDbrhwThYZHu3DUmtsVuOzFEGeXmco60VmXveniL/bnDUdZyknSuYP4FxgS34gw9w== +"@vue/babel-preset-app@^3.10.0": + version "3.10.0" + resolved "https://registry.yarnpkg.com/@vue/babel-preset-app/-/babel-preset-app-3.10.0.tgz#3f89d631dd0f174c8a72e769b55f081c533c4677" + integrity sha512-NzJLI4Qe0SYm9gVHQC9RXyP0YcPjI28TmZ0ds2RJa9NO96LXHLES2U1HqiMDN4+CVjOQFrWUNd7wWeaETRPXbg== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/plugin-proposal-class-properties" "^7.0.0" @@ -821,16 +816,16 @@ core-js "^2.6.5" "@vue/babel-preset-jsx@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@vue/babel-preset-jsx/-/babel-preset-jsx-1.0.0.tgz#e515cd453a5a8ea6b0f30b2bb92f266d8ab4e9f5" - integrity sha512-5CbDu/QHS+TtQNw5aYAffiMxBBB2Eo9+RJpS8X+6FJbdG5Rvc4TVipEqkrg0pJviWadNg7TEy0Uz4o7VNXeIZw== + version "1.1.0" + resolved "https://registry.yarnpkg.com/@vue/babel-preset-jsx/-/babel-preset-jsx-1.1.0.tgz#c8001329f5b372297a3111a251eb4f9e956c1266" + integrity sha512-EeZ9gwEmu79B4A6LMLAw5cPCVYIcbKWgJgJafWtLzh1S+SgERUmTkVQ9Vx4k8zYBiCuxHK3XziZ3VJIMau7THA== dependencies: "@vue/babel-helper-vue-jsx-merge-props" "^1.0.0" "@vue/babel-plugin-transform-vue-jsx" "^1.0.0" "@vue/babel-sugar-functional-vue" "^1.0.0" "@vue/babel-sugar-inject-h" "^1.0.0" "@vue/babel-sugar-v-model" "^1.0.0" - "@vue/babel-sugar-v-on" "^1.0.0" + "@vue/babel-sugar-v-on" "^1.1.0" "@vue/babel-sugar-functional-vue@^1.0.0": version "1.0.0" @@ -858,37 +853,37 @@ html-tags "^2.0.0" svg-tags "^1.0.0" -"@vue/babel-sugar-v-on@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@vue/babel-sugar-v-on/-/babel-sugar-v-on-1.0.0.tgz#a633ee8fe205763e865b011246981b7f89668033" - integrity sha512-2aqJaDLKdSSGlxZU+GjFERaSNUaa6DQreV+V/K4W/6Lxj8520/r1lChWEa/zuAoPD2Vhy0D2QrqqO+I0D6CkKw== +"@vue/babel-sugar-v-on@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@vue/babel-sugar-v-on/-/babel-sugar-v-on-1.1.0.tgz#1f2b35eeeabb87eaf8925931f4d34fd8e6404a45" + integrity sha512-8DwAj/RLpmrDP4eZ3erJcKcyuLArLUYagNODTsSQrMdG5zmLJoFFtEjODfYRh/XxM2wXv9Wxe+HAB41FQxxwQA== dependencies: "@babel/plugin-syntax-jsx" "^7.2.0" "@vue/babel-plugin-transform-vue-jsx" "^1.0.0" camelcase "^5.0.0" -"@vue/cli-overlay@^3.9.0": - version "3.9.0" - resolved "https://registry.yarnpkg.com/@vue/cli-overlay/-/cli-overlay-3.9.0.tgz#11f513d1fa11b0135fb8ba8b88d228df0dc542e0" - integrity sha512-QfyvpJl2ChehBT2qzb5EvW921JxW94uFL3+lHa6VT42ImH8awrvkTGZmxTQWhHvATa7r0LKy7M7ZRMyo547esg== +"@vue/cli-overlay@^3.10.0": + version "3.10.0" + resolved "https://registry.yarnpkg.com/@vue/cli-overlay/-/cli-overlay-3.10.0.tgz#9266c96fb2bffd35ca96edd8e1e1284ca8c00c94" + integrity sha512-DQCY6WIl1UN1nOuPirW63CcYWSBdIn6s4zdGfFodCfV+0PAEXGcrfNStygG+IKUsydQaJGTneV7SFxcS+9gyzA== "@vue/cli-plugin-babel@^3.0.0": - version "3.9.2" - resolved "https://registry.yarnpkg.com/@vue/cli-plugin-babel/-/cli-plugin-babel-3.9.2.tgz#8ff962a383aaeafd2b280998428a57ea23e9539c" - integrity sha512-XqfmGjUGnnJ3NA+HC31F6nkBvB9pFDhk4Lxeao8ZNJcEjKNEBYjlmHunJQdIe/jEXXum6U+U/ZE6DjDStHTIMw== + version "3.10.0" + resolved "https://registry.yarnpkg.com/@vue/cli-plugin-babel/-/cli-plugin-babel-3.10.0.tgz#3c5300bd6daf30b53292a6c3982e3a681cba2c18" + integrity sha512-NHrg6ZYN2fh5ZiMMzCNRuDlH9mcTOu+GIti1Va/zPnG3qMkX2iZ0zZGFaOCltIFoVSXdyOfa0sMtJGDoP9Q7ZA== dependencies: "@babel/core" "^7.0.0" - "@vue/babel-preset-app" "^3.9.2" - "@vue/cli-shared-utils" "^3.9.0" + "@vue/babel-preset-app" "^3.10.0" + "@vue/cli-shared-utils" "^3.10.0" babel-loader "^8.0.5" webpack ">=4 < 4.29" "@vue/cli-plugin-eslint@^3.0.0": - version "3.9.2" - resolved "https://registry.yarnpkg.com/@vue/cli-plugin-eslint/-/cli-plugin-eslint-3.9.2.tgz#747c616b13a11f34ac80554eee899cbfcd1977b8" - integrity sha512-AdvWJN+4Px2r3hbTDM2/rCtTcS6VyI7XuRljbfr2V9nF9cJiH4qsXFrTCRj3OgupbXJ14fUGKrLxmznLZIm1jA== + version "3.10.0" + resolved "https://registry.yarnpkg.com/@vue/cli-plugin-eslint/-/cli-plugin-eslint-3.10.0.tgz#44a2abcecadc5b4854ee8fc4a7c5930f660293b0" + integrity sha512-grM3Z4je8XlPomhYqTC4ILB26rTrJKZhEkCwbXdduMrWtpn2Ggotl2nYayplOzDgoZ4Cx3ykJMkRulla2Zi47g== dependencies: - "@vue/cli-shared-utils" "^3.9.0" + "@vue/cli-shared-utils" "^3.10.0" babel-eslint "^10.0.1" eslint-loader "^2.1.2" globby "^9.2.0" @@ -899,14 +894,14 @@ eslint-plugin-vue "^4.7.1" "@vue/cli-service@^3.0.0": - version "3.9.2" - resolved "https://registry.yarnpkg.com/@vue/cli-service/-/cli-service-3.9.2.tgz#59c95500f1f20ab1cd1905c28f6c3b17c04d6de8" - integrity sha512-R4L9tCMpJ4DzLgu/aU9CEtl5QYsj/FXRrtEgXSKm+71OVtA/o2rkLTC8SLB2Bu7wHP/HCYbaoy4NZqSEQzTuLw== + version "3.10.0" + resolved "https://registry.yarnpkg.com/@vue/cli-service/-/cli-service-3.10.0.tgz#1e61afac9eeed5d902c124715c29719abeb743c5" + integrity sha512-aQaAjtkpSl4XFBM7Di9doh4GvHp1H8/H1QJKRK8bPJ5MVbt8Lt4tBo+YgK9Qs/9x0mrxCAa5UrR9+8ZWIQs2Zw== dependencies: "@intervolga/optimize-cssnano-plugin" "^1.0.5" "@soda/friendly-errors-webpack-plugin" "^1.7.1" - "@vue/cli-overlay" "^3.9.0" - "@vue/cli-shared-utils" "^3.9.0" + "@vue/cli-overlay" "^3.10.0" + "@vue/cli-shared-utils" "^3.10.0" "@vue/component-compiler-utils" "^2.6.0" "@vue/preload-webpack-plugin" "^1.1.0" "@vue/web-component-wrapper" "^1.2.0" @@ -936,7 +931,7 @@ hash-sum "^1.0.2" html-webpack-plugin "^3.2.0" launch-editor-middleware "^2.2.1" - lodash.defaultsdeep "^4.6.0" + lodash.defaultsdeep "^4.6.1" lodash.mapvalues "^4.6.0" lodash.transform "^4.6.0" mini-css-extract-plugin "^0.6.0" @@ -960,10 +955,10 @@ webpack-dev-server "^3.4.1" webpack-merge "^4.2.1" -"@vue/cli-shared-utils@^3.9.0": - version "3.9.0" - resolved "https://registry.yarnpkg.com/@vue/cli-shared-utils/-/cli-shared-utils-3.9.0.tgz#cb56a443bf763a873849a11d07e9e7638aa16cc2" - integrity sha512-wumeMZTz5aQ+1Y6uxTKegIsgOXEWT3hT8f9sW2mj5SwNDVyQ+AHZTgSynYExTUJg3dH81uKgFDUpPdAvGxzh8g== +"@vue/cli-shared-utils@^3.10.0": + version "3.10.0" + resolved "https://registry.yarnpkg.com/@vue/cli-shared-utils/-/cli-shared-utils-3.10.0.tgz#9d156f3c0ef675a939319062489e98c8d3d80f7e" + integrity sha512-i96XBUtLdWeKFCC/ot12ngqnVikN/dXpelGdyxvNZczCkX7Je0FUdrZkiw0+uTYTu1RmuYWpLs+vb/YQerjiWg== dependencies: "@hapi/joi" "^15.0.1" chalk "^2.4.1" @@ -978,7 +973,7 @@ semver "^6.0.0" string.prototype.padstart "^3.0.0" -"@vue/component-compiler-utils@^2.5.1", "@vue/component-compiler-utils@^2.6.0": +"@vue/component-compiler-utils@^2.6.0": version "2.6.0" resolved "https://registry.yarnpkg.com/@vue/component-compiler-utils/-/component-compiler-utils-2.6.0.tgz#aa46d2a6f7647440b0b8932434d22f12371e543b" integrity sha512-IHjxt7LsOFYc0DkTncB7OXJL7UzwOLPPQCfEUNyxL2qt+tF12THV+EO33O1G2Uk4feMSWua3iD39Itszx0f0bw== @@ -993,6 +988,21 @@ source-map "~0.6.1" vue-template-es2015-compiler "^1.9.0" +"@vue/component-compiler-utils@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@vue/component-compiler-utils/-/component-compiler-utils-3.0.0.tgz#d16fa26b836c06df5baaeb45f3d80afc47e35634" + integrity sha512-am+04/0UX7ektcmvhYmrf84BDVAD8afFOf4asZjN84q8xzxFclbk5x0MtxuKGfp+zjN5WWPJn3fjFAWtDdIGSw== + dependencies: + consolidate "^0.15.1" + hash-sum "^1.0.2" + lru-cache "^4.1.2" + merge-source-map "^1.1.0" + postcss "^7.0.14" + postcss-selector-parser "^5.0.0" + prettier "1.16.3" + source-map "~0.6.1" + vue-template-es2015-compiler "^1.9.0" + "@vue/eslint-config-standard@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@vue/eslint-config-standard/-/eslint-config-standard-4.0.0.tgz#6be447ee674e3b0f733c584098fd9a22e6d76fcd" @@ -1005,9 +1015,9 @@ eslint-plugin-standard "^4.0.0" "@vue/preload-webpack-plugin@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@vue/preload-webpack-plugin/-/preload-webpack-plugin-1.1.0.tgz#d768dba004261c029b53a77c5ea2d5f9ee4f3cce" - integrity sha512-rcn2KhSHESBFMPj5vc5X2pI9bcBNQQixvJXhD5gZ4rN2iym/uH2qfDSQfUS5+qwiz0a85TCkeUs6w6jxFDudbw== + version "1.1.1" + resolved "https://registry.yarnpkg.com/@vue/preload-webpack-plugin/-/preload-webpack-plugin-1.1.1.tgz#18723530d304f443021da2292d6ec9502826104a" + integrity sha512-8VCoJeeH8tCkzhkpfOkt+abALQkS11OIHhte5MBzYaKMTqK0A3ZAKEUVAffsOklhEv7t0yrQt696Opnu9oAx+w== "@vue/web-component-wrapper@^1.2.0": version "1.2.0" @@ -1222,9 +1232,9 @@ acorn@^5.0.0, acorn@^5.5.0, acorn@^5.6.2: integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== acorn@^6.0.7, acorn@^6.1.1: - version "6.2.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.2.0.tgz#67f0da2fc339d6cfb5d6fb244fd449f33cd8bbe3" - integrity sha512-8oe72N3WPMjA+2zVG71Ia0nXZ8DpQH+QyyHO+p06jT8eg8FGG3FbcUIi8KziHlAfheJQZeoqbvq1mQSQHXKYLw== + version "6.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.3.0.tgz#0087509119ffa4fc0a0041d1e93a417e68cb856e" + integrity sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA== address@^1.0.3: version "1.1.0" @@ -1257,9 +1267,9 @@ ajv@^5.2.3, ajv@^5.3.0: json-schema-traverse "^0.3.0" ajv@^6.1.0, ajv@^6.5.5: - version "6.10.1" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.1.tgz#ebf8d3af22552df9dd049bfbe50cc2390e823593" - integrity sha512-w1YQaVGNC6t2UCPjEawK/vo/dG8OOrVtUmhBT1uJJYxbl5kU2Tj3v6LGqBcsysN1yhuCStJCCA3GqdvKY8sqXQ== + version "6.10.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52" + integrity sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw== dependencies: fast-deep-equal "^2.0.1" fast-json-stable-stringify "^2.0.0" @@ -1280,6 +1290,11 @@ alphanum-sort@^1.0.0: resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= + ansi-colors@^3.0.0: version "3.2.4" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" @@ -1375,10 +1390,10 @@ arr-union@^3.1.0: resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= -array-filter@~0.0.0: - version "0.0.1" - resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" - integrity sha1-fajPLiZijtcygDWB/SH2fKzS7uw= +array-find-index@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= array-flatten@1.1.1: version "1.1.1" @@ -1398,16 +1413,6 @@ array-includes@^3.0.3: define-properties "^1.1.2" es-abstract "^1.7.0" -array-map@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662" - integrity sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI= - -array-reduce@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b" - integrity sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys= - array-union@^1.0.1, array-union@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" @@ -1469,10 +1474,15 @@ async-each@^1.0.1: resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== +async-foreach@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/async-foreach/-/async-foreach-0.1.3.tgz#36121f845c0578172de419a97dbeb1d16ec34542" + integrity sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI= + async-limiter@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" - integrity sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg== + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" + integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== async@^1.5.2: version "1.5.2" @@ -1490,17 +1500,17 @@ atob@^2.1.1: integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== auth0-js@^9.7.3: - version "9.11.1" - resolved "https://registry.yarnpkg.com/auth0-js/-/auth0-js-9.11.1.tgz#32fe5fc3a11b5c58096c1ce083a5361fa61ab1b9" - integrity sha512-0w8SuSKyJqQOQ6ft5nvlMqRdIo6mMw7zcaP35I1nF9bVzItYxqt8B1MEGDKd/N638sPuMjSendJLG+wPYmicYg== + version "9.11.3" + resolved "https://registry.yarnpkg.com/auth0-js/-/auth0-js-9.11.3.tgz#a19add9f5c47d155b7a6f87a6dd2b197a9a43860" + integrity sha512-86EGbaXPHBuyYPPPpvkckH7rCnEgS14DHsK64v2tb4ph4NsZ+peW6pjwBHkOdz4Ytd/ibhGTYCEbA9xdHWSqiA== dependencies: - base64-js "^1.2.0" - idtoken-verifier "^1.4.0" + base64-js "^1.3.0" + idtoken-verifier "^1.4.1" js-cookie "^2.2.0" - qs "^6.4.0" + qs "^6.7.0" superagent "^3.8.3" - url-join "^4.0.0" - winchan "^0.2.1" + url-join "^4.0.1" + winchan "^0.2.2" autoprefixer@^9.5.1: version "9.6.1" @@ -1610,10 +1620,10 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= -base64-js@^1.0.2, base64-js@^1.2.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" - integrity sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw== +base64-js@^1.0.2, base64-js@^1.2.0, base64-js@^1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" + integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== base@^0.11.1: version "0.11.2" @@ -1665,6 +1675,13 @@ binary-extensions@^1.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== +block-stream@*: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + integrity sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo= + dependencies: + inherits "~2.0.0" + bluebird@^3.1.1, bluebird@^3.5.1, bluebird@^3.5.5: version "3.5.5" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.5.tgz#a8d0afd73251effbbd5fe384a77d73003c17a71f" @@ -1797,12 +1814,12 @@ browserify-zlib@^0.2.0: pako "~1.0.5" browserslist@^4.0.0, browserslist@^4.3.4, browserslist@^4.5.4, browserslist@^4.6.3: - version "4.6.4" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.6.4.tgz#fd0638b3f8867fec2c604ed0ed9300379f8ec7c2" - integrity sha512-ErJT8qGfRt/VWHSr1HeqZzz50DvxHtr1fVL1m5wf20aGrG8e1ce8fpZ2EjZEfs09DDZYSvtRaDlMpWslBf8Low== + version "4.6.6" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.6.6.tgz#6e4bf467cde520bc9dbdf3747dafa03531cec453" + integrity sha512-D2Nk3W9JL9Fp/gIcWei8LrERCS+eXu9AM5cfXA8WEZ84lFks+ARnZ0q/R69m2SV3Wjma83QDDPxsNKXUwdIsyA== dependencies: - caniuse-lite "^1.0.30000981" - electron-to-chromium "^1.3.188" + caniuse-lite "^1.0.30000984" + electron-to-chromium "^1.3.191" node-releases "^1.1.25" buffer-from@^1.0.0: @@ -1863,16 +1880,17 @@ cacache@^10.0.4: unique-filename "^1.1.0" y18n "^4.0.0" -cacache@^11.3.2: - version "11.3.3" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.3.3.tgz#8bd29df8c6a718a6ebd2d010da4d7972ae3bbadc" - integrity sha512-p8WcneCytvzPxhDvYp31PD039vi77I12W+/KfR9S8AZbaiARFBCpsPJS+9uhWfeBfeAtW7o/4vt3MUqLkbY6nA== +cacache@^12.0.2: + version "12.0.3" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.3.tgz#be99abba4e1bf5df461cd5a2c1071fc432573390" + integrity sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw== dependencies: bluebird "^3.5.5" chownr "^1.1.1" figgy-pudding "^3.5.1" glob "^7.1.4" graceful-fs "^4.1.15" + infer-owner "^1.0.3" lru-cache "^5.1.1" mississippi "^3.0.0" mkdirp "^0.5.1" @@ -1953,11 +1971,29 @@ camel-case@3.0.x: no-case "^2.2.0" upper-case "^1.1.1" +camelcase-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" + integrity sha1-MIvur/3ygRkFHvodkyITyRuPkuc= + dependencies: + camelcase "^2.0.0" + map-obj "^1.0.0" + camelcase@^1.0.2: version "1.2.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" integrity sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk= +camelcase@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" + integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= + +camelcase@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" + integrity sha1-MvxLn82vhF/N9+c7uXysImHwqwo= + camelcase@^5.0.0: version "5.3.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" @@ -1973,10 +2009,10 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000981: - version "1.0.30000983" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000983.tgz#ab3c70061ca2a3467182a10ac75109b199b647f8" - integrity sha512-/llD1bZ6qwNkt41AsvjsmwNOoA4ZB+8iqmf5LVyeSXuBODT/hAMFNVOh84NdUzoiYiSKqo5vQ3ZzeYHSi/olDQ== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000984: + version "1.0.30000989" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz#b9193e293ccf7e4426c5245134b8f2a56c0ac4b9" + integrity sha512-vrMcvSuMz16YY6GSVZ0dWDTJP8jqk3iFQ/Aq5iqblPwxSVVZI+zxDyTX0VPqtQsDnfdrBDcsmhgTEOh5R8Lbpw== case-sensitive-paths-webpack-plugin@^2.2.0: version "2.2.0" @@ -1996,7 +2032,7 @@ center-align@^0.1.1: align-text "^0.1.3" lazy-cache "^1.0.3" -chalk@^1.1.3: +chalk@^1.1.1, chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= @@ -2144,6 +2180,15 @@ cliui@^2.1.0: right-align "^0.1.1" wordwrap "0.0.2" +cliui@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0= + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi "^2.0.0" + cliui@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" @@ -2162,6 +2207,15 @@ cliui@^5.0.0: strip-ansi "^5.2.0" wrap-ansi "^5.1.0" +clone-deep@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" + integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== + dependencies: + is-plain-object "^2.0.4" + kind-of "^6.0.2" + shallow-clone "^3.0.0" + clone@^1.0.2: version "1.0.4" resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" @@ -2454,6 +2508,14 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: safe-buffer "^5.0.1" sha.js "^2.4.8" +cross-spawn@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-3.0.1.tgz#1256037ecb9f0c5f79e3d6ef135e30770184b982" + integrity sha1-ElYDfsufDF9549bvE14wdwGEuYI= + dependencies: + lru-cache "^4.0.1" + which "^1.2.9" + cross-spawn@^5.0.1, cross-spawn@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" @@ -2463,7 +2525,7 @@ cross-spawn@^5.0.1, cross-spawn@^5.1.0: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^6.0.0: +cross-spawn@^6.0.0, cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== @@ -2561,14 +2623,6 @@ css-selector-tokenizer@^0.7.0: fastparse "^1.1.1" regexpu-core "^1.0.0" -css-tree@1.0.0-alpha.28: - version "1.0.0-alpha.28" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.28.tgz#8e8968190d886c9477bc8d61e96f61af3f7ffa7f" - integrity sha512-joNNW1gCp3qFFzj4St6zk+Wh/NBv0vM5YbEreZk0SD4S23S+1xBKb6cLDg2uj4P4k/GUMlIm6cKIDqIG+vdt0w== - dependencies: - mdn-data "~1.1.0" - source-map "^0.5.3" - css-tree@1.0.0-alpha.29: version "1.0.0-alpha.29" resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.29.tgz#3fa9d4ef3142cbd1c301e7664c1f352bd82f5a39" @@ -2577,16 +2631,19 @@ css-tree@1.0.0-alpha.29: mdn-data "~1.1.0" source-map "^0.5.3" +css-tree@1.0.0-alpha.33: + version "1.0.0-alpha.33" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.33.tgz#970e20e5a91f7a378ddd0fc58d0b6c8d4f3be93e" + integrity sha512-SPt57bh5nQnpsTBsx/IXbO14sRc9xXu5MtMAVuo0BaQQmyf0NupNPPSoMaqiAF5tDFafYsTkfeH4Q/HCKXkg4w== + dependencies: + mdn-data "2.0.4" + source-map "^0.5.3" + css-unit-converter@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/css-unit-converter/-/css-unit-converter-1.1.1.tgz#d9b9281adcfd8ced935bdbaba83786897f64e996" integrity sha1-2bkoGtz9jO2TW9urqDeGiX9k6ZY= -css-url-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/css-url-regex/-/css-url-regex-1.1.0.tgz#83834230cc9f74c457de59eebd1543feeb83b7ec" - integrity sha1-g4NCMMyfdMRX3lnuvRVD/uuDt+w= - css-what@2.1, css-what@^2.1.2: version "2.1.3" resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" @@ -2682,6 +2739,13 @@ current-script-polyfill@^1.0.0: resolved "https://registry.yarnpkg.com/current-script-polyfill/-/current-script-polyfill-1.0.0.tgz#f31cf7e4f3e218b0726e738ca92a02d3488ef615" integrity sha1-8xz35PPiGLBybnOMqSoC00iO9hU= +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + integrity sha1-mI3zP+qxke95mmE2nddsF635V+o= + dependencies: + array-find-index "^1.0.1" + cyclist@~0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" @@ -2732,7 +2796,7 @@ debug@^4.1.0, debug@^4.1.1: dependencies: ms "^2.1.1" -decamelize@^1.0.0, decamelize@^1.2.0: +decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2, decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= @@ -2771,12 +2835,11 @@ default-gateway@^4.2.0: ip-regex "^2.1.0" default-gateway@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-5.0.2.tgz#d2d8a13d6fee406d9365d19ec9adccb8a60b82b3" - integrity sha512-wXuT0q8T5vxQNecrTgz/KbU2lPUMRc98I9Y5dnH3yhFB3BGYqtADK4lhivLlG0OfjhmfKx1PGILG2jR4zjI+WA== + version "5.0.3" + resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-5.0.3.tgz#18434c9430a18035a2861f7839bf7669b3436e6f" + integrity sha512-zW+ld9xtN0+q48wIwhitUzhfERJN7BPgvijPhuCKG6bfWqnoqtSNSnrXfvAME2ZJLpgYpz6UorpBddGfLzrJBw== dependencies: - execa "^1.0.0" - ip-regex "^2.1.0" + execa "^2.0.3" defaults@^1.0.3: version "1.0.3" @@ -2929,23 +2992,28 @@ dom-converter@^0.2: utila "~0.4" dom-serializer@0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0" - integrity sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA== + version "0.2.1" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.1.tgz#13650c850daffea35d8b626a4cfc4d3a17643fdb" + integrity sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q== dependencies: - domelementtype "^1.3.0" - entities "^1.1.1" + domelementtype "^2.0.1" + entities "^2.0.0" domain-browser@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== -domelementtype@1, domelementtype@^1.3.0, domelementtype@^1.3.1: +domelementtype@1, domelementtype@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== +domelementtype@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.1.tgz#1f8bdfe91f5a78063274e803b4bdcedf6e94f94d" + integrity sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ== + domhandler@^2.3.0: version "2.4.2" resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" @@ -3024,10 +3092,10 @@ ejs@^2.6.1: resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.6.2.tgz#3a32c63d1cd16d11266cd4703b14fec4e74ab4f6" integrity sha512-PcW2a0tyTuPHz3tWyYqtK6r1fZ3gp+3Sop8Ph+ZYN81Ob5rwmbHEzaqs10N3BEsaGTkh/ooniXK+WwszGlc2+Q== -electron-to-chromium@^1.3.188: - version "1.3.191" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.191.tgz#c451b422cd8b2eab84dedabab5abcae1eaefb6f0" - integrity sha512-jasjtY5RUy/TOyiUYM2fb4BDaPZfm6CXRFeJDMfFsXYADGxUN49RBqtgB7EL2RmJXeIRUk9lM1U6A5yk2YJMPQ== +electron-to-chromium@^1.3.191: + version "1.3.235" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.235.tgz#8d0d52c9ec76d12189f2f2d265a17d57f41d20dc" + integrity sha512-xNabEDbMIKPLQd6xgv4nyyeMaWXIKSJr6G51ZhUemHhbz6kjZAYcygA8CvfEcMF+Mt5eLmDWaLmfSOWdQxzBVQ== elliptic@^6.0.0: version "6.5.0" @@ -3078,6 +3146,11 @@ entities@^1.1.1: resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== +entities@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4" + integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw== + errno@^0.1.3, errno@~0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" @@ -3093,9 +3166,9 @@ error-ex@^1.2.0, error-ex@^1.3.1: is-arrayish "^0.2.1" error-stack-parser@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.0.2.tgz#4ae8dbaa2bf90a8b450707b9149dcabca135520d" - integrity sha512-E1fPutRDdIj/hohG0UpT5mayXNCxXP9d+snxFsPU9X0XgccOumKraa3juDMwTUyi7+Bu5+mCGagjg4IYeNbOdw== + version "2.0.3" + resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.0.3.tgz#9d3c000fb9f5c461f7c4e63c1aa75373ac7aaa36" + integrity sha512-vRC4rKv87twMZy92X4+TmUdv3iYMsmePbpG/YguHsfzmZ8bYJZYYep7yrXH09yFUaCEPKgNK5X79+Yq7hwLVOA== dependencies: stackframe "^1.0.4" @@ -3155,9 +3228,9 @@ eslint-loader@^2.1.2: rimraf "^2.6.1" eslint-module-utils@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.4.0.tgz#8b93499e9b00eab80ccb6614e69f03678e84e09a" - integrity sha512-14tltLm38Eu3zS+mt0KvILC3q8jyIAH518MlG+HO0p+yK885Lb1UHTY/UgR91eOyGdmxAPb+OLoW4znqIT6Ndw== + version "2.4.1" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.4.1.tgz#7b4675875bf96b0dbf1b21977456e5bb1f5e018c" + integrity sha512-H6DOj+ejw7Tesdgbfs4jeS4YMFrT8uI8xwd1gtQqXssaR0EQ26L+2O/w6wkYFy2MymON0fTwHmXBvvfLNZVZEw== dependencies: debug "^2.6.8" pkg-dir "^2.0.0" @@ -3171,9 +3244,9 @@ eslint-plugin-es@^1.3.1: regexpp "^2.0.1" eslint-plugin-import@^2.14.0: - version "2.18.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.18.0.tgz#7a5ba8d32622fb35eb9c8db195c2090bd18a3678" - integrity sha512-PZpAEC4gj/6DEMMoU2Df01C5c50r7zdGIN52Yfi7CvvWaYssG7Jt5R9nFG5gmqodxNOz9vQS87xk6Izdtpdrig== + version "2.18.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.18.2.tgz#02f1180b90b077b33d447a17a2326ceb400aceb6" + integrity sha512-5ohpsHAiUBRNaBWAF08izwUGlbrJoJJ+W9/TBwsGoR1MnlgfwMIKrFeSjWbt6moabiXW9xNvtFz+97KHRfI4HQ== dependencies: array-includes "^3.0.3" contains-path "^0.1.0" @@ -3182,8 +3255,8 @@ eslint-plugin-import@^2.14.0: eslint-import-resolver-node "^0.3.2" eslint-module-utils "^2.4.0" has "^1.0.3" - lodash "^4.17.11" minimatch "^3.0.4" + object.values "^1.1.0" read-pkg-up "^2.0.0" resolve "^1.11.0" @@ -3205,9 +3278,9 @@ eslint-plugin-promise@^4.0.1: integrity sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw== eslint-plugin-standard@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-4.0.0.tgz#f845b45109c99cd90e77796940a344546c8f6b5c" - integrity sha512-OwxJkR6TQiYMmt1EsNRMe5qG3GsbjlcOhbGUBY4LtavF9DsLaTcoR+j2Tdjqi23oUwKNUqX7qcn5fPStafMdlA== + version "4.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-4.0.1.tgz#ff0519f7ffaff114f76d1bd7c3996eef0f6e20b4" + integrity sha512-v/KBnfyaOMPmZc/dmc6ozOdWqekGp7bBGq4jLAecEfPGmfKiWS4sA8sC0LqiV9w5qmXAtXVn4M3p1jSyhY85SQ== eslint-plugin-vue@^4.7.1: version "4.7.1" @@ -3241,14 +3314,16 @@ eslint-scope@^4.0.0: estraverse "^4.1.1" eslint-utils@^1.3.0, eslint-utils@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.3.1.tgz#9a851ba89ee7c460346f97cf8939c7298827e512" - integrity sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q== + version "1.4.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.0.tgz#e2c3c8dba768425f897cf0f9e51fe2e241485d4c" + integrity sha512-7ehnzPaP5IIEh1r1tkjuIrxqhNkzUJa9z3R92tLJdZIVdWaczEhr3EbhGtsMrVxi1KeR8qA7Off6SWc5WNQqyQ== + dependencies: + eslint-visitor-keys "^1.0.0" eslint-visitor-keys@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" - integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== + version "1.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" + integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== eslint@^4.19.1: version "4.19.1" @@ -3322,14 +3397,14 @@ esrecurse@^4.1.0: estraverse "^4.1.0" estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: - version "4.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" - integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== esutils@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" - integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs= + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== etag@~1.8.1: version "1.8.1" @@ -3392,6 +3467,21 @@ execa@^1.0.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +execa@^2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/execa/-/execa-2.0.4.tgz#2f5cc589c81db316628627004ea4e37b93391d8e" + integrity sha512-VcQfhuGD51vQUQtKIq2fjGDLDbL6N1DTQVpYzxZ7LPIXw3HqTuIz6uxRmpV1qf8i31LHf2kjiaGI+GdHwRgbnQ== + dependencies: + cross-spawn "^6.0.5" + get-stream "^5.0.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^3.0.0" + onetime "^5.1.0" + p-finally "^2.0.0" + signal-exit "^3.0.2" + strip-final-newline "^2.0.0" + expand-brackets@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" @@ -3627,7 +3717,7 @@ find-cache-dir@^1.0.0: make-dir "^1.0.0" pkg-dir "^2.0.0" -find-cache-dir@^2.0.0: +find-cache-dir@^2.0.0, find-cache-dir@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== @@ -3787,6 +3877,16 @@ fsevents@^1.2.7: nan "^2.12.1" node-pre-gyp "^0.12.0" +fstream@^1.0.0, fstream@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045" + integrity sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg== + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + function-bind@^1.0.2, function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" @@ -3811,6 +3911,13 @@ gauge@~2.7.3: strip-ansi "^3.0.1" wide-align "^1.1.0" +gaze@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/gaze/-/gaze-1.1.3.tgz#c441733e13b927ac8c0ff0b4c3b033f28812924a" + integrity sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g== + dependencies: + globule "^1.0.0" + get-caller-file@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" @@ -3821,6 +3928,11 @@ get-caller-file@^2.0.1: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== +get-stdin@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" + integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= + get-stream@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" @@ -3833,6 +3945,13 @@ get-stream@^4.0.0: dependencies: pump "^3.0.0" +get-stream@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.1.0.tgz#01203cdc92597f9b909067c3e656cc1f4d3c4dc9" + integrity sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw== + dependencies: + pump "^3.0.0" + get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" @@ -3858,7 +3977,7 @@ glob-to-regexp@^0.3.0: resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= -glob@^7.0.3, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: +glob@^7.0.0, glob@^7.0.3, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@~7.1.1: version "7.1.4" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A== @@ -3912,10 +4031,19 @@ globby@^9.2.0: pify "^4.0.1" slash "^2.0.0" +globule@^1.0.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/globule/-/globule-1.2.1.tgz#5dffb1b191f22d20797a9369b49eab4e9839696d" + integrity sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ== + dependencies: + glob "~7.1.1" + lodash "~4.17.10" + minimatch "~3.0.2" + graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6: - version "4.2.0" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.0.tgz#8d8fdc73977cb04104721cb53666c1ca64cd328b" - integrity sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg== + version "4.2.2" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.2.tgz#6f0952605d0140c1cfdb138ed005775b92d67b02" + integrity sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q== gzip-size@^5.0.0: version "5.1.1" @@ -4035,9 +4163,9 @@ hex-color-regex@^1.1.0: integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ== highlight.js@^9.6.0: - version "9.15.8" - resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.15.8.tgz#f344fda123f36f1a65490e932cf90569e4999971" - integrity sha512-RrapkKQWwE+wKdF73VsOa2RQdIoO3mxwJ4P8mhbI6KYJUraUHRKM5w5zQQKXNk0xNL4UVRdulV9SBJcmzJNzVA== + version "9.15.9" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.15.9.tgz#865257da1dbb4a58c4552d46c4b3854f77f0e6d5" + integrity sha512-M0zZvfLr5p0keDMCAhNBp03XJbKBxUx5AfyfufMdFMEP4N/Xj6dh0IqC75ys7BAzceR34NgcvXjupRVaHBPPVQ== hmac-drbg@^1.0.0: version "1.0.1" @@ -4054,9 +4182,9 @@ hoopy@^0.1.4: integrity sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ== hosted-git-info@^2.1.4: - version "2.7.1" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" - integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w== + version "2.8.4" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.4.tgz#44119abaf4bc64692a16ace34700fed9c03e2546" + integrity sha512-pzXIvANXEFrc5oFFXRMkbLPQ2rXRoDERwDLyrcUxGhaZhgP54BBSl9Oheh7Vv0T090cszWBxPjkQQ5Sq1PbBRQ== hpack.js@^2.1.6: version "2.1.6" @@ -4225,7 +4353,7 @@ icss-utils@^2.1.0: dependencies: postcss "^6.0.1" -idtoken-verifier@^1.4.0: +idtoken-verifier@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/idtoken-verifier/-/idtoken-verifier-1.4.1.tgz#032d7720fdd091830d22f694eb94b5f6644b0d3b" integrity sha512-BoJc00Gj37hrNlx7NYmd8uJFvvC9/FiWDKugDluP4JmgOGT/AfNlPfnRmi9fHEEqSatnIIr3WTyf0dlhHfSHnA== @@ -4265,9 +4393,9 @@ ignore@^4.0.3: integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== ignore@^5.0.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.2.tgz#e28e584d43ad7e92f96995019cc43b9e1ac49558" - integrity sha512-vdqWBp7MyzdmHkkRWV5nY+PfGRbYbahfuvsBCh277tq+w9zyNi7h5CYJCK0kmzti9kU+O/cB7sE8HvKv6aXAKQ== + version "5.1.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.4.tgz#84b7b3dbe64552b6ef0eca99f6743dbec6d97adf" + integrity sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A== import-cwd@^2.0.0: version "2.1.0" @@ -4304,11 +4432,28 @@ imurmurhash@^0.1.4: resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= +in-publish@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/in-publish/-/in-publish-2.0.0.tgz#e20ff5e3a2afc2690320b6dc552682a9c7fadf51" + integrity sha1-4g/146KvwmkDILbcVSaCqcf631E= + +indent-string@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + integrity sha1-ji1INIdCEhtKghi3oTfppSBJ3IA= + dependencies: + repeating "^2.0.0" + indexes-of@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= +infer-owner@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" + integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== + inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -4317,7 +4462,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -4372,6 +4517,11 @@ invariant@^2.2.2: dependencies: loose-envify "^1.0.0" +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= + invert-kv@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" @@ -4387,16 +4537,26 @@ ip@^1.1.0, ip@^1.1.5: resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= -ipaddr.js@1.9.0, ipaddr.js@^1.9.0: +ipaddr.js@1.9.0: version "1.9.0" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.0.tgz#37df74e430a0e47550fe54a2defe30d8acd95f65" integrity sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA== +ipaddr.js@^1.9.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + is-absolute-url@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" integrity sha1-UFMN+4T8yap9vnhS6Do3uTufKqY= +is-absolute-url@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.1.tgz#e315cbdcbbc3d6789532d591954ac78a0e5049f6" + integrity sha512-c2QjUwuMxLsld90sj3xYzpFYWJtuxkIn1f5ua9RTEYJt/vV2IsM+Py00/6qjV7qExgifUvt7qfyBGBBKm+2iBg== + is-accessor-descriptor@^0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" @@ -4529,6 +4689,13 @@ is-extglob@^2.1.0, is-extglob@^2.1.1: resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= +is-finite@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + integrity sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko= + dependencies: + number-is-nan "^1.0.0" + is-fullwidth-code-point@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" @@ -4620,6 +4787,11 @@ is-stream@^1.1.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= +is-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" + integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== + is-svg@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-3.0.0.tgz#9321dbd29c212e5ca99c4fa9794c714bcafa2f75" @@ -4639,6 +4811,11 @@ is-typedarray@~1.0.0: resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= + is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" @@ -4681,10 +4858,15 @@ javascript-stringify@^1.6.0: resolved "https://registry.yarnpkg.com/javascript-stringify/-/javascript-stringify-1.6.0.tgz#142d111f3a6e3dae8f4a9afd77d45855b5a9cce3" integrity sha1-FC0RHzpuPa6PSpr9d9RYVbWpzOM= +js-base64@^2.1.8: + version "2.5.1" + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.5.1.tgz#1efa39ef2c5f7980bb1784ade4a8af2de3291121" + integrity sha512-M7kLczedRMYX4L8Mdh4MzyAMM9O5osx+4FcOQuTvr3A9F2D9S5JXheN0ewNbrvK2UatkTRhL5ejGmGSjNMiZuw== + js-cookie@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-2.2.0.tgz#1b2c279a6eece380a12168b92485265b35b1effb" - integrity sha1-Gywnmm7s44ChIWi5JIUmWzWx7/s= + version "2.2.1" + resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-2.2.1.tgz#69e106dc5d5806894562902aa5baec3744e9b2b8" + integrity sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ== js-levenshtein@^1.1.3: version "1.1.6" @@ -4802,11 +4984,6 @@ jsonfile@^4.0.0: optionalDependencies: graceful-fs "^4.1.6" -jsonify@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" - integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= - jsprim@^1.2.2: version "1.4.1" resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" @@ -4874,6 +5051,13 @@ lazy-cache@^1.0.3: resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" integrity sha1-odePw6UEdMuAhF07O24dpJpEbo4= +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= + dependencies: + invert-kv "^1.0.0" + lcid@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" @@ -4894,6 +5078,17 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + load-json-file@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" @@ -4927,7 +5122,7 @@ loader-utils@^0.2.16: json5 "^0.5.0" object-assign "^4.0.1" -loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3: +loader-utils@^1.0.1, loader-utils@^1.0.2, loader-utils@^1.1.0: version "1.2.3" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA== @@ -4952,7 +5147,7 @@ locate-path@^3.0.0: p-locate "^3.0.0" path-exists "^3.0.0" -lodash.defaultsdeep@^4.6.0: +lodash.defaultsdeep@^4.6.1: version "4.6.1" resolved "https://registry.yarnpkg.com/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz#512e9bd721d272d94e3d3a63653fa17516741ca6" integrity sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA== @@ -4982,10 +5177,10 @@ lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= -lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0: - version "4.17.14" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.14.tgz#9ce487ae66c96254fe20b599f21b6816028078ba" - integrity sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw== +lodash@^4.0.0, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.15, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@~4.17.10: + version "4.17.15" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" + integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== log-symbols@^2.2.0: version "2.2.0" @@ -5011,6 +5206,14 @@ loose-envify@^1.0.0: dependencies: js-tokens "^3.0.0 || ^4.0.0" +loud-rejection@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + lower-case@^1.1.1: version "1.1.4" resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" @@ -5058,6 +5261,11 @@ map-cache@^0.2.2: resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= +map-obj@^1.0.0, map-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= + map-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" @@ -5074,6 +5282,11 @@ md5.js@^1.3.4: inherits "^2.0.1" safe-buffer "^5.1.2" +mdn-data@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" + integrity sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA== + mdn-data@~1.1.0: version "1.1.4" resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-1.1.4.tgz#50b5d4ffc4575276573c4eedb8780812a8419f01" @@ -5101,6 +5314,22 @@ memory-fs@^0.4.0, memory-fs@^0.4.1, memory-fs@~0.4.1: errno "^0.1.3" readable-stream "^2.0.1" +meow@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" + integrity sha1-cstmi0JSKCkKu/qFaJJYcwioAfs= + dependencies: + camelcase-keys "^2.0.0" + decamelize "^1.1.2" + loud-rejection "^1.0.0" + map-obj "^1.0.1" + minimist "^1.1.3" + normalize-package-data "^2.3.4" + object-assign "^4.0.1" + read-pkg-up "^1.0.1" + redent "^1.0.0" + trim-newlines "^1.0.0" + merge-descriptors@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" @@ -5113,10 +5342,15 @@ merge-source-map@^1.1.0: dependencies: source-map "^0.6.1" +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + merge2@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.2.3.tgz#7ee99dbd69bb6481689253f018488a1b902b0ed5" - integrity sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA== + version "1.2.4" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.2.4.tgz#c9269589e6885a60cf80605d9522d4b67ca646e3" + integrity sha512-FYE8xI+6pjFOhokZu0We3S5NKCirLbCzSh2Usf3qEyr4X8U+0jNg9P8RZ4qz+V2UoECLVwSyzU3LxXBaLGtD3A== methods@^1.1.1, methods@~1.1.2: version "1.1.2" @@ -5177,7 +5411,7 @@ mimic-fn@^1.0.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== -mimic-fn@^2.0.0: +mimic-fn@^2.0.0, mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== @@ -5202,7 +5436,7 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= -minimatch@^3.0.2, minimatch@^3.0.4: +minimatch@^3.0.2, minimatch@^3.0.4, minimatch@~3.0.2: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== @@ -5214,7 +5448,7 @@ minimist@0.0.8: resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= -minimist@^1.2.0: +minimist@^1.1.3, minimist@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= @@ -5274,7 +5508,7 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -mkdirp@0.5.1, mkdirp@0.5.x, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: +mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= @@ -5340,7 +5574,7 @@ mz@^2.4.0: object-assign "^4.0.1" thenify-all "^1.0.0" -nan@^2.12.1: +nan@^2.12.1, nan@^2.13.2: version "2.14.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== @@ -5403,6 +5637,24 @@ node-forge@0.7.5: resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.5.tgz#6c152c345ce11c52f465c2abd957e8639cd674df" integrity sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ== +node-gyp@^3.8.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.8.0.tgz#540304261c330e80d0d5edce253a68cb3964218c" + integrity sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA== + dependencies: + fstream "^1.0.0" + glob "^7.0.3" + graceful-fs "^4.1.2" + mkdirp "^0.5.0" + nopt "2 || 3" + npmlog "0 || 1 || 2 || 3 || 4" + osenv "0" + request "^2.87.0" + rimraf "2" + semver "~5.3.0" + tar "^2.0.0" + which "1" + node-ipc@^9.1.1: version "9.1.1" resolved "https://registry.yarnpkg.com/node-ipc/-/node-ipc-9.1.1.tgz#4e245ed6938e65100e595ebc5dc34b16e8dd5d69" @@ -5458,12 +5710,42 @@ node-pre-gyp@^0.12.0: tar "^4" node-releases@^1.1.25: - version "1.1.25" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.25.tgz#0c2d7dbc7fed30fbe02a9ee3007b8c90bf0133d3" - integrity sha512-fI5BXuk83lKEoZDdH3gRhtsNgh05/wZacuXkgbiYkceE7+QIMXOg98n9ZV7mz27B+kFHnqHcUpscZZlGRSmTpQ== + version "1.1.27" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.27.tgz#b19ec8add2afe9a826a99dceccc516104c1edaf4" + integrity sha512-9iXUqHKSGo6ph/tdXVbHFbhRVQln4ZDTIBJCzsa90HimnBYc5jw8RWYt4wBYFHehGyC3koIz5O4mb2fHrbPOuA== dependencies: semver "^5.3.0" +node-sass@^4.12.0: + version "4.12.0" + resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.12.0.tgz#0914f531932380114a30cc5fa4fa63233a25f017" + integrity sha512-A1Iv4oN+Iel6EPv77/HddXErL2a+gZ4uBeZUy+a8O35CFYTXhgA8MgLCWBtwpGZdCvTvQ9d+bQxX/QC36GDPpQ== + dependencies: + async-foreach "^0.1.3" + chalk "^1.1.1" + cross-spawn "^3.0.0" + gaze "^1.0.0" + get-stdin "^4.0.1" + glob "^7.0.3" + in-publish "^2.0.0" + lodash "^4.17.11" + meow "^3.7.0" + mkdirp "^0.5.1" + nan "^2.13.2" + node-gyp "^3.8.0" + npmlog "^4.0.0" + request "^2.88.0" + sass-graph "^2.2.4" + stdout-stream "^1.4.0" + "true-case-path" "^1.0.2" + +"nopt@2 || 3": + version "3.0.6" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k= + dependencies: + abbrev "1" + nopt@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" @@ -5472,7 +5754,7 @@ nopt@^4.0.1: abbrev "1" osenv "^0.1.4" -normalize-package-data@^2.3.2, normalize-package-data@^2.5.0: +normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== @@ -5538,7 +5820,14 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" -npmlog@^4.0.2: +npm-run-path@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-3.1.0.tgz#7f91be317f6a466efed3c9f2980ad8a4ee8b0fa5" + integrity sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg== + dependencies: + path-key "^3.0.0" + +"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.0, npmlog@^4.0.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== @@ -5667,6 +5956,13 @@ onetime@^2.0.0: dependencies: mimic-fn "^1.0.0" +onetime@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.0.tgz#fff0f3c91617fe62bb50189636e99ac8a6df7be5" + integrity sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q== + dependencies: + mimic-fn "^2.1.0" + open@^6.3.0: version "6.4.0" resolved "https://registry.yarnpkg.com/open/-/open-6.4.0.tgz#5c13e96d0dc894686164f18965ecfe889ecfc8a9" @@ -5727,7 +6023,14 @@ os-homedir@^1.0.0: resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= -os-locale@^3.0.0, os-locale@^3.1.0: +os-locale@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + integrity sha1-IPnxeuKe00XoveWDsT0gCYA8FNk= + dependencies: + lcid "^1.0.0" + +os-locale@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== @@ -5741,7 +6044,7 @@ os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= -osenv@^0.1.4: +osenv@0, osenv@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== @@ -5759,6 +6062,11 @@ p-finally@^1.0.0: resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= +p-finally@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-2.0.1.tgz#bd6fcaa9c559a096b680806f4d657b3f0f240561" + integrity sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw== + p-is-promise@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" @@ -5772,9 +6080,9 @@ p-limit@^1.0.0, p-limit@^1.1.0: p-try "^1.0.0" p-limit@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.0.tgz#417c9941e6027a9abcba5092dd2904e255b5fbc2" - integrity sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ== + version "2.2.1" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.1.tgz#aa07a788cc3151c939b5131f63570f0dd2009537" + integrity sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg== dependencies: p-try "^2.0.0" @@ -5924,6 +6232,11 @@ path-key@^2.0.0, path-key@^2.0.1: resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= +path-key@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.0.tgz#99a10d870a803bdd5ee6f0470e58dfcd2f9a54d3" + integrity sha512-8cChqz0RP6SHJkMt48FW0A7+qUOn+OsnOsVtzI59tZ8m+5bCSk7hzwET0pulwOM2YMn9J1efb07KB9l9f30SGg== + path-parse@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" @@ -5934,6 +6247,15 @@ path-to-regexp@0.1.7: resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + path-type@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" @@ -6024,10 +6346,10 @@ pluralize@^7.0.0: resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" integrity sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow== -portfinder@^1.0.20: - version "1.0.21" - resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.21.tgz#60e1397b95ac170749db70034ece306b9a27e324" - integrity sha512-ESabpDCzmBS3ekHbmpAIiESq3udRsCBGiBZLsC+HgBKv2ezb0R4oG+7RnYEVZ/ZCfhel5Tx3UzdNWA0Lox2QCA== +portfinder@^1.0.20, portfinder@^1.0.21: + version "1.0.23" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.23.tgz#894db4bcc5daf02b6614517ce89cd21a38226b82" + integrity sha512-B729mL/uLklxtxuiJKfQ84WPxNw5a7Yhx3geQZdcA4GjNjZSTSSMMWyoennMVnTWSmAR0lMdzWYN0JLnHrg1KQ== dependencies: async "^1.5.2" debug "^2.2.0" @@ -6359,9 +6681,9 @@ postcss-value-parser@^3.0.0, postcss-value-parser@^3.3.0, postcss-value-parser@^ integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== postcss-value-parser@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.0.tgz#99a983d365f7b2ad8d0f9b8c3094926eab4b936d" - integrity sha512-ESPktioptiSUchCKgggAkzdmkgzKfmp0EU8jXH+5kbIUB+unr0Y4CY9SRMvibuvYUBjNh1ACLbxqYNpdTQOteQ== + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.2.tgz#482282c09a42706d1fc9a069b73f44ec08391dc9" + integrity sha512-LmeoohTpp/K4UiyQCwuGWlONxXamGzCMtFxLq4W1nZVGIQLYvMCJx3yAF9qyyuFpflABI9yVdtJAqbihOsCsJQ== postcss@^6.0.1, postcss@^6.0.23: version "6.0.23" @@ -6460,9 +6782,9 @@ pseudomap@^1.0.2: integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= psl@^1.1.24, psl@^1.1.28: - version "1.2.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.2.0.tgz#df12b5b1b3a30f51c329eacbdef98f3a6e136dc6" - integrity sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA== + version "1.3.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.3.0.tgz#e1ebf6a3b5564fa8376f3da2275da76d875ca1bd" + integrity sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag== public-encrypt@^4.0.0: version "4.0.3" @@ -6633,11 +6955,16 @@ q@^1.1.2: resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= -qs@6.7.0, qs@^6.4.0, qs@^6.5.1: +qs@6.7.0: version "6.7.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== +qs@^6.5.1, qs@^6.7.0: + version "6.8.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.8.0.tgz#87b763f0d37ca54200334cd57bb2ef8f68a1d081" + integrity sha512-tPSkj8y92PfZVbinY1n84i1Qdx75lZjMQYx9WZhnkofyxzw2r7Ho39G3/aEvSUdebxpnnM4LZJCtvE/Aq3+s9w== + qs@~6.5.2: version "6.5.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" @@ -6707,6 +7034,14 @@ rc@^1.2.7: minimist "^1.2.0" strip-json-comments "~2.0.1" +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + read-pkg-up@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" @@ -6715,6 +7050,15 @@ read-pkg-up@^2.0.0: find-up "^2.0.0" read-pkg "^2.0.0" +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + read-pkg@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" @@ -6765,7 +7109,15 @@ readdirp@^2.2.1: micromatch "^3.1.10" readable-stream "^2.0.2" -regenerate-unicode-properties@^8.0.2: +redent@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" + integrity sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94= + dependencies: + indent-string "^2.1.0" + strip-indent "^1.0.1" + +regenerate-unicode-properties@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz#ef51e0f0ea4ad424b77bf7cb41f3e015c70a3f0e" integrity sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA== @@ -6783,14 +7135,14 @@ regenerator-runtime@^0.11.0: integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== regenerator-runtime@^0.13.2: - version "0.13.2" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz#32e59c9a6fb9b1a4aff09b4930ca2d4477343447" - integrity sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA== + version "0.13.3" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz#7cf6a77d8f5c6f60eb73c5fc1955b2ceb01e6bf5" + integrity sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw== regenerator-transform@^0.14.0: - version "0.14.0" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.0.tgz#2ca9aaf7a2c239dd32e4761218425b8c7a86ecaf" - integrity sha512-rtOelq4Cawlbmq9xuMR5gdFmv7ku/sFoB7sRiywx7aq53bc52b4j6zvH7Te1Vt/X2YveDKnCGUbioieU7FEL3w== + version "0.14.1" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.1.tgz#3b2fce4e1ab7732c08f665dfdb314749c7ddd2fb" + integrity sha512-flVuee02C3FKRISbxhXl9mGzdbWUVHubl1SMaknjxkFB1/iqpJhArQUvRxOOPEc/9tAiX0BaQ28FJH10E4isSQ== dependencies: private "^0.1.6" @@ -6827,12 +7179,12 @@ regexpu-core@^1.0.0: regjsparser "^0.1.4" regexpu-core@^4.5.4: - version "4.5.4" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.5.4.tgz#080d9d02289aa87fe1667a4f5136bc98a6aebaae" - integrity sha512-BtizvGtFQKGPUcTy56o3nk1bGRp4SZOTYrDtGNlqCQufptV5IkkLN6Emw+yunAJjzf+C9FQFtvq7IoA3+oMYHQ== + version "4.5.5" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.5.5.tgz#aaffe61c2af58269b3e516b61a73790376326411" + integrity sha512-FpI67+ky9J+cDizQUJlIlNZFKual/lUkFr1AG6zOCpwZ9cLrg8UUVakyUQJD7fCDIe9Z2nwTQJNPyonatNmDFQ== dependencies: regenerate "^1.4.0" - regenerate-unicode-properties "^8.0.2" + regenerate-unicode-properties "^8.1.0" regjsgen "^0.5.0" regjsparser "^0.6.0" unicode-match-property-ecmascript "^1.0.4" @@ -6893,6 +7245,13 @@ repeat-string@^1.5.2, repeat-string@^1.6.1: resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= + dependencies: + is-finite "^1.0.0" + request-promise-core@1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.2.tgz#339f6aababcafdb31c799ff158700336301d3346" @@ -6909,7 +7268,7 @@ request-promise-native@^1.0.7: stealthy-require "^1.1.1" tough-cookie "^2.3.3" -request@^2.87.0: +request@^2.87.0, request@^2.88.0: version "2.88.0" resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== @@ -6991,9 +7350,9 @@ resolve-url@^0.2.1: integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= resolve@^1.1.6, resolve@^1.10.0, resolve@^1.11.0, resolve@^1.3.2, resolve@^1.4.0, resolve@^1.5.0, resolve@^1.8.1: - version "1.11.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.11.1.tgz#ea10d8110376982fef578df8fc30b9ac30a07a3e" - integrity sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw== + version "1.12.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.12.0.tgz#3fc644a35c84a48554609ff26ec52b66fa577df6" + integrity sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w== dependencies: path-parse "^1.0.6" @@ -7032,7 +7391,14 @@ right-align@^0.1.1: dependencies: align-text "^0.1.1" -rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3, rimraf@~2.6.2: +rimraf@2, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + +rimraf@~2.6.2: version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== @@ -7078,7 +7444,7 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2: +safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== @@ -7095,6 +7461,27 @@ safe-regex@^1.1.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== +sass-graph@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/sass-graph/-/sass-graph-2.2.4.tgz#13fbd63cd1caf0908b9fd93476ad43a51d1e0b49" + integrity sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k= + dependencies: + glob "^7.0.0" + lodash "^4.0.0" + scss-tokenizer "^0.2.3" + yargs "^7.0.0" + +sass-loader@^7.3.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-7.3.1.tgz#a5bf68a04bcea1c13ff842d747150f7ab7d0d23f" + integrity sha512-tuU7+zm0pTCynKYHpdqaPpe+MMTQ76I9TPZ7i4/5dZsigE350shQWe5EZNl5dBidM49TPET75tNqRbcsUZWeNA== + dependencies: + clone-deep "^4.0.1" + loader-utils "^1.0.1" + neo-async "^2.5.0" + pify "^4.0.1" + semver "^6.3.0" + sax@^1.2.4, sax@~1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" @@ -7117,6 +7504,14 @@ schema-utils@^1.0.0: ajv-errors "^1.0.0" ajv-keywords "^3.1.0" +scss-tokenizer@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz#8eb06db9a9723333824d3f5530641149847ce5d1" + integrity sha1-jrBtualyMzOCTT9VMGQRSYR85dE= + dependencies: + js-base64 "^2.1.8" + source-map "^0.4.2" + select-hose@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" @@ -7130,14 +7525,19 @@ selfsigned@^1.10.4: node-forge "0.7.5" "semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: - version "5.7.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" - integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA== + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== -semver@^6.0.0, semver@^6.1.1: - version "6.2.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.2.0.tgz#4d813d9590aaf8a9192693d6c85b9344de5901db" - integrity sha512-jdFC1VdUGT/2Scgbimf7FSx9iJLXoqfglSF+gJeuNWVpiE37OIbc1jywR/GJyFdz3mnkz2/id0L0J/cr0izR5A== +semver@^6.0.0, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@~5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" + integrity sha1-myzl094C0XxgEq0yaqa00M9U+U8= send@0.17.1: version "0.17.1" @@ -7224,6 +7624,13 @@ sha.js@^2.4.0, sha.js@^2.4.8: inherits "^2.0.1" safe-buffer "^5.0.1" +shallow-clone@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" + integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== + dependencies: + kind-of "^6.0.2" + shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" @@ -7237,14 +7644,9 @@ shebang-regex@^1.0.0: integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= shell-quote@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767" - integrity sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c= - dependencies: - array-filter "~0.0.0" - array-map "~0.0.0" - array-reduce "~0.0.0" - jsonify "~0.0.0" + version "1.7.1" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.1.tgz#3161d969886fb14f9140c65245a5dd19b6f0b06b" + integrity sha512-2kUqeAGnMAu6YrTPX4E3LfxacH9gKljzVjlkUeSqY0soGwK4KLl7TURXCem712tkhBCeeaFP9QK4dKn88s3Icg== signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" @@ -7349,9 +7751,9 @@ source-map-resolve@^0.5.0: urix "^0.1.0" source-map-support@~0.5.12: - version "0.5.12" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.12.tgz#b4f3b10d51857a5af0138d3ce8003b201613d599" - integrity sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ== + version "0.5.13" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" + integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== dependencies: buffer-from "^1.0.0" source-map "^0.6.0" @@ -7361,6 +7763,13 @@ source-map-url@^0.4.0: resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= +source-map@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" + integrity sha1-66T12pwNyZneaAMti092FzZSA2s= + dependencies: + amdefine ">=0.0.4" + source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" @@ -7409,10 +7818,10 @@ spdy-transport@^3.0.0: readable-stream "^3.0.6" wbuf "^1.7.3" -spdy@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.0.tgz#81f222b5a743a329aa12cea6a390e60e9b613c52" - integrity sha512-ot0oEGT/PGUpzf/6uk4AWLqkq+irlqHXkrdbk51oWONh3bxQmBuljxPNl66zlRRcIJStWq0QkLUCPOPjgjvU0Q== +spdy@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.1.tgz#6f12ed1c5db7ea4f24ebb8b89ba58c87c08257f2" + integrity sha512-HeZS3PBdMA+sZSu0qwpCxl3DeALD5ASx8pAX0jZdKXSpPWbQ6SYGnlg3BBmYLx5LtiZrmkAZfErCm2oECBcioA== dependencies: debug "^4.1.0" handle-thing "^2.0.0" @@ -7484,6 +7893,13 @@ static-extend@^0.1.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= +stdout-stream@^1.4.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/stdout-stream/-/stdout-stream-1.4.1.tgz#5ac174cdd5cd726104aa0c0b2bd83815d8d535de" + integrity sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA== + dependencies: + readable-stream "^2.0.1" + stealthy-require@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" @@ -7526,7 +7942,7 @@ strict-uri-encode@^1.0.0: resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= -string-width@^1.0.1: +string-width@^1.0.1, string-width@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= @@ -7571,11 +7987,11 @@ string.prototype.padstart@^3.0.0: function-bind "^1.0.2" string_decoder@^1.0.0, string_decoder@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d" - integrity sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w== + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== dependencies: - safe-buffer "~5.1.0" + safe-buffer "~5.2.0" string_decoder@~1.1.1: version "1.1.1" @@ -7605,6 +8021,13 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: dependencies: ansi-regex "^4.1.0" +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= + dependencies: + is-utf8 "^0.2.0" + strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" @@ -7615,6 +8038,18 @@ strip-eof@^1.0.0: resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-indent@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" + integrity sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI= + dependencies: + get-stdin "^4.0.1" + strip-indent@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" @@ -7675,16 +8110,15 @@ svg-tags@^1.0.0: integrity sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q= svgo@^1.0.0: - version "1.2.2" - resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.2.2.tgz#0253d34eccf2aed4ad4f283e11ee75198f9d7316" - integrity sha512-rAfulcwp2D9jjdGu+0CuqlrAUin6bBWrpoqXWwKDZZZJfXcUXQSxLJOFJCQCSA0x0pP2U0TxSlJu2ROq5Bq6qA== + version "1.3.0" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.3.0.tgz#bae51ba95ded9a33a36b7c46ce9c359ae9154313" + integrity sha512-MLfUA6O+qauLDbym+mMZgtXCGRfIxyQoeH6IKVcFslyODEe/ElJNwr0FohQ3xG4C6HK6bk3KYPPXwHVJk3V5NQ== dependencies: chalk "^2.4.1" coa "^2.0.2" css-select "^2.0.0" css-select-base-adapter "^0.1.1" - css-tree "1.0.0-alpha.28" - css-url-regex "^1.1.0" + css-tree "1.0.0-alpha.33" csso "^3.5.1" js-yaml "^3.13.1" mkdirp "~0.5.1" @@ -7711,6 +8145,15 @@ tapable@^1.0.0, tapable@^1.1.0: resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== +tar@^2.0.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.2.tgz#0ca8848562c7299b8b446ff6a4d60cdbb23edc40" + integrity sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA== + dependencies: + block-stream "*" + fstream "^1.0.12" + inherits "2" + tar@^4: version "4.4.10" resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.10.tgz#946b2810b9a5e0b26140cf78bea6b0b0d689eba1" @@ -7725,25 +8168,24 @@ tar@^4: yallist "^3.0.3" terser-webpack-plugin@^1.1.0, terser-webpack-plugin@^1.2.3: - version "1.3.0" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.3.0.tgz#69aa22426299f4b5b3775cbed8cb2c5d419aa1d4" - integrity sha512-W2YWmxPjjkUcOWa4pBEv4OP4er1aeQJlSo2UhtCFQCuRXEHjOFscO8VyWHj9JLlA0RzQb8Y2/Ta78XZvT54uGg== + version "1.4.1" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.1.tgz#61b18e40eaee5be97e771cdbb10ed1280888c2b4" + integrity sha512-ZXmmfiwtCLfz8WKZyYUuuHf3dMYEjg8NrjHMb0JqHVHVOSkzp3cW2/XG1fP3tRhqEqSzMwzzRQGtAPbs4Cncxg== dependencies: - cacache "^11.3.2" - find-cache-dir "^2.0.0" + cacache "^12.0.2" + find-cache-dir "^2.1.0" is-wsl "^1.1.0" - loader-utils "^1.2.3" schema-utils "^1.0.0" serialize-javascript "^1.7.0" source-map "^0.6.1" - terser "^4.0.0" - webpack-sources "^1.3.0" + terser "^4.1.2" + webpack-sources "^1.4.0" worker-farm "^1.7.0" -terser@^4.0.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/terser/-/terser-4.1.2.tgz#b2656c8a506f7ce805a3f300a2ff48db022fa391" - integrity sha512-jvNoEQSPXJdssFwqPSgWjsOrb+ELoE+ILpHPKXC83tIxOlh2U75F1KuB2luLD/3a6/7K3Vw5pDn+hvu0C4AzSw== +terser@^4.1.2: + version "4.2.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.2.0.tgz#4b1b5f4424b426a7a47e80d6aae45e0d7979aef0" + integrity sha512-6lPt7lZdZ/13icQJp8XasFOwZjFJkxFFIb/N1fhYEQNoNI3Ilo3KABZ9OocZvZoB39r6SiIk/0+v/bt8nZoSeA== dependencies: commander "^2.20.0" source-map "~0.6.1" @@ -7769,9 +8211,9 @@ thenify-all@^1.0.0: any-promise "^1.0.0" thread-loader@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/thread-loader/-/thread-loader-2.1.2.tgz#f585dd38e852c7f9cded5d092992108148f5eb30" - integrity sha512-7xpuc9Ifg6WU+QYw/8uUqNdRwMD+N5gjwHKMqETrs96Qn+7BHwECpt2Brzr4HFlf4IAkZsayNhmGdbkBsTJ//w== + version "2.1.3" + resolved "https://registry.yarnpkg.com/thread-loader/-/thread-loader-2.1.3.tgz#cbd2c139fc2b2de6e9d28f62286ab770c1acbdda" + integrity sha512-wNrVKH2Lcf8ZrWxDF/khdlLlsTMczdcwPA9VEK4c2exlEPynYWxi9op3nPTo5lAnDIkE0rQEB3VBP+4Zncc9Hg== dependencies: loader-runner "^2.3.1" loader-utils "^1.1.0" @@ -7796,9 +8238,9 @@ thunky@^1.0.2: integrity sha512-YwT8pjmNcAXBZqrubu22P4FYsh2D4dxRmnWBOL8Jk8bUcRUtc5326kx32tuTmFDAZtLOGEVNl8POAR8j896Iow== timers-browserify@^2.0.4: - version "2.0.10" - resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.10.tgz#1d28e3d2aadf1d5a5996c4e9f95601cd053480ae" - integrity sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg== + version "2.0.11" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.11.tgz#800b1f3eee272e5bc53ee465a04d0e804c31211f" + integrity sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ== dependencies: setimmediate "^1.0.4" @@ -7885,11 +8327,23 @@ tough-cookie@~2.4.3: psl "^1.1.24" punycode "^1.4.1" +trim-newlines@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" + integrity sha1-WIeWa7WCpFA6QetST301ARgVphM= + trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= +"true-case-path@^1.0.2": + version "1.0.3" + resolved "https://registry.yarnpkg.com/true-case-path/-/true-case-path-1.0.3.tgz#f813b5a8c86b40da59606722b144e3225799f47d" + integrity sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew== + dependencies: + glob "^7.1.2" + tryer@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" @@ -8077,7 +8531,7 @@ url-join@^1.1.0: resolved "https://registry.yarnpkg.com/url-join/-/url-join-1.1.0.tgz#741c6c2f4596c4830d6718460920d0c92202dc78" integrity sha1-dBxsL0WWxIMNZxhGCSDQySIC3Hg= -url-join@^4.0.0: +url-join@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/url-join/-/url-join-4.0.1.tgz#b642e21a2646808ffa178c4c5fda39844e12cde7" integrity sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA== @@ -8150,9 +8604,9 @@ utils-merge@1.0.1: integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= uuid@^3.0.1, uuid@^3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" - integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== + version "3.3.3" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.3.tgz#4568f0216e78760ee1dbf3a4d2cf53e224112866" + integrity sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ== validate-npm-package-license@^3.0.1: version "3.0.4" @@ -8209,25 +8663,25 @@ vue-hot-reload-api@^2.3.0: integrity sha512-KmvZVtmM26BQOMK1rwUZsrqxEGeKiYSZGA7SNWE6uExx8UX/cj9hq2MRV/wWC3Cq6AoeDGk57rL9YMFRel/q+g== vue-loader@^15.7.0: - version "15.7.0" - resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-15.7.0.tgz#27275aa5a3ef4958c5379c006dd1436ad04b25b3" - integrity sha512-x+NZ4RIthQOxcFclEcs8sXGEWqnZHodL2J9Vq+hUz+TDZzBaDIh1j3d9M2IUlTjtrHTZy4uMuRdTi8BGws7jLA== + version "15.7.1" + resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-15.7.1.tgz#6ccacd4122aa80f69baaac08ff295a62e3aefcfd" + integrity sha512-fwIKtA23Pl/rqfYP5TSGK7gkEuLhoTvRYW+TU7ER3q9GpNLt/PjG5NLv3XHRDiTg7OPM1JcckBgds+VnAc+HbA== dependencies: - "@vue/component-compiler-utils" "^2.5.1" + "@vue/component-compiler-utils" "^3.0.0" hash-sum "^1.0.2" loader-utils "^1.1.0" vue-hot-reload-api "^2.3.0" vue-style-loader "^4.1.0" -vue-progressbar@^0.7.3: - version "0.7.5" - resolved "https://registry.yarnpkg.com/vue-progressbar/-/vue-progressbar-0.7.5.tgz#414730892252b1e45582d4979dec93038e007f79" - integrity sha512-VeNG/inMsFbvdCTS7lJ1gjDAKSUZdqkhW9gS1tb0we1rqFKxR+BCEiVUgw5C84vODKb14M2GWHTw0WVdpoVg6g== +vue-material@^1.0.0-beta-11: + version "1.0.0-beta-11" + resolved "https://registry.yarnpkg.com/vue-material/-/vue-material-1.0.0-beta-11.tgz#11baf0cdb22a35d35859c619099d6c3cb3cc2cc3" + integrity sha512-1+dIVkQafMIA/zNONb7OwGaTjAxaWk/JhUA2/FInQvbArxf1ToKB+yIdeSfzopQ1KICnBTAmk9E0Vdr5p4MWNA== vue-router@^3.0.0: - version "3.0.7" - resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.0.7.tgz#b36ca107b4acb8ff5bc4ff824584059c23fcb87b" - integrity sha512-utJ+QR3YlIC/6x6xq17UMXeAfxEvXA0VKD3PiSio7hBOZNusA1jXcbxZxVEfJunLp48oonjTepY8ORoIlRx/EQ== + version "3.1.2" + resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.1.2.tgz#2e0904703545dabdd42b2b7a2e617f02f99a1969" + integrity sha512-WssQEHSEvIS1/CI4CO2T8LJdoK4Q9Ngox28K7FDNMTfzNTk2WS5D0dDlqYCaPG+AG4Z8wJkn1KrBc7AhspZJUQ== vue-style-loader@^4.1.0: version "4.1.2" @@ -8250,11 +8704,6 @@ vue-template-es2015-compiler@^1.9.0: resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825" integrity sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw== -vue-toast@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/vue-toast/-/vue-toast-3.1.0.tgz#19eb4c8150faf5c31c12f8b897a955d1ac0b5e9e" - integrity sha1-GetMgVD69cMcEvi4l6lV0awLXp4= - vue@^2.5.15: version "2.6.10" resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.10.tgz#a72b1a42a4d82a721ea438d1b6bf55e66195c637" @@ -8288,10 +8737,10 @@ wcwidth@^1.0.1: dependencies: defaults "^1.0.3" -webpack-bundle-analyzer@^3.3.0: - version "3.3.2" - resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.3.2.tgz#3da733a900f515914e729fcebcd4c40dde71fc6f" - integrity sha512-7qvJLPKB4rRWZGjVp5U1KEjwutbDHSKboAl0IfafnrdXMrgC0tOtZbQD6Rw0u4cmpgRN4O02Fc0t8eAT+FgGzA== +webpack-bundle-analyzer@^3.3.0, webpack-bundle-analyzer@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.4.1.tgz#430544c7ba1631baccf673475ca8300cb74a3c47" + integrity sha512-Bs8D/1zF+17lhqj2OYmzi7HEVYqEVxu7lCO9Ff8BwajenOU0vAwEoV8e4ICCPNZAcqR1PCR/7o2SkW+cnCmF0A== dependencies: acorn "^6.0.7" acorn-walk "^6.1.1" @@ -8302,7 +8751,7 @@ webpack-bundle-analyzer@^3.3.0: express "^4.16.3" filesize "^3.6.1" gzip-size "^5.0.0" - lodash "^4.17.10" + lodash "^4.17.15" mkdirp "^0.5.1" opener "^1.5.1" ws "^6.0.0" @@ -8326,9 +8775,9 @@ webpack-dev-middleware@^3.7.0: webpack-log "^2.0.0" webpack-dev-server@^3.4.1: - version "3.7.2" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.7.2.tgz#f79caa5974b7f8b63268ef5421222a8486d792f5" - integrity sha512-mjWtrKJW2T9SsjJ4/dxDC2fkFVUw8jlpemDERqV0ZJIkjjjamR2AbQlr3oz+j4JLhYCHImHnXZK5H06P2wvUew== + version "3.8.0" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.8.0.tgz#06cc4fc2f440428508d0e9770da1fef10e5ef28d" + integrity sha512-Hs8K9yI6pyMvGkaPTeTonhD6JXVsigXDApYk9JLW4M7viVBspQvb1WdAcWxqtmttxNW4zf2UFLsLNe0y87pIGQ== dependencies: ansi-html "0.0.7" bonjour "^3.5.0" @@ -8343,23 +8792,25 @@ webpack-dev-server@^3.4.1: import-local "^2.0.0" internal-ip "^4.3.0" ip "^1.1.5" + is-absolute-url "^3.0.0" killable "^1.0.1" loglevel "^1.6.3" opn "^5.5.0" p-retry "^3.0.1" - portfinder "^1.0.20" + portfinder "^1.0.21" schema-utils "^1.0.0" selfsigned "^1.10.4" - semver "^6.1.1" + semver "^6.3.0" serve-index "^1.9.1" sockjs "0.3.19" sockjs-client "1.3.0" - spdy "^4.0.0" + spdy "^4.0.1" strip-ansi "^3.0.1" supports-color "^6.1.0" url "^0.11.0" webpack-dev-middleware "^3.7.0" webpack-log "^2.0.0" + ws "^6.2.1" yargs "12.0.5" webpack-log@^2.0.0: @@ -8377,10 +8828,10 @@ webpack-merge@^4.2.1: dependencies: lodash "^4.17.5" -webpack-sources@^1.1.0, webpack-sources@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.3.0.tgz#2a28dcb9f1f45fe960d8f1493252b5ee6530fa85" - integrity sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA== +webpack-sources@^1.1.0, webpack-sources@^1.3.0, webpack-sources@^1.4.0: + version "1.4.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" + integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== dependencies: source-list-map "^2.0.0" source-map "~0.6.1" @@ -8429,12 +8880,17 @@ websocket-extensions@>=0.1.1: resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29" integrity sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg== +which-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" + integrity sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8= + which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which@^1.2.9: +which@1, which@^1.2.9: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== @@ -8448,7 +8904,7 @@ wide-align@^1.1.0: dependencies: string-width "^1.0.2 || 2" -winchan@^0.2.1: +winchan@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/winchan/-/winchan-0.2.2.tgz#6766917b88e5e1cb75f455ffc7cc13f51e5c834e" integrity sha512-pvN+IFAbRP74n/6mc6phNyCH8oVkzXsto4KCHPJ2AScniAnA1AmeLI03I2BzjePpaClGSI4GUMowzsD3qz5PRQ== @@ -8512,7 +8968,7 @@ write@^0.2.1: dependencies: mkdirp "^0.5.1" -ws@^6.0.0: +ws@^6.0.0, ws@^6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA== @@ -8524,6 +8980,11 @@ xtend@^4.0.0, xtend@~4.0.1: resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== +y18n@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" + integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= + "y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" @@ -8547,7 +9008,7 @@ yargs-parser@^11.1.1: camelcase "^5.0.0" decamelize "^1.2.0" -yargs-parser@^13.1.0: +yargs-parser@^13.1.1: version "13.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0" integrity sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ== @@ -8555,6 +9016,13 @@ yargs-parser@^13.1.0: camelcase "^5.0.0" decamelize "^1.2.0" +yargs-parser@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a" + integrity sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo= + dependencies: + camelcase "^3.0.0" + yargs@12.0.5: version "12.0.5" resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" @@ -8574,21 +9042,39 @@ yargs@12.0.5: yargs-parser "^11.1.1" yargs@^13.0.0: - version "13.2.4" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.4.tgz#0b562b794016eb9651b98bd37acf364aa5d6dc83" - integrity sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg== + version "13.3.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.0.tgz#4c657a55e07e5f2cf947f8a366567c04a0dedc83" + integrity sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA== dependencies: cliui "^5.0.0" find-up "^3.0.0" get-caller-file "^2.0.1" - os-locale "^3.1.0" require-directory "^2.1.1" require-main-filename "^2.0.0" set-blocking "^2.0.0" string-width "^3.0.0" which-module "^2.0.0" y18n "^4.0.0" - yargs-parser "^13.1.0" + yargs-parser "^13.1.1" + +yargs@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8" + integrity sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg= + dependencies: + camelcase "^3.0.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.2" + which-module "^1.0.0" + y18n "^3.2.1" + yargs-parser "^5.0.0" yargs@~3.10.0: version "3.10.0" diff --git a/src/migrate/Program.fs b/src/migrate/Program.fs new file mode 100644 index 0000000..e4878c2 --- /dev/null +++ b/src/migrate/Program.fs @@ -0,0 +1,110 @@ + +open Microsoft.FSharpLu.Json +open MyPrayerJournal +open Npgsql +open Raven.Client.Documents + +type NpgsqlDataReader with + member this.getShort = this.GetOrdinal >> this.GetInt16 + member this.getString = this.GetOrdinal >> this.GetString + member this.getTicks = this.GetOrdinal >> this.GetInt64 >> Ticks + member this.isNull = this.GetOrdinal >> this.IsDBNull + +let pgConn connStr = + let c = new NpgsqlConnection (connStr) + c.Open () + c + +let isValidStatus stat = + try + (RequestAction.fromString >> ignore) stat + true + with _ -> false + +let getHistory reqId connStr = + use conn = pgConn connStr + use cmd = conn.CreateCommand () + cmd.CommandText <- """SELECT "asOf", status, text FROM mpj.history WHERE "requestId" = @reqId ORDER BY "asOf" """ + (cmd.Parameters.Add >> ignore) (NpgsqlParameter ("@reqId", reqId :> obj)) + use rdr = cmd.ExecuteReader () + seq { + while rdr.Read () do + match (rdr.getString >> isValidStatus) "status" with + | true -> + yield + { asOf = rdr.getTicks "asOf" + status = (rdr.getString >> RequestAction.fromString) "status" + text = match rdr.isNull "text" with true -> None | false -> (rdr.getString >> Some) "text" + } + | false -> + printf "Invalid status %s; skipped history entry %s/%i\n" (rdr.getString "status") reqId + ((rdr.getTicks >> Ticks.toLong) "asOf") + } + |> List.ofSeq + +let getNotes reqId connStr = + use conn = pgConn connStr + use cmd = conn.CreateCommand () + cmd.CommandText <- """SELECT "asOf", notes FROM mpj.note WHERE "requestId" = @reqId""" + (cmd.Parameters.Add >> ignore) (NpgsqlParameter ("@reqId", reqId :> obj)) + use rdr = cmd.ExecuteReader () + seq { + while rdr.Read () do + yield + { asOf = rdr.getTicks "asOf" + notes = rdr.getString "notes" + } + } + |> List.ofSeq + +let migrateRequests (store : IDocumentStore) connStr = + use sess = store.OpenSession () + use conn = pgConn connStr + use cmd = conn.CreateCommand () + cmd.CommandText <- + """SELECT "requestId", "enteredOn", "userId", "snoozedUntil", "showAfter", "recurType", "recurCount" FROM mpj.request""" + use rdr = cmd.ExecuteReader () + while rdr.Read () do + let reqId = rdr.getString "requestId" + let recurrence = + match rdr.getString "recurType" with + | "immediate" -> Immediate + | "hours" -> Hours + | "days" -> Days + | "weeks" -> Weeks + | x -> invalidOp (sprintf "%s is not a valid recurrence" x) + sess.Store ( + { Id = (RequestId.fromIdString >> RequestId.toString) reqId + enteredOn = rdr.getTicks "enteredOn" + userId = (rdr.getString >> UserId) "userId" + snoozedUntil = rdr.getTicks "snoozedUntil" + showAfter = match recurrence with Immediate -> Ticks 0L | _ -> rdr.getTicks "showAfter" + recurType = recurrence + recurCount = rdr.getShort "recurCount" + history = getHistory reqId connStr + notes = getNotes reqId connStr + }) + sess.SaveChanges () + +open Converters +open System +open System.Security.Cryptography.X509Certificates + +[] +let main argv = + match argv.Length with + | 4 -> + let clientCert = new X509Certificate2 (argv.[1], argv.[2]) + let raven = new DocumentStore (Urls = [| argv.[0] |], Database = "myPrayerJournal", Certificate = clientCert) + raven.Conventions.CustomizeJsonSerializer <- + fun x -> + x.Converters.Add (RequestIdJsonConverter ()) + x.Converters.Add (TicksJsonConverter ()) + x.Converters.Add (UserIdJsonConverter ()) + x.Converters.Add (CompactUnionJsonConverter ()) + let store = raven.Initialize () + migrateRequests store argv.[3] + printfn "fin" + | _ -> + Console.WriteLine "Usage: dotnet migrate.dll [raven-url] [raven-cert-file] [raven-cert-pw] [postgres-conn-str]" + 0 diff --git a/src/migrate/migrate.fsproj b/src/migrate/migrate.fsproj new file mode 100644 index 0000000..bdea31d --- /dev/null +++ b/src/migrate/migrate.fsproj @@ -0,0 +1,23 @@ + + + + Exe + netcoreapp2.2 + + + + + + + + + + + + + + + + + +